diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index bb10f6ce6bf..00000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,169 +0,0 @@ -version: 2 -jobs: - build_and_test_reorg: - docker: - # Any image that includes the docker client will do - - image: circleci/ruby - steps: - - checkout - - setup_remote_docker - - - run: - name: Log in to the Docker registry - command: | - if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASSWORD" ]; then - docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" - else - echo "No Docker credentials, skipping login" - fi - - - run: - name: Prepare environment variables - command: | - BRANCH_TAG="$(echo $CIRCLE_BRANCH | sed -E 's/[^A-Za-z0-9]+/-/g')" - echo "export BRANCH_TAG='$BRANCH_TAG'" >> $BASH_ENV - - VERSION="$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" common/lib/dependabot/version.rb)" - echo "export VERSION='$VERSION'" >> $BASH_ENV - - - run: - name: Pull Docker base images & warm Docker cache - command: | - docker pull ubuntu:18.04 - docker pull "dependabot/dependabot-core-ci:core--$BRANCH_TAG" || - docker pull "dependabot/dependabot-core:latest" - docker pull "dependabot/dependabot-core-ci:ci--$BRANCH_TAG" || - docker pull "dependabot/dependabot-core-ci:latest" || true - - - run: - name: Build dependabot-core image - command: | - docker build \ - -t "dependabot/dependabot-core:latest" \ - -t "dependabot/dependabot-core:$VERSION" \ - -t "dependabot/dependabot-core-ci:core--$BRANCH_TAG" \ - --cache-from ubuntu:18.04 \ - --cache-from "dependabot/dependabot-core-ci:core--$BRANCH_TAG" \ - --cache-from "dependabot/dependabot-core:latest" \ - . - - - run: - name: Push dependabot-core image to CI cache repo - command: | - if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASSWORD" ]; then - docker push "dependabot/dependabot-core-ci:core--$BRANCH_TAG" - else - echo "No Docker credentials, skipping push" - fi - - - run: - name: Build dependabot-core-ci image - command: | - rm .dockerignore # we usually don't want tests etc, but here we do - docker build \ - -t "dependabot/dependabot-core-ci:latest" \ - -t "dependabot/dependabot-core-ci:ci--$BRANCH_TAG" \ - -f Dockerfile.ci \ - --cache-from ubuntu:18.04 \ - --cache-from "dependabot/dependabot-core:latest" \ - --cache-from "dependabot/dependabot-core-ci:ci--$BRANCH_TAG" \ - --cache-from "dependabot/dependabot-core-ci:latest" \ - . - - - run: - name: Rubocop - command: | - docker run \ - --env "CIRCLE_COMPARE_URL=$CIRCLE_COMPARE_URL" \ - -ti dependabot/dependabot-core-ci \ - bash -c "rake ci:rubocop" - - - run: - name: RSpec - command: | - docker run \ - --env "CIRCLE_COMPARE_URL=$CIRCLE_COMPARE_URL" \ - -ti dependabot/dependabot-core-ci \ - bash -c "rake ci:rspec" - - - run: - name: Push dependabot-core image to Docker hub, if on main - command: | - if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASSWORD" ]; then - if [ "${CIRCLE_BRANCH}" == "main" ]; then - echo "Pushing dependabot-core:{latest,$VERSION}} to registry" - docker push "dependabot/dependabot-core:$VERSION" - docker push "dependabot/dependabot-core:latest" - else - echo "Not on main, skipping deployment" - fi - else - echo "No Docker credentials, skipping push" - fi - - - run: - name: Push dependabot-core-ci image to CI cache repo - command: | - if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASSWORD" ]; then - docker push "dependabot/dependabot-core-ci:ci--$BRANCH_TAG" - docker push "dependabot/dependabot-core-ci:latest" - else - echo "No Docker credentials, skipping push" - fi - - test_core: - docker: - - image: dependabot/dependabot-core:0.1.47 - working_directory: ~/dependabot-core - steps: - - checkout - - - restore_cache: - keys: - - v1-dependencies-{{ .Branch }} - - v1-dependencies-main - - # Install dependencies - - run: cd npm_and_yarn/helpers && yarn install - - - save_cache: - key: v1-dependencies-{{ .Branch }}-{{ epoch }} - paths: - - ~/dependabot-core/npm_and_yarn/helpers/node_modules - - # Run code formatting linters - - run: cd npm_and_yarn/helpers && yarn lint - - # Run tests - - run: cd npm_and_yarn/helpers && yarn test - - - store_test_results: - path: ~/rspec - - store_artifacts: - path: ~/rspec - - release_gems: - docker: - - image: dependabot/dependabot-core:latest - working_directory: ~/dependabot-core - steps: - - checkout - - run: | - [ -d ~/.gem ] || mkdir ~/.gem - echo "---" > ~/.gem/credentials - echo ":rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials - chmod 0600 ~/.gem/credentials - - run: gem install rake && rake gems:release - -workflows: - version: 2 - test: - jobs: - - test_core - - build_and_test_reorg - - release_gems: - filters: - branches: - ignore: /.*/ - tags: - only: /^v[0-9]+\.[0-9]+\.[0-9]+$/ diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000000..828de1fbe7e --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,11 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu/.devcontainer/base.Dockerfile + +# [Choice] Ubuntu version (use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon): ubuntu-22.04, ubuntu-20.04, ubuntu-18.04 +ARG VARIANT="jammy" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + + diff --git a/.devcontainer/core-dev/devcontainer.json b/.devcontainer/core-dev/devcontainer.json new file mode 100644 index 00000000000..080ec5491a1 --- /dev/null +++ b/.devcontainer/core-dev/devcontainer.json @@ -0,0 +1,132 @@ +{ + "name": "core-dev", + "build": { + "dockerfile": "../../Dockerfile.development", + "cacheFrom": "ghcr.io/dependabot/dependabot-core-development" + }, + + "workspaceFolder": "/home/dependabot/dependabot-core", + + "runArgs": [ + "-u", "dependabot", + "-e", "LOCAL_GITHUB_ACCESS_TOKEN=${env:LOCAL_GITHUB_ACCESS_TOKEN}", + "-e", "LOCAL_CONFIG_VARIABLES=${env:LOCAL_CONFIG_VARIABLES}", + + "-v", "${localWorkspaceFolder}/.vscode:/home/dependabot/dependabot-core/.vscode", + "-v", "${localWorkspaceFolder}/.gitignore:/home/dependabot/dependabot-core/.gitignore", + "-v", "${localWorkspaceFolder}/.rubocop.yml:/home/dependabot/dependabot-core/.rubocop.yml", + "-v", "${localWorkspaceFolder}/bin:/home/dependabot/dependabot-core/bin", + "-v", "${localWorkspaceFolder}/common/Gemfile:/home/dependabot/dependabot-core/common/Gemfile", + "-v", "${localWorkspaceFolder}/common/dependabot-common.gemspec:/home/dependabot/dependabot-core/common/dependabot-common.gemspec", + "-v", "${localWorkspaceFolder}/common/bin:/home/dependabot/dependabot-core/common/bin", + "-v", "${localWorkspaceFolder}/common/lib:/home/dependabot/dependabot-core/common/lib", + "-v", "${localWorkspaceFolder}/common/spec:/home/dependabot/dependabot-core/common/spec", + "-v", "${localWorkspaceFolder}/bundler/dependabot-bundler.gemspec:/home/dependabot/dependabot-core/bundler/dependabot-bundler.gemspec", + "-v", "${localWorkspaceFolder}/bundler/Gemfile:/home/dependabot/dependabot-core/bundler/Gemfile", + "-v", "${localWorkspaceFolder}/bundler/helpers:/home/dependabot/dependabot-core/bundler/helpers", + "-v", "${localWorkspaceFolder}/bundler/lib:/home/dependabot/dependabot-core/bundler/lib", + "-v", "${localWorkspaceFolder}/bundler/spec:/home/dependabot/dependabot-core/bundler/spec", + "-v", "${localWorkspaceFolder}/cargo/dependabot-cargo.gemspec:/home/dependabot/dependabot-core/cargo/dependabot-cargo.gemspec", + "-v", "${localWorkspaceFolder}/cargo/Gemfile:/home/dependabot/dependabot-core/cargo/Gemfile", + "-v", "${localWorkspaceFolder}/cargo/lib:/home/dependabot/dependabot-core/cargo/lib", + "-v", "${localWorkspaceFolder}/cargo/spec:/home/dependabot/dependabot-core/cargo/spec", + "-v", "${localWorkspaceFolder}/composer/dependabot-composer.gemspec:/home/dependabot/dependabot-core/composer/dependabot-composer.gemspec", + "-v", "${localWorkspaceFolder}/composer/Gemfile:/home/dependabot/dependabot-core/composer/Gemfile", + "-v", "${localWorkspaceFolder}/composer/lib:/home/dependabot/dependabot-core/composer/lib", + "-v", "${localWorkspaceFolder}/composer/spec:/home/dependabot/dependabot-core/composer/spec", + "-v", "${localWorkspaceFolder}/docker/dependabot-docker.gemspec:/home/dependabot/dependabot-core/docker/dependabot-docker.gemspec", + "-v", "${localWorkspaceFolder}/docker/Gemfile:/home/dependabot/dependabot-core/docker/Gemfile", + "-v", "${localWorkspaceFolder}/docker/lib:/home/dependabot/dependabot-core/docker/lib", + "-v", "${localWorkspaceFolder}/docker/spec:/home/dependabot/dependabot-core/docker/spec", + "-v", "${localWorkspaceFolder}/elm/dependabot-elm.gemspec:/home/dependabot/dependabot-core/elm/dependabot-elm.gemspec", + "-v", "${localWorkspaceFolder}/elm/Gemfile:/home/dependabot/dependabot-core/elm/Gemfile", + "-v", "${localWorkspaceFolder}/elm/lib:/home/dependabot/dependabot-core/elm/lib", + "-v", "${localWorkspaceFolder}/elm/spec:/home/dependabot/dependabot-core/elm/spec", + "-v", "${localWorkspaceFolder}/git_submodules/dependabot-git_submodules.gemspec:/home/dependabot/dependabot-core/git_submodules/dependabot-git_submodules.gemspec", + "-v", "${localWorkspaceFolder}/git_submodules/Gemfile:/home/dependabot/dependabot-core/git_submodules/Gemfile", + "-v", "${localWorkspaceFolder}/git_submodules/lib:/home/dependabot/dependabot-core/git_submodules/lib", + "-v", "${localWorkspaceFolder}/git_submodules/spec:/home/dependabot/dependabot-core/git_submodules/spec", + "-v", "${localWorkspaceFolder}/github_actions/dependabot-github_actions.gemspec:/home/dependabot/dependabot-core/github_actions/dependabot-github_actions.gemspec", + "-v", "${localWorkspaceFolder}/github_actions/Gemfile:/home/dependabot/dependabot-core/github_actions/Gemfile", + "-v", "${localWorkspaceFolder}/github_actions/lib:/home/dependabot/dependabot-core/github_actions/lib", + "-v", "${localWorkspaceFolder}/github_actions/spec:/home/dependabot/dependabot-core/github_actions/spec", + "-v", "${localWorkspaceFolder}/go_modules/dependabot-go_modules.gemspec:/home/dependabot/dependabot-core/go_modules/dependabot-go_modules.gemspec", + "-v", "${localWorkspaceFolder}/go_modules/Gemfile:/home/dependabot/dependabot-core/go_modules/Gemfile", + "-v", "${localWorkspaceFolder}/go_modules/lib:/home/dependabot/dependabot-core/go_modules/lib", + "-v", "${localWorkspaceFolder}/go_modules/spec:/home/dependabot/dependabot-core/go_modules/spec", + "-v", "${localWorkspaceFolder}/gradle/dependabot-gradle.gemspec:/home/dependabot/dependabot-core/gradle/dependabot-gradle.gemspec", + "-v", "${localWorkspaceFolder}/gradle/Gemfile:/home/dependabot/dependabot-core/gradle/Gemfile", + "-v", "${localWorkspaceFolder}/gradle/lib:/home/dependabot/dependabot-core/gradle/lib", + "-v", "${localWorkspaceFolder}/gradle/spec:/home/dependabot/dependabot-core/gradle/spec", + "-v", "${localWorkspaceFolder}/hex/dependabot-hex.gemspec:/home/dependabot/dependabot-core/hex/dependabot-hex.gemspec", + "-v", "${localWorkspaceFolder}/hex/Gemfile:/home/dependabot/dependabot-core/hex/Gemfile", + "-v", "${localWorkspaceFolder}/hex/lib:/home/dependabot/dependabot-core/hex/lib", + "-v", "${localWorkspaceFolder}/hex/spec:/home/dependabot/dependabot-core/hex/spec", + "-v", "${localWorkspaceFolder}/maven/dependabot-maven.gemspec:/home/dependabot/dependabot-core/maven/dependabot-maven.gemspec", + "-v", "${localWorkspaceFolder}/maven/Gemfile:/home/dependabot/dependabot-core/maven/Gemfile", + "-v", "${localWorkspaceFolder}/maven/lib:/home/dependabot/dependabot-core/maven/lib", + "-v", "${localWorkspaceFolder}/maven/spec:/home/dependabot/dependabot-core/maven/spec", + "-v", "${localWorkspaceFolder}/npm_and_yarn/dependabot-npm_and_yarn.gemspec:/home/dependabot/dependabot-core/npm_and_yarn/dependabot-npm_and_yarn.gemspec", + "-v", "${localWorkspaceFolder}/npm_and_yarn/Gemfile:/home/dependabot/dependabot-core/npm_and_yarn/Gemfile", + "-v", "${localWorkspaceFolder}/npm_and_yarn/lib:/home/dependabot/dependabot-core/npm_and_yarn/lib", + "-v", "${localWorkspaceFolder}/npm_and_yarn/spec:/home/dependabot/dependabot-core/npm_and_yarn/spec", + "-v", "${localWorkspaceFolder}/nuget/dependabot-nuget.gemspec:/home/dependabot/dependabot-core/nuget/dependabot-nuget.gemspec", + "-v", "${localWorkspaceFolder}/nuget/Gemfile:/home/dependabot/dependabot-core/nuget/Gemfile", + "-v", "${localWorkspaceFolder}/nuget/lib:/home/dependabot/dependabot-core/nuget/lib", + "-v", "${localWorkspaceFolder}/nuget/spec:/home/dependabot/dependabot-core/nuget/spec", + "-v", "${localWorkspaceFolder}/pub/dependabot-pub.gemspec:/home/dependabot/dependabot-core/pub/dependabot-pub.gemspec", + "-v", "${localWorkspaceFolder}/pub/Gemfile:/home/dependabot/dependabot-core/pub/Gemfile", + "-v", "${localWorkspaceFolder}/pub/lib:/home/dependabot/dependabot-core/pub/lib", + "-v", "${localWorkspaceFolder}/pub/spec:/home/dependabot/dependabot-core/pub/spec", + "-v", "${localWorkspaceFolder}/python/dependabot-python.gemspec:/home/dependabot/dependabot-core/python/dependabot-python.gemspec", + "-v", "${localWorkspaceFolder}/python/Gemfile:/home/dependabot/dependabot-core/python/Gemfile", + "-v", "${localWorkspaceFolder}/python/lib:/home/dependabot/dependabot-core/python/lib", + "-v", "${localWorkspaceFolder}/python/spec:/home/dependabot/dependabot-core/python/spec", + "-v", "${localWorkspaceFolder}/terraform/dependabot-terraform.gemspec:/home/dependabot/dependabot-core/terraform/dependabot-terraform.gemspec", + "-v", "${localWorkspaceFolder}/terraform/Gemfile:/home/dependabot/dependabot-core/terraform/Gemfile", + "-v", "${localWorkspaceFolder}/terraform/lib:/home/dependabot/dependabot-core/terraform/lib", + "-v", "${localWorkspaceFolder}/terraform/spec:/home/dependabot/dependabot-core/terraform/spec", + "-v", "${localWorkspaceFolder}/omnibus/Gemfile:/home/dependabot/dependabot-core/omnibus/Gemfile", + "-v", "${localWorkspaceFolder}/omnibus/dependabot-omnibus.gemspec:/home/dependabot/dependabot-core/omnibus/dependabot-omnibus.gemspec", + "-v", "${localWorkspaceFolder}/omnibus/lib:/home/dependabot/dependabot-core/omnibus/lib", + + "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" + ], + + // Use 'settings' to set *default* container specific settings.json values on container create. + // You can edit these settings after create using File > Preferences > Settings > Remote. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "solargraph.useBundler": true, + "ruby.useBundler": true, + "ruby.useLanguageServer": true, + "ruby.lint": { + "rubocop": { + "useBundler": true, + "lint": true + }, + "reek": { + "useBundler": true + } + }, + "ruby.format": "rubocop", + "[ruby]": { + "editor.defaultFormatter": "misogi.ruby-rubocop" + } + }, + + // Uncomment the next line if you want to publish any ports. + // "appPort": [], + + // Uncomment the next line to run commands after the container is created. + // "postCreateCommand": "ruby --version" + + "extensions": [ + "rebornix.ruby", + "castwide.solargraph", + "misogi.ruby-rubocop", + "groksrc.ruby", + "hoovercj.ruby-linter", + "miguel-savignano.ruby-symbols" + ] +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 16530dd764b..80b98703148 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,129 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu { - "name": "Ruby", - "dockerFile": "../Dockerfile.development", - - "workspaceFolder": "/home/dependabot/dependabot-core", - - "runArgs": [ - "-u", "dependabot", - "-e", "LOCAL_GITHUB_ACCESS_TOKEN=${env:LOCAL_GITHUB_ACCESS_TOKEN}", - "-e", "LOCAL_CONFIG_VARIABLES=${env:LOCAL_CONFIG_VARIABLES}", - - "-v", "${localWorkspaceFolder}/.vscode:/home/dependabot/dependabot-core/.vscode", - "-v", "${localWorkspaceFolder}/.gitignore:/home/dependabot/dependabot-core/.gitignore", - "-v", "${localWorkspaceFolder}/.rubocop.yml:/home/dependabot/dependabot-core/.rubocop.yml", - "-v", "${localWorkspaceFolder}/bin:/home/dependabot/dependabot-core/bin", - "-v", "${localWorkspaceFolder}/common/Gemfile:/home/dependabot/dependabot-core/common/Gemfile", - "-v", "${localWorkspaceFolder}/common/dependabot-common.gemspec:/home/dependabot/dependabot-core/common/dependabot-common.gemspec", - "-v", "${localWorkspaceFolder}/common/bin:/home/dependabot/dependabot-core/common/bin", - "-v", "${localWorkspaceFolder}/common/lib:/home/dependabot/dependabot-core/common/lib", - "-v", "${localWorkspaceFolder}/common/spec:/home/dependabot/dependabot-core/common/spec", - "-v", "${localWorkspaceFolder}/bundler/dependabot-bundler.gemspec:/home/dependabot/dependabot-core/bundler/dependabot-bundler.gemspec", - "-v", "${localWorkspaceFolder}/bundler/Gemfile:/home/dependabot/dependabot-core/bundler/Gemfile", - "-v", "${localWorkspaceFolder}/bundler/lib:/home/dependabot/dependabot-core/bundler/lib", - "-v", "${localWorkspaceFolder}/bundler/spec:/home/dependabot/dependabot-core/bundler/spec", - "-v", "${localWorkspaceFolder}/cargo/dependabot-cargo.gemspec:/home/dependabot/dependabot-core/cargo/dependabot-core.gemspec", - "-v", "${localWorkspaceFolder}/cargo/Gemfile:/home/dependabot/dependabot-core/cargo/Gemfile", - "-v", "${localWorkspaceFolder}/cargo/lib:/home/dependabot/dependabot-core/cargo/lib", - "-v", "${localWorkspaceFolder}/cargo/spec:/home/dependabot/dependabot-core/cargo/spec", - "-v", "${localWorkspaceFolder}/composer/dependabot-composer.gemspec:/home/dependabot/dependabot-core/composer/dependabot-composer.gemspec", - "-v", "${localWorkspaceFolder}/composer/Gemfile:/home/dependabot/dependabot-core/composer/Gemfile", - "-v", "${localWorkspaceFolder}/composer/lib:/home/dependabot/dependabot-core/composer/lib", - "-v", "${localWorkspaceFolder}/composer/spec:/home/dependabot/dependabot-core/composer/spec", - "-v", "${localWorkspaceFolder}/dep/dependabot-dep.gemspec:/home/dependabot/dependabot-core/dep/dependabot-dep.gemspec", - "-v", "${localWorkspaceFolder}/dep/Gemfile:/home/dependabot/dependabot-core/dep/Gemfile", - "-v", "${localWorkspaceFolder}/dep/lib:/home/dependabot/dependabot-core/dep/lib", - "-v", "${localWorkspaceFolder}/dep/spec:/home/dependabot/dependabot-core/dep/spec", - "-v", "${localWorkspaceFolder}/docker/dependabot-docker.gemspec:/home/dependabot/dependabot-core/docker/dependabot-docker.gemspec", - "-v", "${localWorkspaceFolder}/docker/Gemfile:/home/dependabot/dependabot-core/docker/Gemfile", - "-v", "${localWorkspaceFolder}/docker/lib:/home/dependabot/dependabot-core/docker/lib", - "-v", "${localWorkspaceFolder}/docker/spec:/home/dependabot/dependabot-core/docker/spec", - "-v", "${localWorkspaceFolder}/elm/dependabot-elm.gemspec:/home/dependabot/dependabot-core/elm/dependabot-elm.gemspec", - "-v", "${localWorkspaceFolder}/elm/Gemfile:/home/dependabot/dependabot-core/elm/Gemfile", - "-v", "${localWorkspaceFolder}/elm/lib:/home/dependabot/dependabot-core/elm/lib", - "-v", "${localWorkspaceFolder}/elm/spec:/home/dependabot/dependabot-core/elm/spec", - "-v", "${localWorkspaceFolder}/git_submodules/dependabot-git_submodules.gemspec:/home/dependabot/dependabot-core/git_submodules/dependabot-core.gemspec", - "-v", "${localWorkspaceFolder}/git_submodules/Gemfile:/home/dependabot/dependabot-core/git_submodules/Gemfile", - "-v", "${localWorkspaceFolder}/git_submodules/lib:/home/dependabot/dependabot-core/git_submodules/lib", - "-v", "${localWorkspaceFolder}/git_submodules/spec:/home/dependabot/dependabot-core/git_submodules/spec", - "-v", "${localWorkspaceFolder}/github_actions/dependabot-github_actions.gemspec:/home/dependabot/dependabot-core/github_actions/dependabot-core.gemspec", - "-v", "${localWorkspaceFolder}/github_actions/Gemfile:/home/dependabot/dependabot-core/github_actions/Gemfile", - "-v", "${localWorkspaceFolder}/github_actions/lib:/home/dependabot/dependabot-core/github_actions/lib", - "-v", "${localWorkspaceFolder}/github_actions/spec:/home/dependabot/dependabot-core/github_actions/spec", - "-v", "${localWorkspaceFolder}/go_modules/dependabot-go_modules.gemspec:/home/dependabot/dependabot-core/go_modules/dependabot-go_modules.gemspec", - "-v", "${localWorkspaceFolder}/go_modules/Gemfile:/home/dependabot/dependabot-core/go_modules/Gemfile", - "-v", "${localWorkspaceFolder}/go_modules/lib:/home/dependabot/dependabot-core/go_modules/lib", - "-v", "${localWorkspaceFolder}/go_modules/spec:/home/dependabot/dependabot-core/go_modules/spec", - "-v", "${localWorkspaceFolder}/gradle/dependabot-gradle.gemspec:/home/dependabot/dependabot-core/gradle/dependabot-gradle.gemspec", - "-v", "${localWorkspaceFolder}/gradle/Gemfile:/home/dependabot/dependabot-core/gradle/Gemfile", - "-v", "${localWorkspaceFolder}/gradle/lib:/home/dependabot/dependabot-core/gradle/lib", - "-v", "${localWorkspaceFolder}/gradle/spec:/home/dependabot/dependabot-core/gradle/spec", - "-v", "${localWorkspaceFolder}/hex/dependabot-hex.gemspec:/home/dependabot/dependabot-core/hex/dependabot-hex.gemspec", - "-v", "${localWorkspaceFolder}/hex/Gemfile:/home/dependabot/dependabot-core/hex/Gemfile", - "-v", "${localWorkspaceFolder}/hex/lib:/home/dependabot/dependabot-core/hex/lib", - "-v", "${localWorkspaceFolder}/hex/spec:/home/dependabot/dependabot-core/hex/spec", - "-v", "${localWorkspaceFolder}/maven/dependabot-maven.gemspec:/home/dependabot/dependabot-core/maven/dependabot-core.gemspec", - "-v", "${localWorkspaceFolder}/maven/Gemfile:/home/dependabot/dependabot-core/maven/Gemfile", - "-v", "${localWorkspaceFolder}/maven/lib:/home/dependabot/dependabot-core/maven/lib", - "-v", "${localWorkspaceFolder}/maven/spec:/home/dependabot/dependabot-core/maven/spec", - "-v", "${localWorkspaceFolder}/npm_and_yarn/dependabot-npm_and_yarn.gemspec:/home/dependabot/dependabot-core/npm_and_yarn/dependabot-npm_and_yarn.gemspec", - "-v", "${localWorkspaceFolder}/npm_and_yarn/Gemfile:/home/dependabot/dependabot-core/npm_and_yarn/Gemfile", - "-v", "${localWorkspaceFolder}/npm_and_yarn/lib:/home/dependabot/dependabot-core/npm_and_yarn/lib", - "-v", "${localWorkspaceFolder}/npm_and_yarn/spec:/home/dependabot/dependabot-core/npm_and_yarn/spec", - "-v", "${localWorkspaceFolder}/nuget/dependabot-nuget.gemspec:/home/dependabot/dependabot-core/nuget/dependabot-core.gemspec", - "-v", "${localWorkspaceFolder}/nuget/Gemfile:/home/dependabot/dependabot-core/nuget/Gemfile", - "-v", "${localWorkspaceFolder}/nuget/lib:/home/dependabot/dependabot-core/nuget/lib", - "-v", "${localWorkspaceFolder}/nuget/spec:/home/dependabot/dependabot-core/nuget/spec", - "-v", "${localWorkspaceFolder}/python/dependabot-python.gemspec:/home/dependabot/dependabot-core/python/dependabot-python.gemspec", - "-v", "${localWorkspaceFolder}/python/Gemfile:/home/dependabot/dependabot-core/python/Gemfile", - "-v", "${localWorkspaceFolder}/python/lib:/home/dependabot/dependabot-core/python/lib", - "-v", "${localWorkspaceFolder}/python/spec:/home/dependabot/dependabot-core/python/spec", - "-v", "${localWorkspaceFolder}/terraform/dependabot-terraform.gemspec:/home/dependabot/dependabot-core/terraform/dependabot-terraform.gemspec", - "-v", "${localWorkspaceFolder}/terraform/Gemfile:/home/dependabot/dependabot-core/terraform/Gemfile", - "-v", "${localWorkspaceFolder}/terraform/lib:/home/dependabot/dependabot-core/terraform/lib", - "-v", "${localWorkspaceFolder}/terraform/spec:/home/dependabot/dependabot-core/terraform/spec", - "-v", "${localWorkspaceFolder}/omnibus/Gemfile:/home/dependabot/dependabot-core/omnibus/Gemfile", - "-v", "${localWorkspaceFolder}/omnibus/dependabot-omnibus.gemspec:/home/dependabot/dependabot-core/omnibus/dependabot-omnibus.gemspec", - "-v", "${localWorkspaceFolder}/omnibus/lib:/home/dependabot/dependabot-core/omnibus/lib", - "-v", "${localWorkspaceFolder}/omnibus/spec:/home/dependabot/dependabot-core/omnibus/spec", - - "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" - ], - - // Use 'settings' to set *default* container specific settings.json values on container create. - // You can edit these settings after create using File > Preferences > Settings > Remote. - "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - "solargraph.useBundler": true, - "ruby.useBundler": true, - "ruby.useLanguageServer": true, - "ruby.lint": { - "rubocop": { - "useBundler": true, - "lint": true - }, - "reek": { - "useBundler": true - } - }, - "ruby.format": "rubocop", - "[ruby]": { - "editor.defaultFormatter": "misogi.ruby-rubocop" + "name": "Ubuntu", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04 + // Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon. + "args": { + "VARIANT": "ubuntu-22.04" } }, - - // Uncomment the next line if you want to publish any ports. - // "appPort": [], - - // Uncomment the next line to run commands after the container is created. - // "postCreateCommand": "ruby --version" - - "extensions": [ - "rebornix.ruby", - "castwide.solargraph", - "misogi.ruby-rubocop", - "groksrc.ruby", - "hoovercj.ruby-linter", - "miguel-savignano.ruby-symbols" - ] + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + "onCreateCommand": "bash .devcontainer/on-create.sh", + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "bash .devcontainer/post-create.sh", + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "docker-from-docker": "latest", + "github-cli": "latest", + "node": "lts", + "golang": "latest", + "ruby": "latest", + "rust": "latest", + "dotnet": "latest", + "ghcr.io/devcontainers/features/sshd:1": { + "version": "latest" + } + } } diff --git a/.devcontainer/on-create.sh b/.devcontainer/on-create.sh new file mode 100644 index 00000000000..9ecc3725459 --- /dev/null +++ b/.devcontainer/on-create.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This pull takes a while, adding it to the prebuild +docker pull ghcr.io/dependabot/dependabot-updater:latest +docker pull ghcr.io/github/dependabot-update-job-proxy/dependabot-update-job-proxy:latest diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100644 index 00000000000..fb20394c68c --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,7 @@ +#!/bin/bash +gh release download --repo dependabot/cli -p "*linux-amd64.tar.gz" +tar xzvf "*.tar.gz" >/dev/null 2>&1 +sudo mv dependabot /usr/local/bin +rm "*.tar.gz" + +echo "export LOCAL_GITHUB_ACCESS_TOKEN=$GITHUB_TOKEN" >> ~/.bashrc diff --git a/.dockerignore b/.dockerignore index 6f221846275..b6900a6f7b2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,27 @@ -/.bundle +/.core-bash_history +/.env +/.envrc /.git -/tmp/ -/helpers -/spec -gitignored +/.github +/.vscode-server-insiders/ +/.vscode-server/ +/.vscode/ +/dependabot-*.gem +/dry-run +/pkg +/vendor +/tmp +**/.bundle +**/coverage +**/Gemfile.lock +!updater/Gemfile.lock +!updater/spec/fixtures/**/Gemfile.lock +**/node_modules +!**/spec/fixtures/* +git.store +.DS_Store +*.pyc +.dockerignore +Dockerfile* +*.md +CODEOWNERS diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index b9465cc3d66..00000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: "\U0001F41B Bug report" -about: Report a bug in Dependabot to help us fix it -title: '' -labels: bug -assignees: '' - ---- - - - - - - - -**Package manager/ecosystem** - -**Manifest contents prior to update** - -**Updated dependency** - -**What you expected to see, versus what you actually saw** - -**Images of the diff or a link to the PR, issue or logs** - diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 00000000000..1ab4737905b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,91 @@ +name: 🐛 Bug report +description: Report a bug in dependabot-core to help us fix it +labels: ["T: bug 🐞"] +body: + - type: markdown + attributes: + value: | + For support on the GitHub-integrated Dependabot service, please contact [GitHub support](https://support.github.com/). + This issue-tracker is meant for issues related to Dependabot's updating logic, a good rule of thumb is that if you have questions about the _diff_ in a PR, it belongs here, otherwise the GitHub support team is best equipped to help you. + + The more information you can provide, the easier it will be to reproduce the issue and find a fix. + + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search existing issues to avoid creating duplicates. + options: + - label: I have searched the existing issues + required: true + + - type: input + attributes: + label: Package ecosystem + description: Are you using npm, Docker, Bundler, etc. + validations: + required: true + + - type: input + attributes: + label: Package manager version + description: If applicable, specify the package manager version you're using (e.g., npm `7.1`, pip-compile `5.0`, etc.) + validations: + required: false + + - type: input + attributes: + label: Language version + description: If applicable, specify the language version you're using (e.g., Node.js `16.18`, Ruby `3.1`, etc.) + validations: + required: false + + - type: textarea + attributes: + label: Manifest location and content before the Dependabot update + description: | + If applicable, specify the path to each manifest file (`/client/package.json`, `/Gemfile`, etc.) + If applicable, attach each manifest file or provide a link to each manifest file. + validations: + required: false + + - type: textarea + attributes: + label: dependabot.yml content + description: If using GitHub-native Dependabot, attach your `dependabot.yml` file or provide a link to it. + validations: + required: false + + - type: textarea + attributes: + label: Updated dependency + description: If applicable, the dependency name and to and from versions. + validations: + required: false + + - type: textarea + attributes: + label: What you expected to see, versus what you actually saw + description: A clear and concise description of what you expected to happen. + validations: + required: true + + - type: textarea + attributes: + label: Native package manager behavior + description: If applicable, what output do you see when you update the dependency using the native package manager (e.g., Bundler, npm, etc.)? + validations: + required: false + + - type: textarea + attributes: + label: Images of the diff or a link to the PR, issue, or logs + description: If applicable, add links to public PRs or Issues that Dependabot opened, and/or paste in any related logs. + validations: + required: false + + - type: textarea + attributes: + label: Smallest manifest that reproduces the issue + description: Want to make a 🤖 smile? You can do it! Show us the smallest manifest file (or set of files) that reproduces this problem. Remove anything that's not essential to reproduce this issue, and it will help us address the problem more quickly. ✨ + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..6f158ee1ec9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Questions or comments about Dependabot Alerts or Security Updates + url: https://support.github.com/ + about: You're looking at the repository for Dependabot's updating logic. For issues about Dependabot the service, please contact GitHub Support. diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index 06c59217328..00000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: "\U0001F680 Feature request" -about: Suggest an idea for Dependabot -title: '' -labels: enhancements -assignees: '' - ---- - - - - - - diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 00000000000..c6962f8e6db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,18 @@ +name: 🚀 Feature request +description: Suggest an idea for Dependabot +labels: "T: feature-request" +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search existing issues to avoid creating duplicates. + options: + - label: I have searched the existing issues + required: true + + - type: textarea + attributes: + label: Feature description + description: Describe the feature you'd like. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/tech-debt.yml b/.github/ISSUE_TEMPLATE/tech-debt.yml new file mode 100644 index 00000000000..1af1978e378 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tech-debt.yml @@ -0,0 +1,18 @@ +name: ⚙ Tech Debt +description: Tech debt is for code improvements that do not change the user-facing behavior (ie, neither adding features nor fixing bugs). +labels: "T: tech-debt ⚙ī¸" +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search existing issues to avoid creating duplicates. + options: + - label: I have searched the existing issues + required: true + + - type: textarea + attributes: + label: Code improvement description + description: Describe the code improvement you'd like. + validations: + required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b325d7aa87a..c9b5c287b35 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,26 +1,53 @@ version: 2 updates: - package-ecosystem: "bundler" - directory: "/common" + directory: "/updater" schedule: - interval: "daily" + interval: "weekly" + + # No ecosystem folders are watched because they roll up to the omnibus watcher + - package-ecosystem: "bundler" + directory: "/omnibus" + schedule: + interval: "weekly" + + # Watch the per-ecosystem native helpers + - package-ecosystem: "composer" + directory: "/composer/helpers/v1" + schedule: + interval: "weekly" - package-ecosystem: "composer" - directory: "/composer/helpers" + directory: "/composer/helpers/v2" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" schedule: - interval: "daily" + interval: "weekly" + - package-ecosystem: "gomod" + directory: "/go_modules/helpers" + schedule: + interval: "weekly" - package-ecosystem: "mix" directory: "/hex/helpers" schedule: - interval: "daily" + interval: "weekly" - package-ecosystem: "npm" directory: "/npm_and_yarn/helpers" schedule: - interval: "daily" + interval: "weekly" + ignore: + - dependency-name: "npm" + update-types: ["version-update:semver-major"] - package-ecosystem: "pip" directory: "/python/helpers" schedule: - interval: "daily" - - package-ecosystem: "gomod" - directory: "/go_modules/helpers" + interval: "weekly" + - package-ecosystem: "pub" + directory: "/pub/helpers" schedule: - interval: "daily" + interval: "weekly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..0ed181b271a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,203 @@ +name: CI +on: + push: + branches: + - "main" + pull_request: + schedule: + - cron: "0 0 * * *" + +jobs: + ci: + name: CI + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + suite: + - { path: bundler, name: bundler1, ci_node_total: 2, ci_node_index: 0 } + - { path: bundler, name: bundler1, ci_node_total: 2, ci_node_index: 1 } + - { path: bundler, name: bundler2, ci_node_total: 2, ci_node_index: 0 } + - { path: bundler, name: bundler2, ci_node_total: 2, ci_node_index: 1 } + - { path: cargo, name: cargo } + - { path: common, name: common } + - { path: composer, name: composer, ci_node_total: 2, ci_node_index: 0 } + - { path: composer, name: composer, ci_node_total: 2, ci_node_index: 1 } + - { path: docker, name: docker } + - { path: elm, name: elm } + - { path: git_submodules, name: git_submodules } + - { path: github_actions, name: github_actions } + - { path: go_modules, name: go_module, ci_node_total: 2, index: 0 } + - { path: go_modules, name: go_module, ci_node_total: 2, index: 1 } + - { path: gradle, name: gradle } + - { path: hex, name: hex, ci_node_total: 2, ci_node_index: 0 } + - { path: hex, name: hex, ci_node_total: 2, ci_node_index: 1 } + - { path: maven, name: maven } + - { path: npm_and_yarn, name: npm_and_yarn, ci_node_total: 3, ci_node_index: 0 } + - { path: npm_and_yarn, name: npm_and_yarn, ci_node_total: 3, ci_node_index: 1 } + - { path: npm_and_yarn, name: npm_and_yarn, ci_node_total: 3, ci_node_index: 2 } + - { path: nuget, name: nuget } + - { path: omnibus, name: omnibus } + - { path: python, name: python, ci_node_total: 5, ci_node_index: 0 } + - { path: python, name: python, ci_node_total: 5, ci_node_index: 1 } + - { path: python, name: python, ci_node_total: 5, ci_node_index: 2 } + - { path: python, name: python, ci_node_total: 5, ci_node_index: 3 } + - { path: python, name: python, ci_node_total: 5, ci_node_index: 4 } + - { path: python, name: python_slow, ci_node_total: 5, ci_node_index: 0 } + - { path: python, name: python_slow, ci_node_total: 5, ci_node_index: 1 } + - { path: python, name: python_slow, ci_node_total: 5, ci_node_index: 2 } + - { path: python, name: python_slow, ci_node_total: 5, ci_node_index: 3 } + - { path: python, name: python_slow, ci_node_total: 5, ci_node_index: 4 } + - { path: pub, name: pub, ci_node_total: 2, ci_node_index: 0 } + - { path: pub, name: pub, ci_node_total: 2, ci_node_index: 1 } + - { path: terraform, name: terraform } + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - uses: dorny/paths-filter@v2 + id: changes + with: + filters: | + bundler: + - Dockerfile + - 'common/**' + - 'bundler/**' + cargo: + - Dockerfile + - 'common/**' + - 'cargo/**' + common: + - Dockerfile + - 'common/**' + composer: + - Dockerfile + - 'common/**' + - 'composer/**' + docker: + - Dockerfile + - 'common/**' + - 'docker/**' + elm: + - Dockerfile + - 'common/**' + - 'elm/**' + git_submodules: + - Dockerfile + - 'common/**' + - 'git_submodules/**' + github_actions: + - Dockerfile + - 'common/**' + - 'github_actions/**' + go_modules: + - Dockerfile + - 'common/**' + - 'go_modules/**' + gradle: + - Dockerfile + - 'common/**' + - 'maven/**' + - 'gradle/**' + hex: + - Dockerfile + - 'common/**' + - 'hex/**' + maven: + - Dockerfile + - 'common/**' + - 'maven/**' + npm_and_yarn: + - Dockerfile + - 'common/**' + - 'npm_and_yarn/**' + nuget: + - Dockerfile + - 'common/**' + - 'nuget/**' + omnibus: + - Dockerfile + - 'common/**' + - 'omnibus/**' + pub: + - Dockerfile + - 'common/**' + - 'pub/**' + python: + - Dockerfile + - 'common/**' + - 'python/**' + terraform: + - Dockerfile + - 'common/**' + - 'terraform/**' + + - name: Build dependabot-core image + if: steps.changes.outputs[matrix.suite.path] == 'true' + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + + - name: Build dependabot-core-ci image + if: steps.changes.outputs[matrix.suite.path] == 'true' + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -f Dockerfile.ci \ + -t "dependabot-core-ci:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + . + + - name: Run ${{ matrix.suite.name }} tests + if: steps.changes.outputs[matrix.suite.path] == 'true' + run: | + docker run \ + --env "CI=true" \ + --env "RAISE_ON_WARNINGS=true" \ + --env "DEPENDABOT_TEST_ACCESS_TOKEN=${{ secrets.GITHUB_TOKEN }}" \ + --env "SUITE_NAME=${{ matrix.suite.name }}" \ + --env "CI_NODE_TOTAL=${{ matrix.suite.ci_node_total }}" \ + --env "CI_NODE_INDEX=${{ matrix.suite.ci_node_index }}" \ + --rm dependabot-core-ci bash -c \ + "cd /home/dependabot/dependabot-core/${{ matrix.suite.path }} && ./script/ci-test" + + updater: + name: Updater + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Build dependabot-core image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + - name: Build + run: script/build + - name: Lint + run: script/lint + env: + SKIP_BUILD: true + - name: Run updater tests + run: ./script/ci-test-updater + env: + SKIP_BUILD: true + DEPENDABOT_TEST_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: ./bin/lint diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..bfa5d46ba3e --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,75 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + paths-ignore: + - '*/spec/fixtures/**' + - 'CHANGELOG.md' + - 'common/lib/dependabot/version.rb' + schedule: + - cron: '41 4 * * 3' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + if: ${{ github.event_name != 'schedule' || github.repository == 'dependabot/dependabot-core' }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go', 'javascript', 'python', 'ruby' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000000..e7d9c501cd2 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,15 @@ +name: Dependency Review +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Perform Dependency Review + uses: actions/dependency-review-action@v3 diff --git a/.github/workflows/docker-branch-releases.yml b/.github/workflows/docker-branch-releases.yml new file mode 100644 index 00000000000..1a8eef84374 --- /dev/null +++ b/.github/workflows/docker-branch-releases.yml @@ -0,0 +1,84 @@ +name: Push branch images +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BASE_IMAGE: "ubuntu:20.04" + UPDATER_IMAGE: "dependabot/updater" + UPDATER_IMAGE_MIRROR: "ghcr.io/dependabot/dependabot-updater" +on: + pull_request: + branches: + - main + types: + - synchronize + pull_request_review: + types: + - submitted + +jobs: + push-updater-image: + name: Deploy + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + TAG: ${{ github.sha }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + # sets DECISION to the PR's review decision, handling the push-after-approval case + - name: Check if pull request is approved + run: | + DECISION=$(gh pr view ${{ github.event.pull_request.number }} --json reviewDecision,state -t '{{.reviewDecision}}:{{.state}}') + echo "Review decision is: $DECISION" + echo "DECISION=$DECISION" >> $GITHUB_ENV + + # overwrite the previous result if this is a fork since forks can't publish to GHCR + - name: Skip forks + if: github.event.pull_request.head.repo.fork + run: echo "DECISION=FORK" >> $GITHUB_ENV + + - name: Build dependabot-core image + if: env.DECISION == 'APPROVED:OPEN' + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + + - name: Build dependabot-updater image + if: env.DECISION == 'APPROVED:OPEN' + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "$UPDATER_IMAGE:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$UPDATER_IMAGE_MIRROR" \ + --build-arg OMNIBUS_VERSION=$TAG \ + -f Dockerfile.updater \ + . + + - name: Log in to GHCR + if: env.DECISION == 'APPROVED:OPEN' + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Push branch image + if: env.DECISION == 'APPROVED:OPEN' + run: | + docker tag "$UPDATER_IMAGE:$TAG" "$UPDATER_IMAGE_MIRROR:$TAG" + docker push "$UPDATER_IMAGE_MIRROR:$TAG" + + - name: Set summary + if: env.DECISION == 'APPROVED:OPEN' + run: | + echo "updater uploaded with tag \`$TAG\`" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "$UPDATER_IMAGE_MIRROR:$TAG" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/docker-fork-releases.yml b/.github/workflows/docker-fork-releases.yml new file mode 100644 index 00000000000..160df4b6799 --- /dev/null +++ b/.github/workflows/docker-fork-releases.yml @@ -0,0 +1,88 @@ +name: Push fork images +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BASE_IMAGE: "ubuntu:20.04" + UPDATER_IMAGE: "dependabot/updater" + UPDATER_IMAGE_MIRROR: "ghcr.io/dependabot/dependabot-updater" +on: + workflow_dispatch: + inputs: + pr: + required: true + type: string + description: PR number + +jobs: + push-fork-image: + name: Deploy + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + TAG: ${{ github.sha }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Check if pull request is approved + # The PR must be approved. This is mostly to ensure you've typed the correct PR. + # Note: forks will have a blank review decision without approval. Not NEEDS_REVIEW. + run: | + DECISION=$(gh pr view ${{ github.event.inputs.pr }} --json reviewDecision -t {{.reviewDecision}}) + echo "Review decision is: $DECISION" + [[ $DECISION == "APPROVED" ]] || exit 1 + + - name: Checkout the fork + # This checks out the fork and cherry-picks the changes onto main, creating a new merge SHA tag. + run: | + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + gh pr checkout ${{ github.event.inputs.pr }} --branch docker-branch-release-workflow + git reset main + git add . + git commit -m squashed + PICK=$(git rev-parse HEAD) + git checkout main + git cherry-pick $PICK + echo "TAG=$(git rev-parse HEAD)" >> $GITHUB_ENV + + - name: Build dependabot-core image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + + - name: Build dependabot-updater image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "$UPDATER_IMAGE:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$UPDATER_IMAGE_MIRROR" \ + --build-arg OMNIBUS_VERSION=$TAG \ + -f Dockerfile.updater \ + . + + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Push fork image + run: | + docker tag "$UPDATER_IMAGE:$TAG" "$UPDATER_IMAGE_MIRROR:$TAG" + docker push "$UPDATER_IMAGE_MIRROR:$TAG" + + - name: Set summary + run: | + echo "generated for PR ${{ github.event.inputs.pr }}" > $GITHUB_STEP_SUMMARY + echo "updater uploaded with tag \`$TAG\`" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "$UPDATER_IMAGE_MIRROR:$TAG" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/docker-main-releases.yml b/.github/workflows/docker-main-releases.yml new file mode 100644 index 00000000000..0658b39566f --- /dev/null +++ b/.github/workflows/docker-main-releases.yml @@ -0,0 +1,73 @@ +name: Push latest images +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BASE_IMAGE: "ubuntu:20.04" + UPDATER_IMAGE: "dependabot/updater" + UPDATER_IMAGE_MIRROR: "ghcr.io/dependabot/dependabot-updater" +on: + push: + branches: + - main + paths-ignore: + - "CHANGELOG.md" + - "common/lib/dependabot/version.rb" + +jobs: + push-updater-image: + name: Deploy + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + TAG: ${{ github.sha }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Build dependabot-core image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + + - name: Build dependabot-updater image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "$UPDATER_IMAGE:$TAG" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$UPDATER_IMAGE_MIRROR" \ + --build-arg OMNIBUS_VERSION=$TAG \ + -f Dockerfile.updater \ + . + + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Push branch image + run: | + docker tag "$UPDATER_IMAGE:$TAG" "$UPDATER_IMAGE_MIRROR:$TAG" + docker push "$UPDATER_IMAGE_MIRROR:$TAG" + + - name: Push latest on main + run: | + # The v2 tag is the Updater image tag, not related to the core version. + DATE_BASED_VERSION=v2.0.$(date +%Y%m%d%H%M%S) + docker tag "$UPDATER_IMAGE:$TAG" "$UPDATER_IMAGE_MIRROR:latest" + docker tag "$UPDATER_IMAGE:$TAG" "$UPDATER_IMAGE_MIRROR:$DATE_BASED_VERSION" + docker push --all-tags "$UPDATER_IMAGE_MIRROR" + + - name: Set summary + run: | + echo "updater uploaded with tag \`$TAG\`" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "$UPDATER_IMAGE_MIRROR:$TAG" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000000..eca1e0f92cb --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,122 @@ +name: Push docker images +env: + BASE_IMAGE: "ubuntu:20.04" + CORE_IMAGE: "dependabot/dependabot-core" + CORE_IMAGE_MIRROR: "ghcr.io/dependabot/dependabot-core" + UPDATER_IMAGE: "dependabot/dependabot-updater" + UPDATER_IMAGE_MIRROR: "ghcr.io/dependabot/dependabot-updater" +on: + push: + branches: + - main + tags: + - v[0-9]+.[0-9]+.[0-9]+ +jobs: + push-core-image: + name: Push dependabot-core image to docker hub + runs-on: ubuntu-latest + if: github.repository == 'dependabot/dependabot-core' + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Build dependabot-core image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "$CORE_IMAGE:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$CORE_IMAGE:latest" \ + . + - name: Log in to the Docker registry + run: | + echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Push latest image + run: | + docker push "$CORE_IMAGE:latest" + docker tag "$CORE_IMAGE:latest" "$CORE_IMAGE_MIRROR:latest" + docker push "$CORE_IMAGE_MIRROR:latest" + - name: Push tagged image + if: contains(github.ref, 'refs/tags') + run: | + VERSION="$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" common/lib/dependabot/version.rb)" + docker tag "$CORE_IMAGE:latest" "$CORE_IMAGE:$VERSION" + docker push "$CORE_IMAGE:$VERSION" + docker tag "$CORE_IMAGE:latest" "$CORE_IMAGE_MIRROR:$VERSION" + docker push "$CORE_IMAGE_MIRROR:$VERSION" + push-updater-image: + name: Push tagged dependabot-updater image + runs-on: ubuntu-latest + if: contains(github.ref, 'refs/tags') + needs: push-core-image + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Build dependabot-updater image + env: + DOCKER_BUILDKIT: 1 + run: | + VERSION="$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" common/lib/dependabot/version.rb)" + docker build \ + -t "$UPDATER_IMAGE:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$UPDATER_IMAGE:latest" \ + --build-arg OMNIBUS_VERSION=$VERSION \ + -f Dockerfile.updater \ + . + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Push tagged image + run: | + VERSION="$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" common/lib/dependabot/version.rb)" + docker tag "$UPDATER_IMAGE:latest" "$UPDATER_IMAGE:$VERSION" + docker push "$UPDATER_IMAGE:$VERSION" + docker tag "$UPDATER_IMAGE:latest" "$UPDATER_IMAGE_MIRROR:$VERSION" + docker push "$UPDATER_IMAGE_MIRROR:$VERSION" + push-development-image: + name: Push dependabot-core-development image to GHCR + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + needs: push-core-image + env: + DEV_IMAGE: ghcr.io/dependabot/dependabot-core-development + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Build dependabot-core image + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "$DEV_IMAGE:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from "$BASE_IMAGE" \ + --cache-from "$CORE_IMAGE:latest" \ + --cache-from "$DEV_IMAGE:latest" \ + -f Dockerfile.development . + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Push latest image + run: | + docker push "$DEV_IMAGE:latest" + - name: Push tagged image + if: contains(github.ref, 'refs/tags') + run: | + VERSION="$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" common/lib/dependabot/version.rb)" + docker tag "$DEV_IMAGE:latest" "$DEV_IMAGE:$VERSION" + docker push "$DEV_IMAGE:$VERSION" diff --git a/.github/workflows/gems.yml b/.github/workflows/gems.yml new file mode 100644 index 00000000000..fbd16426235 --- /dev/null +++ b/.github/workflows/gems.yml @@ -0,0 +1,21 @@ +name: Release gems +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+ +permissions: + contents: read +jobs: + release-gems: + name: Release gems to rubygems.org + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + - run: | + [ -d ~/.gem ] || mkdir ~/.gem + echo "---" > ~/.gem/credentials + echo ":rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}" > ~/.gem/credentials + chmod 0600 ~/.gem/credentials + gem install rake && rake gems:release diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml new file mode 100644 index 00000000000..c8524914da2 --- /dev/null +++ b/.github/workflows/smoke.yml @@ -0,0 +1,238 @@ +# Runs all ecosystems cached and concurrently. +name: Smoke + +on: + workflow_dispatch: + push: + branches: [ "main" ] + pull_request: + paths-ignore: + - docs/** + - README.md +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} +jobs: + e2e: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + suite: + - actions + - bundler + - cargo + - composer + - docker + - elm + - go + - gradle + - hex + - maven + - npm + - npm-remove-transitive + - nuget + - pip + - pip-compile + - pipenv + - poetry + - pub + - submodules + - terraform + - yarn-berry + steps: + - uses: actions/checkout@v3 + - uses: dorny/paths-filter@v2 + if: github.event_name != 'workflow_dispatch' + id: changes + with: + filters: | + actions: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'github_actions/**' + bundler: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'bundler/**' + cargo: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'cargo/**' + composer: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'composer/**' + docker: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'docker/**' + elm: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'elm/**' + go: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'go_modules/**' + gradle: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'maven/**' + - 'gradle/**' + hex: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'hex/**' + maven: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'maven/**' + npm: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'npm_and_yarn/**' + 'npm-remove-transitive': + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'npm_and_yarn/**' + nuget: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'nuget/**' + pub: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'pub/**' + pip: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'python/**' + 'pip-compile': + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'python/**' + pipenv: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'python/**' + poetry: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'python/**' + submodules: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'git_submodules/**' + terraform: + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'terraform/**' + 'yarn-berry': + - Dockerfile + - Dockerfile.updater + - 'common/**' + - 'updater/**' + - 'npm_and_yarn/**' + + - name: Download CLI and test + if: steps.changes.outputs[matrix.suite] == 'true' + run: | + gh release download --repo dependabot/cli -p "*linux-amd64.tar.gz" + tar xzvf *.tar.gz >/dev/null 2>&1 + ./dependabot --version + URL=https://api.github.com/repos/dependabot/smoke-tests/contents/tests/smoke-${{ matrix.suite }}.yaml + curl $(gh api $URL --jq .download_url) -o smoke.yaml + + # Download the Proxy cache. The job is ideally 100% cached so no real calls are made. + - name: Download cache + if: steps.changes.outputs[matrix.suite] == 'true' + run: | + mkdir cache + cd cache + gh run download --repo dependabot/smoke-tests --name cache-${{ matrix.suite }} + + - name: Build dependabot-core image + if: steps.changes.outputs[matrix.suite] == 'true' + env: + DOCKER_BUILDKIT: 1 + run: | + docker build \ + -t "dependabot/dependabot-core:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + . + - name: Build dependabot-updater image + if: steps.changes.outputs[matrix.suite] == 'true' + env: + DOCKER_BUILDKIT: 1 + OMNIBUS_VERSION: latest + run: | + docker build \ + -t "dependabot/updater:latest" \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --cache-from ghcr.io/dependabot/dependabot-core \ + --cache-from ghcr.io/dependabot/dependabot-updater/dependabot-updater \ + --build-arg OMNIBUS_VERSION=$OMNIBUS_VERSION \ + -f Dockerfile.updater \ + . + + - name: ${{ matrix.suite }} + if: steps.changes.outputs[matrix.suite] == 'true' + env: + LOCAL_GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -o pipefail + ./dependabot test -f=smoke.yaml -o=result.yaml --cache=cache --timeout=20m --updater-image=dependabot/updater:latest 2>&1 | tee -a log.txt + + - name: Diff + if: always() + continue-on-error: true + run: diff --ignore-space-change smoke.yaml result.yaml && echo "Contents are identical" + + - name: Create summary + if: steps.changes.outputs[matrix.suite] == 'true' + run: tail -n100 log.txt | grep -P '\d+/\d+ calls cached \(\d+%\)' >> $GITHUB_STEP_SUMMARY + + # No upload at the end: + # - If a test is uncachable in some regard, the cache would grow unbound. + # - We might want to consider erroring if the cache is changed. diff --git a/.gitignore b/.gitignore index 56887e6d483..4a2eeedb4c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,32 @@ /.bundle/ /node_modules /.env +/.envrc /tmp /pkg /dependabot-*.gem +!bundler/spec/fixtures/projects/**/Gemfile.lock Gemfile.lock +!updater/spec/fixtures/**/Gemfile.lock +!updater/Gemfile.lock vendor +!bundler/spec/fixtures/vendored_gems/vendor +!common/spec/fixtures/projects/**/*/vendor +!go_modules/spec/fixtures/projects/**/* .DS_Store *.pyc *git.store /.vscode/ /.vscode-server/ /.vscode-server-insiders/ -.byebug_history -/terraform/helpers/install-dir -/go_modules/helpers/install-dir +**/helpers/install-dir /npm_and_yarn/helpers/node_modules -/npm_and_yarn/helpers/install-dir +/npm_and_yarn/helpers/.node-version /dry-run **/bin/helper -/.core-bash_history \ No newline at end of file +/.core-bash_history +coverage/ +.ruby-gemset +.tool-versions +.rspec_status +.rdbg_history diff --git a/.rubocop.yml b/.rubocop.yml index 0b55c74e55f..ddce1fafec7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,131 +1,333 @@ +--- +require: rubocop-performance + AllCops: DisplayCopNames: true - TargetRubyVersion: 2.5 Exclude: - - '*/vendor/**/*' - - '*/bin/**/*' - - '*/tmp/**/*' - - 'tmp/**/*' - - '*/helpers/**/*' - + - "*/vendor/**/*" + - "*/bin/**/*" + - "**/tmp/**/*" + - "*/spec/fixtures/**/*" + - "dry-run/**/*" + NewCops: enable + SuggestExtensions: false +Gemspec/DeprecatedAttributeAssignment: + Enabled: true +Gemspec/RequireMFA: + Enabled: false Layout/DotPosition: EnforcedStyle: trailing - Layout/EmptyLinesAroundAttributeAccessor: Enabled: false - +Layout/FirstArrayElementIndentation: + EnforcedStyle: consistent +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent Layout/LineLength: - Max: 80 - + Max: 120 Layout/RescueEnsureAlignment: Enabled: false - Layout/SpaceAroundMethodCallOperator: Enabled: false - +Layout/SpaceBeforeBrackets: + Enabled: true +Layout/LineContinuationLeadingSpace: + Enabled: false +Lint/AmbiguousAssignment: + Enabled: true +Lint/BinaryOperatorWithIdenticalOperands: + Enabled: true +Lint/DeprecatedConstants: + Enabled: true Lint/DeprecatedOpenSSLConstant: Enabled: false - +Lint/DuplicateBranch: + Enabled: false +Lint/DuplicateElsifCondition: + Enabled: false +Lint/DuplicateRegexpCharacterClassElement: + Enabled: true +Lint/DuplicateRequire: + Enabled: true +Lint/DuplicateRescueException: + Enabled: true +Lint/EmptyBlock: + Enabled: true +Lint/EmptyClass: + Enabled: true +Lint/EmptyConditionalBody: + Enabled: true +Lint/EmptyFile: + Enabled: true +Lint/EmptyInPattern: + Enabled: true +Lint/FloatComparison: + Enabled: true +Lint/LambdaWithoutLiteralBlock: + Enabled: true +Lint/MissingSuper: + Enabled: false Lint/MixedRegexpCaptureTypes: Enabled: false - +Lint/NoReturnInBeginEndBlocks: + Enabled: false +Lint/NumberedParameterAssignment: + Enabled: true +Lint/OrAssignmentToConstant: + Enabled: true +Lint/OutOfRangeRegexpRef: + Enabled: true Lint/RaiseException: Enabled: false - +Lint/RedundantDirGlobSort: + Enabled: true +Lint/SelfAssignment: + Enabled: true Lint/StructNewOverride: Enabled: false - +Lint/SymbolConversion: + Enabled: true +Lint/ToEnumArguments: + Enabled: true +Lint/TopLevelReturnWithArgument: + Enabled: true +Lint/TrailingCommaInAttributeDeclaration: + Enabled: true +Lint/TripleQuotes: + Enabled: true +Lint/UnexpectedBlockArity: + Enabled: true +Lint/UnmodifiedReduceAccumulator: + Enabled: true +Lint/UnreachableLoop: + Enabled: true +Lint/UselessMethodDefinition: + Enabled: true +Metrics/AbcSize: + Max: 35 +Metrics/BlockLength: + Exclude: + - "*/Rakefile" + - "**/spec/**/*" + - "*/dependabot-*.gemspec" + Max: 35 Metrics/ClassLength: Max: 350 - -Metrics/ModuleLength: - Max: 350 - Metrics/CyclomaticComplexity: Max: 15 - -Metrics/AbcSize: - Max: 35 - Metrics/MethodLength: Max: 35 - -Metrics/BlockLength: - Max: 35 - Exclude: - - '*/Rakefile' - - '*/spec/**/*' - - '*/dependabot-*.gemspec' - +Metrics/ModuleLength: + Max: 350 Metrics/ParameterLists: CountKeywordArgs: false - +Metrics/PerceivedComplexity: + Max: 10 Naming/FileName: Enabled: false - -Style/StringLiterals: - EnforcedStyle: double_quotes - -Style/SignalException: - EnforcedStyle: only_raise - +Performance/AncestorsInclude: + Enabled: true +Performance/BigDecimalWithNumericArgument: + Enabled: true +Performance/BindCall: + Enabled: true +Performance/BlockGivenWithExplicitBlock: + Enabled: true +Performance/Caller: + Enabled: true +Performance/CaseWhenSplat: + Enabled: true +Performance/Casecmp: + Enabled: true +Performance/ChainArrayAllocation: + Enabled: false +Performance/CollectionLiteralInLoop: + Enabled: true +Performance/CompareWithBlock: + Enabled: true +Performance/ConcurrentMonotonicTime: + Enabled: true +Performance/ConstantRegexp: + Enabled: true +Performance/Count: + Enabled: true +Performance/DeletePrefix: + Enabled: true +Performance/DeleteSuffix: + Enabled: true +Performance/Detect: + Enabled: true +Performance/DoubleStartEndWith: + Enabled: true +Performance/EndWith: + Enabled: true +Performance/FixedSize: + Enabled: true +Performance/FlatMap: + Enabled: true +Performance/InefficientHashSearch: + Enabled: true +Performance/IoReadlines: + Enabled: true +Performance/MapCompact: + Enabled: true +Performance/MethodObjectAsBlock: + Enabled: true +Performance/OpenStruct: + Enabled: false +Performance/RangeInclude: + Enabled: true +Performance/RedundantBlockCall: + Enabled: true +Performance/RedundantEqualityComparisonBlock: + Enabled: true +Performance/RedundantMatch: + Enabled: true +Performance/RedundantMerge: + Enabled: true +Performance/RedundantSortBlock: + Enabled: true +Performance/RedundantSplitRegexpArgument: + Enabled: true +Performance/RedundantStringChars: + Enabled: true +Performance/RegexpMatch: + Enabled: true +Performance/ReverseEach: + Enabled: true +Performance/ReverseFirst: + Enabled: true +Performance/SelectMap: + Enabled: false +Performance/Size: + Enabled: true +Performance/SortReverse: + Enabled: true +Performance/Squeeze: + Enabled: true +Performance/StartWith: + Enabled: true +Performance/StringIdentifierArgument: + Enabled: true +Performance/StringInclude: + Enabled: true +Performance/StringReplacement: + Enabled: true +Performance/Sum: + Enabled: true +Performance/TimesMap: + Enabled: true +Performance/UnfreezeString: + Enabled: true +Performance/UriDefaultParser: + Enabled: true +Style/AccessorGrouping: + Enabled: false +Style/ArgumentsForwarding: + Enabled: true +Style/ArrayCoercion: + Enabled: false +Style/BisectedAttrAccessor: + Enabled: false +Style/CaseLikeIf: + Enabled: false +Style/CollectionCompact: + Enabled: true +Style/CombinableLoops: + Enabled: true +Style/DocumentDynamicEvalDefinition: + Enabled: true Style/Documentation: Enabled: false - +Style/EndlessMethod: + Enabled: true +Style/ExplicitBlockArgument: + Enabled: true +Style/ExponentialNotation: + Enabled: false +Style/GlobalStdStream: + Enabled: true +Style/HashAsLastArrayItem: + Enabled: false +Style/HashConversion: + Enabled: true Style/HashEachMethods: Enabled: false - +Style/HashExcept: + Enabled: true +Style/HashLikeCase: + Enabled: false +Style/HashSyntax: + EnforcedShorthandSyntax: either Style/HashTransformKeys: Enabled: false - Style/HashTransformValues: Enabled: false - -Style/PercentLiteralDelimiters: - PreferredDelimiters: - '%i': () - '%I': () - '%w': () - '%W': () - -Style/ExponentialNotation: +Style/IfWithBooleanLiteralBranches: + Enabled: true +Style/InPatternThen: + Enabled: true +Style/KeywordParametersOrder: Enabled: false - -Style/RedundantRegexpCharacterClass: +Style/MultilineInPatternThen: + Enabled: true +Style/MultipleComparison: Enabled: false - -Style/RedundantRegexpEscape: +Style/NegatedIfElseCondition: + Enabled: true +Style/NilLambda: + Enabled: true +Style/OptionalBooleanParameter: Enabled: false - -Style/SlicingWithRange: +Style/PercentLiteralDelimiters: + PreferredDelimiters: + "%I": "()" + "%W": "()" + "%i": "()" + "%w": "()" +Style/QuotedSymbols: + Enabled: true +Style/RedundantArgument: + Enabled: true +Style/RedundantAssignment: Enabled: false - Style/RedundantFetchBlock: Enabled: false - -Lint/DuplicateElsifCondition: +Style/RedundantFileExtensionInRequire: Enabled: false - -Style/AccessorGrouping: +Style/RedundantRegexpCharacterClass: Enabled: false - -Style/ArrayCoercion: +Style/RedundantRegexpEscape: Enabled: false - -Style/BisectedAttrAccessor: +Style/RedundantSelfAssignment: + Enabled: true +Style/SignalException: + EnforcedStyle: only_raise +Style/SingleArgumentDig: + Enabled: true +Style/SlicingWithRange: Enabled: false - -Style/CaseLikeIf: +Style/SoleNestedConditional: + Enabled: true +Style/StringChars: + Enabled: true +Style/StringConcatenation: Enabled: false - -Style/HashAsLastArrayItem: +Style/StringLiterals: + EnforcedStyle: double_quotes +Style/SwapValues: + Enabled: true +Style/OpenStructUse: Enabled: false - -Style/HashLikeCase: +Style/SpecialGlobalVars: Enabled: false - -Style/RedundantAssignment: +Style/SelectByRegexp: Enabled: false -Style/RedundantFileExtensionInRequire: +# TODO these were temporarily disabled during the Ruby 2.7 -> 3.1 upgrade +# in order to keep the upgrade diff small, they will be enabled/fixed in +# a follow-on PR. +Naming/BlockForwarding: + Enabled: false +Style/MutableConstant: Enabled: false diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000000..ef538c28109 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.1.2 diff --git a/.vscode/launch.json b/.vscode/launch.json index 6e187c5c7ef..46518252be8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,6 +15,63 @@ "${input:package_manager}", "${input:repository}" ] + }, + { + "name": "Debug Tests", + "type": "Ruby", + "request": "launch", + "program": "${workspaceRoot}/omnibus/.bundle/bin/rspec", + "cwd": "${workspaceRoot}/${input:ecosystem}", + "useBundler": true, + "args": ["${input:test_path}"], + }, + { + "type": "node", + "name": "vscode-jest-tests", + "request": "launch", + "program": "${workspaceFolder}/npm_and_yarn/helpers/node_modules/jest/bin/jest.js", + "args": [ + "--runInBand", + "-c", + "${workspaceFolder}/npm_and_yarn/helpers/jest.config.js" + ], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true + }, + { + "type": "node", + "name": "Run jest tests (watch)", + "request": "launch", + "program": "${workspaceFolder}/npm_and_yarn/helpers/node_modules/jest/bin/jest.js", + "args": [ + "--runInBand", + "--watchAll", + "-c", + "${workspaceFolder}/npm_and_yarn/helpers/jest.config.js" + ], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true + }, + { + "type": "node", + "name": "Run jest tests on opened file (watch)", + "request": "launch", + "program": "${workspaceFolder}/npm_and_yarn/helpers/node_modules/jest/bin/jest.js", + "args": [ + "${fileBasenameNoExtension}", + "--runInBand", + "--watchAll", + "-c", + "${workspaceFolder}/npm_and_yarn/helpers/jest.config.js" + ], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true } ], "inputs": [ @@ -29,6 +86,7 @@ "dep", "docker", "elm", + "github_actions", "go_modules", "gradle", "hex", @@ -41,6 +99,35 @@ ], "default": "go_modules" }, + { + "type": "pickString", + "id": "ecosystem", + "description": "What type of ecosystem tests do you want to debug?", + "options": [ + "bundler", + "cargo", + "common", + "composer", + "docker", + "elm", + "github_actions", + "go_modules", + "gradle", + "hex", + "maven", + "npm_and_yarn", + "nuget", + "python", + "terraform" + ], + "default": "python" + }, + { + "type": "promptString", + "id": "test_path", + "description": "Enter the path of the test(s) to run.", + "default": "spec" + }, { "type": "promptString", "id": "repository", diff --git a/.vscode/settings.json b/.vscode/settings.json index 09ddca91a6c..64417dc09aa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "files.associations": { "Dockerfile.*": "dockerfile" - } + }, + "jest.pathToJest": "${workspaceFolder}/npm_and_yarn/helpers/node_modules/.bin/jest", + "jest.pathToConfig": "${workspaceFolder}/npm_and_yarn/helpers/jest.config.js" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c1925837740..c6e36af4988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,2313 @@ +## v0.215.0, 7 December 2022 + +- Improve SubprocessFailed Sentry errors [#6276](https://github.com/dependabot/dependabot-core/pull/6276) +- More error aggregation [#6274](https://github.com/dependabot/dependabot-core/pull/6274) +- Aggregate more subcommand failed errors [#6273](https://github.com/dependabot/dependabot-core/pull/6273) +- Improve subprocess failed error aggregation [#6272](https://github.com/dependabot/dependabot-core/pull/6272) +- Pass `raven_context` to Sentry on failed subprocess exceptions [#6268](https://github.com/dependabot/dependabot-core/pull/6268) +- Rescue socket errors for poetry library detection [#6271](https://github.com/dependabot/dependabot-core/pull/6271) +- No need to install RubyGems explicitly [#6267](https://github.com/dependabot/dependabot-core/pull/6267) +- build(deps): bump terraform from 1.3.5 to 1.3.6 (@HorizonNet) [#6246](https://github.com/dependabot/dependabot-core/pull/6246) +- Yarn Berry: Offline cache updates [#6242](https://github.com/dependabot/dependabot-core/pull/6242) +- Don't use compare URLs for deciding GitHub Actions upgrades [#6240](https://github.com/dependabot/dependabot-core/pull/6240) +- Fix some branches getting in the middle of upgrading actions pinned to SHAs [#6239](https://github.com/dependabot/dependabot-core/pull/6239) + +## v0.214.0, 30 November 2022 + +- Yarn Berry: Make a best effort to preserve file permissions (@pavera) [#6141](https://github.com/dependabot/dependabot-core/pull/6141) +- Check if existing python requirement is satisfied before modifying (@pavera) [#6237](https://github.com/dependabot/dependabot-core/pull/6237) +- Prevent `NoMethodError` when captures are missing (@landongrindheim) [#6227](https://github.com/dependabot/dependabot-core/pull/6227) +- Respect existing precision of base docker images (@deivid-rodriguez) [#6170](https://github.com/dependabot/dependabot-core/pull/6170) +- test: add test for private registry module with dir suffix (@stigok) [#6137](https://github.com/dependabot/dependabot-core/pull/6137) +- Improve Bundler configuration (@deivid-rodriguez) [#6069](https://github.com/dependabot/dependabot-core/pull/6069) +- Fix dependabot not updating gemspec dependencies loaded dynamically from other gemspecs (@deivid-rodriguez) [#6188](https://github.com/dependabot/dependabot-core/pull/6188) +- Use git to fill in gemspec files (@deivid-rodriguez) [#6199](https://github.com/dependabot/dependabot-core/pull/6199) +- Remove hardcoded master branch (@deivid-rodriguez) [#6149](https://github.com/dependabot/dependabot-core/pull/6149) +- Honor new dir selection logic in Github Actions error messages (@deivid-rodriguez) [#6192](https://github.com/dependabot/dependabot-core/pull/6192) +- Mention BitBucket is supported by dependabot-script (@jeffwidman) [#6198](https://github.com/dependabot/dependabot-core/pull/6198) +- Use only python major.minor version (@pavera) [#6195](https://github.com/dependabot/dependabot-core/pull/6195) +- Fix inconsistent docker updates with `-` suffixed images (@deivid-rodriguez) [#6173](https://github.com/dependabot/dependabot-core/pull/6173) +- Bump minimatch from 3.0.4 to 3.1.2 in /npm_and_yarn/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested [#6162](https://github.com/dependabot/dependabot-core/pull/6162) +- Add a spec to cover custom dir given to actions (@deivid-rodriguez) [#6190](https://github.com/dependabot/dependabot-core/pull/6190) +- Respect custom directory for actions updates (@deivid-rodriguez) [#6189](https://github.com/dependabot/dependabot-core/pull/6189) +- Allow cargo versions with hypens in build identifiers (@deivid-rodriguez) [#6183](https://github.com/dependabot/dependabot-core/pull/6183) +- Add security update support for Github Actions (@deivid-rodriguez) [#6071](https://github.com/dependabot/dependabot-core/pull/6071) +- Refactor some common logic across ecosystems (@deivid-rodriguez) [#6164](https://github.com/dependabot/dependabot-core/pull/6164) +- Use pre-built python as much as possible. (@pavera) [#6079](https://github.com/dependabot/dependabot-core/pull/6079) +- Yarn Berry: Use -R for yarn up (@pavera) [#6167](https://github.com/dependabot/dependabot-core/pull/6167) +- Yarn Berry: Adding a peer dependency checker (@pavera) [#6077](https://github.com/dependabot/dependabot-core/pull/6077) +- Add missing Python versions (@ulgens) [#6089](https://github.com/dependabot/dependabot-core/pull/6089) +- Bump loader-utils from 1.4.1 to 1.4.2 in /npm_and_yarn/helpers [#6156](https://github.com/dependabot/dependabot-core/pull/6156) +- Create a permanent root Gemfile (@deivid-rodriguez) [#6159](https://github.com/dependabot/dependabot-core/pull/6159) +- Adding yarn berry smoke test (@pavera) [#6154](https://github.com/dependabot/dependabot-core/pull/6154) +- Fix updating GitHub actions to major tags that are branches (@deivid-rodriguez) [#5963](https://github.com/dependabot/dependabot-core/pull/5963) +- Private hex repo support (@sorentwo) [#5043](https://github.com/dependabot/dependabot-core/pull/5043) +- Make specs time zone independent (@deivid-rodriguez) [#6135](https://github.com/dependabot/dependabot-core/pull/6135) +- Consider precision when finding latest action (@deivid-rodriguez) [#6102](https://github.com/dependabot/dependabot-core/pull/6102) +- Remove `faraday-retry` warning (@deivid-rodriguez) [#6114](https://github.com/dependabot/dependabot-core/pull/6114) +- Fix spaces in uri (@AlekhyaYalla) [#5656](https://github.com/dependabot/dependabot-core/pull/5656) +- Fix multiple constraint Poetry dependencies getting bad updates (@deivid-rodriguez) [#6074](https://github.com/dependabot/dependabot-core/pull/6074) +- Don't leak pipenv warnings into manifest files (@deivid-rodriguez) [#6103](https://github.com/dependabot/dependabot-core/pull/6103) +- Fix GitHub actions updater crashing and cloning the wrong repository (@deivid-rodriguez) [#6052](https://github.com/dependabot/dependabot-core/pull/6052) +- Update SECURITY.md (@maclarel) [#6093](https://github.com/dependabot/dependabot-core/pull/6093) +- Bump friendsofphp/php-cs-fixer from 3.12.0 to 3.13.0 in /composer/helpers/v2 [#6063](https://github.com/dependabot/dependabot-core/pull/6063) +- Bump eslint from 8.26.0 to 8.27.0 in /npm_and_yarn/helpers [#6061](https://github.com/dependabot/dependabot-core/pull/6061) +- Bump phpstan/phpstan from 1.8.11 to 1.9.1 in /composer/helpers/v2 [#6062](https://github.com/dependabot/dependabot-core/pull/6062) +- Bump phpstan/phpstan from 1.8.11 to 1.9.1 in /composer/helpers/v1 [#6064](https://github.com/dependabot/dependabot-core/pull/6064) +- Update parallel_tests requirement from ~> 3.13.0 to ~> 4.0.0 in /common [#6059](https://github.com/dependabot/dependabot-core/pull/6059) +- Yarn Berry: Subdependency fixes (@pavera) [#6040](https://github.com/dependabot/dependabot-core/pull/6040) +- Don't fail if dependency with unknown vcs has local replacement (@zioyero) [#5983](https://github.com/dependabot/dependabot-core/pull/5983) +- Upgrade Bundler to 2.3.25 (@Bo98) [#6042](https://github.com/dependabot/dependabot-core/pull/6042) +- nuget: keep version build identifiers out of manifests (@jakecoffman) [#6034](https://github.com/dependabot/dependabot-core/pull/6034) +- Fix some PEP 621 projects not getting upgrades (@deivid-rodriguez) [#6032](https://github.com/dependabot/dependabot-core/pull/6032) +- Fix accidental downgrades in Bundler PRs (@deivid-rodriguez) [#6030](https://github.com/dependabot/dependabot-core/pull/6030) +- Yarn Berry: Use appropriate mode for yarn version and repo state (@pavera) [#6017](https://github.com/dependabot/dependabot-core/pull/6017) +- Removes `YarnLockfileParser` (@bdragon) [#6016](https://github.com/dependabot/dependabot-core/pull/6016) +- Yarn Private Registry Support (@Nishnha) [#5883](https://github.com/dependabot/dependabot-core/pull/5883) +- Yarn Berry: run git lfs pull before running yarn (@jtbandes) [#5833](https://github.com/dependabot/dependabot-core/pull/5833) +- fix hex native helpers: v2.0.0 removed Hex.Version.InvalidRequirementError (@jakecoffman) [#6006](https://github.com/dependabot/dependabot-core/pull/6006) + +## v0.213.0, 31 October 2022 + +- prevent failing to create a PR due to metadata gathering errors [#5980](https://github.com/dependabot/dependabot-core/pull/5980) +- Bump Node.js in bug report description field (@HonkingGoose) [#5984](https://github.com/dependabot/dependabot-core/pull/5984) +- Allow file fetchers to opt into loading git submodules [#5982](https://github.com/dependabot/dependabot-core/pull/5982) +- Centralize pyenv install logic [#5985](https://github.com/dependabot/dependabot-core/pull/5985) +- prevent trying to get a commit that can't exist [#5981](https://github.com/dependabot/dependabot-core/pull/5981) +- Remove Current User From List of Default Reviewer (@Kimor-hello) [#5968](https://github.com/dependabot/dependabot-core/pull/5968) +- Bump @npmcli/arborist from 5.6.2 to 6.0.0 in /npm_and_yarn/helpers [#5955](https://github.com/dependabot/dependabot-core/pull/5955) +- Update rubocop requirement from ~> 1.36.0 to ~> 1.37.1 in /common [#5959](https://github.com/dependabot/dependabot-core/pull/5959) +- Regenerate `updater/Gemfile.lock` [#5858](https://github.com/dependabot/dependabot-core/pull/5858) +- Keep updater lockfile in sync with subgem changes [#5972](https://github.com/dependabot/dependabot-core/pull/5972) +- Add Dependency Review workflow [#5973](https://github.com/dependabot/dependabot-core/pull/5973) +- Yarn Berry: Fully update cache and include .pnp.cjs in PR [#5964](https://github.com/dependabot/dependabot-core/pull/5964) +- Actually consider development dependencies (v2) [#5971](https://github.com/dependabot/dependabot-core/pull/5971) +- Actually consider development dependencies [#5969](https://github.com/dependabot/dependabot-core/pull/5969) +- Fix crashes on Python libraries using multiple manifests [#5965](https://github.com/dependabot/dependabot-core/pull/5965) +- Fix rubocop redundant freeze warnings [#5468](https://github.com/dependabot/dependabot-core/pull/5468) +- Don't repeat dependency names in PR title [#5915](https://github.com/dependabot/dependabot-core/pull/5915) +- fix race and updating local mounted repositories [#5937](https://github.com/dependabot/dependabot-core/pull/5937) +- Initial work on standard Python support [#5661](https://github.com/dependabot/dependabot-core/pull/5661) +- Only call pip compile once (@jerbob92) [#5905](https://github.com/dependabot/dependabot-core/pull/5905) +- Bump rubocop from 1.36.0 to 1.37.1 in /updater [#5960](https://github.com/dependabot/dependabot-core/pull/5960) +- Bump licensed from 3.7.4 to 3.7.5 in /updater [#5957](https://github.com/dependabot/dependabot-core/pull/5957) +- Update octokit requirement from >= 4.6, < 6.0 to >= 4.6, < 7.0 in /common [#5954](https://github.com/dependabot/dependabot-core/pull/5954) +- Make dry-run script twice as fast [#5950](https://github.com/dependabot/dependabot-core/pull/5950) +- Bump collection from 1.16.0 to 1.17.0 in /pub/helpers [#5898](https://github.com/dependabot/dependabot-core/pull/5898) +- Bump eslint from 8.25.0 to 8.26.0 in /npm_and_yarn/helpers [#5953](https://github.com/dependabot/dependabot-core/pull/5953) +- Update pip requirement from <22.2.3,>=21.3.1 to >=21.3.1,<22.4.0 in /python/helpers [#5893](https://github.com/dependabot/dependabot-core/pull/5893) +- build(deps): bump terraform from 1.3.2 to 1.3.3 (@HorizonNet) [#5952](https://github.com/dependabot/dependabot-core/pull/5952) +- No public url call when public registry is disabled [#5948](https://github.com/dependabot/dependabot-core/pull/5948) +- fix calling npm.org when there's no npmrc with replaces-base [#5928](https://github.com/dependabot/dependabot-core/pull/5928) +- Never change version precision of actions chosen by users [#5891](https://github.com/dependabot/dependabot-core/pull/5891) +- Bump nokogiri from 1.13.8 to 1.13.9 in /updater [#5936](https://github.com/dependabot/dependabot-core/pull/5936) +- Fix crash when updating git dependencies [#5934](https://github.com/dependabot/dependabot-core/pull/5934) +- Fix error when parsing Gitlab changelogs [#5929](https://github.com/dependabot/dependabot-core/pull/5929) +- Fix crash when updating Python libraries with multiple manifest types [#5932](https://github.com/dependabot/dependabot-core/pull/5932) +- Fix updating to tags with a branch with same name [#5918](https://github.com/dependabot/dependabot-core/pull/5918) +- Batch some PRs updating dependencies [#5942](https://github.com/dependabot/dependabot-core/pull/5942) +- Maven: fix forgetting repositories seen in earlier POMs [#5931](https://github.com/dependabot/dependabot-core/pull/5931) +- Yarn Berry: Fixes subdependency security updates [#5930](https://github.com/dependabot/dependabot-core/pull/5930) +- Bump phpstan/phpstan from 1.8.8 to 1.8.10 in /composer/helpers/v1 [#5910](https://github.com/dependabot/dependabot-core/pull/5910) +- Bump friendsofphp/php-cs-fixer from 3.11.0 to 3.12.0 in /composer/helpers/v2 [#5895](https://github.com/dependabot/dependabot-core/pull/5895) +- Install composer in a way that does not use `COPY --from` [#5904](https://github.com/dependabot/dependabot-core/pull/5904) +- Fall back to PR title if original PR head commit is missing [#5913](https://github.com/dependabot/dependabot-core/pull/5913) +- Maven: implement parent snapshot lookup [#5924](https://github.com/dependabot/dependabot-core/pull/5924) +- Fixed disabledPackageSources for nuget.org [#5874](https://github.com/dependabot/dependabot-core/pull/5874) +- maven: implement replaces-base to avoid calling central [#5908](https://github.com/dependabot/dependabot-core/pull/5908) +- Fix commitlint message style detection [#5744](https://github.com/dependabot/dependabot-core/pull/5744) +- Fixing PR failures if pypi.org unavailable [#5876](https://github.com/dependabot/dependabot-core/pull/5876) +- Fix dependabot incorrectly downgrading docker versions [#5886](https://github.com/dependabot/dependabot-core/pull/5886) +- fix version_finder not preferring private registry [#5907](https://github.com/dependabot/dependabot-core/pull/5907) +- Remove CI hack much less needed now [#5906](https://github.com/dependabot/dependabot-core/pull/5906) +- add Maven credential metadata to the URLs it searches for POM files [#5884](https://github.com/dependabot/dependabot-core/pull/5884) +- Revert lockfile-only changes [#5901](https://github.com/dependabot/dependabot-core/pull/5901) +- Detect dependencies in Gradle included builds (@gabrielfeo) [#5028](https://github.com/dependabot/dependabot-core/pull/5028) +- Make `script/dependabot --help` actually work [#5881](https://github.com/dependabot/dependabot-core/pull/5881) +- Fix `lockfile-only` versioning strategy not creating some updates that are expected [#5581](https://github.com/dependabot/dependabot-core/pull/5581) +- Fix Maven inability to overwrite repository urls by ID [#5878](https://github.com/dependabot/dependabot-core/pull/5878) +- Revert "Bump activesupport from 6.1.4.4 to 7.0.4 in /updater" [#5882](https://github.com/dependabot/dependabot-core/pull/5882) +- Bump activesupport from 6.1.4.4 to 7.0.4 in /updater [#5704](https://github.com/dependabot/dependabot-core/pull/5704) +- [npm] Flag indirect transitive updates to be ignored by the FileUpdater [#5873](https://github.com/dependabot/dependabot-core/pull/5873) +- [npm] Randomize advisory id to avoid cache collisions across tests [#5875](https://github.com/dependabot/dependabot-core/pull/5875) +- maven: stop querying repositories once one returns a result [#5872](https://github.com/dependabot/dependabot-core/pull/5872) +- Yarn Berry: Ensure registry config is respected [#5863](https://github.com/dependabot/dependabot-core/pull/5863) +- raise when a path dependency is absolute [#5869](https://github.com/dependabot/dependabot-core/pull/5869) +- Update `.dockerignore` [#5585](https://github.com/dependabot/dependabot-core/pull/5585) +- Bump phpstan/phpstan from 1.8.6 to 1.8.8 in /composer/helpers/v2 [#5860](https://github.com/dependabot/dependabot-core/pull/5860) +- Make quotes around Yarn private registry sources optional [#5844](https://github.com/dependabot/dependabot-core/pull/5844) +- Fix typos [#5859](https://github.com/dependabot/dependabot-core/pull/5859) +- swap history file from `byebug` to new `debug` gem [#5855](https://github.com/dependabot/dependabot-core/pull/5855) +- [npm] fix to preserve all_versions metadata from the lockfile [#5846](https://github.com/dependabot/dependabot-core/pull/5846) +- handle path="" correctly in Cargo.toml [#5866](https://github.com/dependabot/dependabot-core/pull/5866) +- allow interactive debugging in the CLI [#5763](https://github.com/dependabot/dependabot-core/pull/5763) +- Update faraday requirement from = 2.5.2 to = 2.6.0 in /common [#5851](https://github.com/dependabot/dependabot-core/pull/5851) +- Add support for Python 3.10.7 and 3.[7-9].14 (@Kurt-von-Laven) [#5769](https://github.com/dependabot/dependabot-core/pull/5769) +- build(deps): bump terraform from 1.3.0 to 1.3.2 (@HorizonNet) [#5857](https://github.com/dependabot/dependabot-core/pull/5857) +- Update pip-tools requirement from <6.8.1,>=6.4.0 to >=6.4.0,<6.9.1 in /python/helpers [#5850](https://github.com/dependabot/dependabot-core/pull/5850) +- Bump http from 4.4.1 to 5.1.0 in /updater [#5701](https://github.com/dependabot/dependabot-core/pull/5701) +- Bump jest from 28.1.3 to 29.1.2 in /npm_and_yarn/helpers [#5821](https://github.com/dependabot/dependabot-core/pull/5821) +- Bump semver from 7.3.7 to 7.3.8 in /npm_and_yarn/helpers [#5848](https://github.com/dependabot/dependabot-core/pull/5848) +- Bump licensed from 3.7.3 to 3.7.4 in /updater [#5849](https://github.com/dependabot/dependabot-core/pull/5849) +- feat: Add support for `workspace.dependencies` in `cargo` 1.64.0+ (@poliorcetics) [#5794](https://github.com/dependabot/dependabot-core/pull/5794) +- Update debug requirement from ~> 1.0.0 to ~> 1.6.2 in /updater [#5853](https://github.com/dependabot/dependabot-core/pull/5853) +- Bump eslint from 8.24.0 to 8.25.0 in /npm_and_yarn/helpers [#5852](https://github.com/dependabot/dependabot-core/pull/5852) +- Bump phpstan/phpstan from 1.8.6 to 1.8.8 in /composer/helpers/v1 [#5854](https://github.com/dependabot/dependabot-core/pull/5854) +- Fix typo [#5847](https://github.com/dependabot/dependabot-core/pull/5847) +- Bump Ruby to 3.1 [#5447](https://github.com/dependabot/dependabot-core/pull/5447) +- [npm] Consider all installed versions when checking if a dependency is still vulnerable [#5801](https://github.com/dependabot/dependabot-core/pull/5801) +- use configured global registry for library lookup [#5840](https://github.com/dependabot/dependabot-core/pull/5840) +- allow updating at a commit, for testing [#5843](https://github.com/dependabot/dependabot-core/pull/5843) +- Fix Dependabot removes double backslashes in maven plugin configurations (@mallowlabs) [#5835](https://github.com/dependabot/dependabot-core/pull/5835) +- Stop disabling new `poetry` installer [#5838](https://github.com/dependabot/dependabot-core/pull/5838) +- Bump Rubygems to `3.3.22` [#5823](https://github.com/dependabot/dependabot-core/pull/5823) +- Yarn Berry: Private registry support [#5831](https://github.com/dependabot/dependabot-core/pull/5831) +- Consider all dependency versions in Job.vulnerable? [#5837](https://github.com/dependabot/dependabot-core/pull/5837) +- Yarn Berry: Ensure multiple requirements are parsed correctly [#5839](https://github.com/dependabot/dependabot-core/pull/5839) +- Add support for helm files. (@brendandburns) [#5738](https://github.com/dependabot/dependabot-core/pull/5738) +- Update `v1/composer.lock` using `composer1 update` [#5717](https://github.com/dependabot/dependabot-core/pull/5717) +- Decouple Bundler versions [#5513](https://github.com/dependabot/dependabot-core/pull/5513) +- Upgrade Bundler to 2.3.22 [#5509](https://github.com/dependabot/dependabot-core/pull/5509) +- Add support for Python 3.10.6 (@Kurt-von-Laven) [#5780](https://github.com/dependabot/dependabot-core/pull/5780) +- Yarn Berry: Prevent sub-package dependencies being added to root workspace [#5829](https://github.com/dependabot/dependabot-core/pull/5829) +- [npm] Preserve requirement source when updating transtive dep parents [#5816](https://github.com/dependabot/dependabot-core/pull/5816) +- [npm] Allow updates with both top level and sub dependencies [#5822](https://github.com/dependabot/dependabot-core/pull/5822) +- Yarn Berry: Run commands in `update-lockfile` mode [#5827](https://github.com/dependabot/dependabot-core/pull/5827) +- Update parallel_tests requirement from ~> 3.12.0 to ~> 3.13.0 in /common [#5791](https://github.com/dependabot/dependabot-core/pull/5791) +- [npm] Reject audits which don't have a fix we can apply [#5815](https://github.com/dependabot/dependabot-core/pull/5815) +- Update all versions of the same private module in single terraform file (@szemek) [#5786](https://github.com/dependabot/dependabot-core/pull/5786) +- Ensure always_clone is enabled for yarn_berry during file_fetching [#5817](https://github.com/dependabot/dependabot-core/pull/5817) +- Bump phpstan/phpstan from 1.8.5 to 1.8.6 in /composer/helpers/v2 [#5792](https://github.com/dependabot/dependabot-core/pull/5792) +- Bump phpstan/phpstan from 1.8.5 to 1.8.6 in /composer/helpers/v1 [#5793](https://github.com/dependabot/dependabot-core/pull/5793) +- Bump eslint from 8.23.1 to 8.24.0 in /npm_and_yarn/helpers [#5790](https://github.com/dependabot/dependabot-core/pull/5790) +- add dependabot CLI dev container [#5813](https://github.com/dependabot/dependabot-core/pull/5813) +- smoke test npm removed dependencies [#5808](https://github.com/dependabot/dependabot-core/pull/5808) +- Set custom CA file path for yarn berry [#5783](https://github.com/dependabot/dependabot-core/pull/5783) +- [npm] fix failure to attempt parent update if unfixed transitive update is available [#5799](https://github.com/dependabot/dependabot-core/pull/5799) +- Fix syntax error in Actions workflow file [#5805](https://github.com/dependabot/dependabot-core/pull/5805) +- Update smoke test to download CLI from `dependabot/cli` repo [#5803](https://github.com/dependabot/dependabot-core/pull/5803) +- Fix typo in README (promted -> prompted) (@szemek) [#5802](https://github.com/dependabot/dependabot-core/pull/5802) +- remove :npm_transitive_security_updates flag [#5788](https://github.com/dependabot/dependabot-core/pull/5788) +- [Gradle] Handle plugin version variables without string interpolation (@Flexicon) [#5381](https://github.com/dependabot/dependabot-core/pull/5381) +- [npm] Only shortcut search when non-vuln version of advisory dep is found [#5796](https://github.com/dependabot/dependabot-core/pull/5796) +- Terraform 1.3.0 [#5782](https://github.com/dependabot/dependabot-core/pull/5782) +- Skip cron run of CodeQL in forks [#5784](https://github.com/dependabot/dependabot-core/pull/5784) +- [npm] Only return a chain if a node matches a vulnerable version [#5785](https://github.com/dependabot/dependabot-core/pull/5785) +- bundler: optimize gemfile parsing (@skipkayhil) [#4059](https://github.com/dependabot/dependabot-core/pull/4059) +- Initial yarn berry support [#5660](https://github.com/dependabot/dependabot-core/pull/5660) +- Fixing issue with nuget devDependency support (@mwaddell) [#4774](https://github.com/dependabot/dependabot-core/pull/4774) +- Bump commonmarker from 0.23.5 to 0.23.6 in /updater [#5773](https://github.com/dependabot/dependabot-core/pull/5773) +- Bump @npmcli/arborist from 5.6.1 to 5.6.2 in /npm_and_yarn/helpers [#5747](https://github.com/dependabot/dependabot-core/pull/5747) +- Update poetry requirement from <=1.2.0,>=1.1.15 to >=1.1.15,<1.3.0 in /python/helpers [#5746](https://github.com/dependabot/dependabot-core/pull/5746) +- Improve PR message for removed dependencies [#5770](https://github.com/dependabot/dependabot-core/pull/5770) +- build(deps): bump NPM from 8.18.0 to 8.19.2 (@THETCR) [#5754](https://github.com/dependabot/dependabot-core/pull/5754) +- prevent forks from trying and failing to deploy to GHCR [#5768](https://github.com/dependabot/dependabot-core/pull/5768) +- Sanitize metadata links on all platforms [#5739](https://github.com/dependabot/dependabot-core/pull/5739) +- Fixes for transitive dependency vulnerabilities without a top level dependency update [#5762](https://github.com/dependabot/dependabot-core/pull/5762) +- Experiments not Experiment [#5760](https://github.com/dependabot/dependabot-core/pull/5760) +- More descriptive PR message when multiple dependencies are fixed in a security update [#5595](https://github.com/dependabot/dependabot-core/pull/5595) +- Add new interface to register experiments [#5755](https://github.com/dependabot/dependabot-core/pull/5755) +- [pub] Log the Dart / Flutter SDK version selected (@sigurdm) [#5748](https://github.com/dependabot/dependabot-core/pull/5748) +- Run CI and smoke tests on stacked PRs [#5752](https://github.com/dependabot/dependabot-core/pull/5752) +- Fix multiple Python requirements separated by whitespace [#5735](https://github.com/dependabot/dependabot-core/pull/5735) +- Allow updating Java images with "update releases" [#5734](https://github.com/dependabot/dependabot-core/pull/5734) +- Support `bump_versions_if_necessary` versioning strategy in python [#5605](https://github.com/dependabot/dependabot-core/pull/5605) +- Sanitize mentions for merge requests in Gitlab (@andrcuns) [#3437](https://github.com/dependabot/dependabot-core/pull/3437) +- add a date tag to the docker image when merged [#5736](https://github.com/dependabot/dependabot-core/pull/5736) +- Make `script/debug` a simple wrapper over the CLI [#5733](https://github.com/dependabot/dependabot-core/pull/5733) +- Use `"latest"` for ESLint `ecmaVersion` [#5715](https://github.com/dependabot/dependabot-core/pull/5715) +- Fix URIs logged by dry-run [#5732](https://github.com/dependabot/dependabot-core/pull/5732) +- Bump webmock from 3.17.1 to 3.18.1 in /updater [#5700](https://github.com/dependabot/dependabot-core/pull/5700) +- Add composer fields to silence PHPStan [#5716](https://github.com/dependabot/dependabot-core/pull/5716) +- Add max length option to BranchNamer (@TomNaessens) [#5338](https://github.com/dependabot/dependabot-core/pull/5338) +- Bump jason from 1.3.0 to 1.4.0 in /hex/helpers [#5699](https://github.com/dependabot/dependabot-core/pull/5699) +- Fix fetching bug for requirements.in files (@stulle123) [#5580](https://github.com/dependabot/dependabot-core/pull/5580) +- Relax the composer pin to make it less confusing [#5714](https://github.com/dependabot/dependabot-core/pull/5714) +- Fix `PHP-CS-Fixer` deprecation warnings [#5713](https://github.com/dependabot/dependabot-core/pull/5713) +- Revert "disable branch release workflow for forks" [#5711](https://github.com/dependabot/dependabot-core/pull/5711) +- disable branch release workflow for forks [#5709](https://github.com/dependabot/dependabot-core/pull/5709) +- Bump rubocop-performance from 1.14.3 to 1.15.0 in /updater [#5703](https://github.com/dependabot/dependabot-core/pull/5703) +- Bump rubocop from 1.33.0 to 1.36.0 in /updater [#5702](https://github.com/dependabot/dependabot-core/pull/5702) +- Rename `phpstan.neon` -> `phpstan.dist.neon` [#5692](https://github.com/dependabot/dependabot-core/pull/5692) +- Fix typo [#5696](https://github.com/dependabot/dependabot-core/pull/5696) +- Fix typo (@HonkingGoose) [#5705](https://github.com/dependabot/dependabot-core/pull/5705) +- Rename `.php_cs` -> `.php-cs-fixer.dist.php` [#5691](https://github.com/dependabot/dependabot-core/pull/5691) +- Watch the new `updater/Gemfile` [#5697](https://github.com/dependabot/dependabot-core/pull/5697) +- Handle removed dependencies in existing PRs [#5673](https://github.com/dependabot/dependabot-core/pull/5673) +- Bump friendsofphp/php-cs-fixer from 3.9.3 to 3.11.0 in /composer/helpers/v2 [#5689](https://github.com/dependabot/dependabot-core/pull/5689) +- build(deps-dev): bump phpstan/phpstan from 1.7.15 to 1.8.5 in /composer/helpers/v1 [#5651](https://github.com/dependabot/dependabot-core/pull/5651) +- build(deps-dev): bump phpstan/phpstan from 1.8.1 to 1.8.5 in /composer/helpers/v2 [#5652](https://github.com/dependabot/dependabot-core/pull/5652) +- Update debase-ruby_core_source requirement from = 0.10.16 to = 0.10.17 in /common [#5677](https://github.com/dependabot/dependabot-core/pull/5677) +- fix Poetry not using system git [#5688](https://github.com/dependabot/dependabot-core/pull/5688) +- build(deps): bump @npmcli/arborist from 5.6.0 to 5.6.1 in /npm_and_yarn/helpers [#5629](https://github.com/dependabot/dependabot-core/pull/5629) +- Increase docker registry client timeout [#5674](https://github.com/dependabot/dependabot-core/pull/5674) +- deploy from a fork using a workflow [#5668](https://github.com/dependabot/dependabot-core/pull/5668) +- Bump eslint from 8.22.0 to 8.23.1 in /npm_and_yarn/helpers [#5679](https://github.com/dependabot/dependabot-core/pull/5679) +- python/helpers/build: fix a pip warning related to pipfile installation (@SpecLad) [#5587](https://github.com/dependabot/dependabot-core/pull/5587) +- Update file size to 500 kilobytes (@stulle123) [#5596](https://github.com/dependabot/dependabot-core/pull/5596) +- build(deps): bump terraform from 1.2.8 to 1.2.9 (@HorizonNet) [#5675](https://github.com/dependabot/dependabot-core/pull/5675) +- Update rubocop-performance requirement from ~> 1.14.2 to ~> 1.15.0 in /common [#5680](https://github.com/dependabot/dependabot-core/pull/5680) +- Fix typo: spwans -> spawns [#5681](https://github.com/dependabot/dependabot-core/pull/5681) +- Reword comment & fix typo [#5682](https://github.com/dependabot/dependabot-core/pull/5682) +- Test #conficting_dependencies with a locking parent dependabot fixture [#5672](https://github.com/dependabot/dependabot-core/pull/5672) +- Include removed dependency flag when creating a pull request [#5671](https://github.com/dependabot/dependabot-core/pull/5671) +- Cleanup updater specs output [#5666](https://github.com/dependabot/dependabot-core/pull/5666) +- [npm] Add additional logging to VulnerabilityAuditor [#5662](https://github.com/dependabot/dependabot-core/pull/5662) +- fix smoke tests from forks by using public sources [#5665](https://github.com/dependabot/dependabot-core/pull/5665) +- Speed up dealing with non-reachable git repos [#5658](https://github.com/dependabot/dependabot-core/pull/5658) +- Fix incomplete clean up of odd python requirements [#5647](https://github.com/dependabot/dependabot-core/pull/5647) +- Run `rspec` with `--profile` flag by default in Python [#5607](https://github.com/dependabot/dependabot-core/pull/5607) +- Propagate author details when initializing PullRequestUpdater for Azure. (@JManou) [#5604](https://github.com/dependabot/dependabot-core/pull/5604) +- Fix updater specs on M1 [#5657](https://github.com/dependabot/dependabot-core/pull/5657) +- fix tagged push overwriting previous tags [#5649](https://github.com/dependabot/dependabot-core/pull/5649) +- Add more helpful error messaging when a vulnerable dependency cannot be upgraded [#5645](https://github.com/dependabot/dependabot-core/pull/5645) +- deploy commits made after approval [#5650](https://github.com/dependabot/dependabot-core/pull/5650) +- To prevent dependabot-core from failing when the incorrect release tag is created for a release, adding a rescue statement [#5615](https://github.com/dependabot/dependabot-core/pull/5615) +- Adding code tags around any nwo#number text string [#5646](https://github.com/dependabot/dependabot-core/pull/5646) +- move devcontainer to allow debugging updater with the default devcontainer [#5648](https://github.com/dependabot/dependabot-core/pull/5648) +- Revert "Add more helpful error messaging when a vulnerable dependency cannot be upgraded" [#5613](https://github.com/dependabot/dependabot-core/pull/5613) + +## v0.212.0, 6 September 2022 + +- prevent the push to main event from skipping [#5641](https://github.com/dependabot/dependabot-core/pull/5641) +- Fix path to python native helpers [#5617](https://github.com/dependabot/dependabot-core/pull/5617) +- push docker images after approval [#5640](https://github.com/dependabot/dependabot-core/pull/5640) +- branch naming for removed dependencies [#5623](https://github.com/dependabot/dependabot-core/pull/5623) +- Properly upgrade github actions pinned to specific commits [#5576](https://github.com/dependabot/dependabot-core/pull/5576) +- pull request message is always built, removing experiment [#5638](https://github.com/dependabot/dependabot-core/pull/5638) +- gradle depends on maven gem, so run gradle tests when maven changes [#5637](https://github.com/dependabot/dependabot-core/pull/5637) +- build(deps-dev): update parallel_tests requirement from ~> 3.11.1 to ~> 3.12.0 in /common [#5627](https://github.com/dependabot/dependabot-core/pull/5627) +- build(deps-dev): update rubocop requirement from ~> 1.35.1 to ~> 1.36.0 in /common [#5628](https://github.com/dependabot/dependabot-core/pull/5628) +- fix latest docker image not being pushed on merge to main [#5636](https://github.com/dependabot/dependabot-core/pull/5636) +- Add RuboCop Performance [#5586](https://github.com/dependabot/dependabot-core/pull/5586) +- Speedup rebuilding native helper changes [#5624](https://github.com/dependabot/dependabot-core/pull/5624) +- build(deps): bump poetry from 1.1.15 to 1.2.0 in /python/helpers [#5599](https://github.com/dependabot/dependabot-core/pull/5599) +- fix main failures saying there's no repository here [#5622](https://github.com/dependabot/dependabot-core/pull/5622) +- skip CI if no changes effect the ecosystem [#5620](https://github.com/dependabot/dependabot-core/pull/5620) +- only use GHCR for deploys [#5614](https://github.com/dependabot/dependabot-core/pull/5614) +- Enable new RuboCop cops [#5588](https://github.com/dependabot/dependabot-core/pull/5588) +- Configure RSpec to allow running `rspec --only-failures` [#5606](https://github.com/dependabot/dependabot-core/pull/5606) +- Revert "Add more helpful error messaging when a vulnerable dependency cannot be upgraded" [#5613](https://github.com/dependabot/dependabot-core/pull/5613) +- publish main branch images [#5610](https://github.com/dependabot/dependabot-core/pull/5610) +- build(deps): bump terraform from 1.2.3 to 1.2.8 (@gtirloni) [#5591](https://github.com/dependabot/dependabot-core/pull/5591) +- Add more helpful error messaging when a vulnerable dependency cannot be upgraded [#5542](https://github.com/dependabot/dependabot-core/pull/5542) +- Merge previously private updater code into core [#5608](https://github.com/dependabot/dependabot-core/pull/5608) +- Use correct label for tech debt form (@HonkingGoose) [#5602](https://github.com/dependabot/dependabot-core/pull/5602) +- Convert issue templates to issue forms (@HonkingGoose) [#5600](https://github.com/dependabot/dependabot-core/pull/5600) +- Dependabot Ltd -> GitHub Inc [#5592](https://github.com/dependabot/dependabot-core/pull/5592) +- Fix typo: `requiers` -> `requires` [#5583](https://github.com/dependabot/dependabot-core/pull/5583) +- build(deps): update faraday requirement from = 2.3.0 to = 2.5.2 in /common [#5535](https://github.com/dependabot/dependabot-core/pull/5535) + +## v0.211.0, 23 August 2022 + +- Support for transitive dependency removal [#5549](https://github.com/dependabot/dependabot-core/pull/5549) +- build(deps): bump poetry from 1.1.14 to 1.1.15 in /python/helpers [#5578](https://github.com/dependabot/dependabot-core/pull/5578) +- Adding required checks in ci-release.yml [#5575](https://github.com/dependabot/dependabot-core/pull/5575) + +## v0.210.0, 23 August 2022 + +- build(deps): bump nock from 13.2.8 to 13.2.9 in /npm_and_yarn/helpers [#5397](https://github.com/dependabot/dependabot-core/pull/5397) +- build(deps): bump NPM from 8.5.1 to 8.18.0 (@THETCR) [#5518](https://github.com/dependabot/dependabot-core/pull/5518) +- build(deps-dev): bump eslint from 8.21.0 to 8.22.0 in /npm_and_yarn/helpers [#5533](https://github.com/dependabot/dependabot-core/pull/5533) +- Fix file updater removing variants from docker tags [#5560](https://github.com/dependabot/dependabot-core/pull/5560) +- Update rubocop requirement from ~> 1.33.0 to ~> 1.35.1 in /common [#5564](https://github.com/dependabot/dependabot-core/pull/5564) +- Fix Bundler vendoring when a subdirectory is configured [#5567](https://github.com/dependabot/dependabot-core/pull/5567) +- Fix CI matrices [#5573](https://github.com/dependabot/dependabot-core/pull/5573) +- Split slow ecosystems across multiple CI jobs [#5568](https://github.com/dependabot/dependabot-core/pull/5568) +- Set the author details when updating an Azure pull request. (@JManou) [#5557](https://github.com/dependabot/dependabot-core/pull/5557) +- Bump @npmcli/arborist from 5.3.1 to 5.6.0 in /npm_and_yarn/helpers [#5563](https://github.com/dependabot/dependabot-core/pull/5563) +- Bump docker_registry2 to fix #3989 (@noorul) [#5436](https://github.com/dependabot/dependabot-core/pull/5436) +- Add a fix for when the image tag is the first entry in the array. (@brendandburns) [#5558](https://github.com/dependabot/dependabot-core/pull/5558) +- [terraform] Cache client-side timeouts when a remote host is unreachable [#5407](https://github.com/dependabot/dependabot-core/pull/5407) + +## v0.209.0, 17 August 2022 + +- Ignore newlines when determining indentation [#5550](https://github.com/dependabot/dependabot-core/pull/5550) +- Allow diverged-commit pinned Actions to be updated [#5516](https://github.com/dependabot/dependabot-core/pull/5516) +- Add a dependabot implementation for Kubernetes YAML files. (@brendandburns) [#5348](https://github.com/dependabot/dependabot-core/pull/5348) +- The new pip resolver is not backwards compatible [#5540](https://github.com/dependabot/dependabot-core/pull/5540) + +## v0.208.0, 16 August 2022 + +- Try fix spec failure due to broken setuptools [#5546](https://github.com/dependabot/dependabot-core/pull/5546) +- Share omnibus gems with all projects to reduce install time [#5529](https://github.com/dependabot/dependabot-core/pull/5529) +- build(deps): bump @dependabot/yarn-lib from 1.21.1 to 1.22.19 in /npm_and_yarn/helpers [#5531](https://github.com/dependabot/dependabot-core/pull/5531) +- Run shellcheck on all native helper build scripts [#5519](https://github.com/dependabot/dependabot-core/pull/5519) +- Python private registry authentication fix (@andrcuns) [#5452](https://github.com/dependabot/dependabot-core/pull/5452) +- Adds a TODO and more detailed comment about python 3.6 support [#5527](https://github.com/dependabot/dependabot-core/pull/5527) +- [Bitbucket] Add default reviewers to pull request (@stefangr) [#5526](https://github.com/dependabot/dependabot-core/pull/5526) +- Make failures in Bundler 1 native helper specs actually fail CI [#5517](https://github.com/dependabot/dependabot-core/pull/5517) +- Optional options arg for FileFetcher [#5524](https://github.com/dependabot/dependabot-core/pull/5524) +- Cleanup Ruby sources after installing Ruby [#5522](https://github.com/dependabot/dependabot-core/pull/5522) +- Remove ENV no longer necessary [#5515](https://github.com/dependabot/dependabot-core/pull/5515) + +## v0.207.0, 11 August 2022 + +- Monkey patch bundler EndpointSpecification [#5510](https://github.com/dependabot/dependabot-core/pull/5510) +- Log reasons why npm audit can't succeed [#5512](https://github.com/dependabot/dependabot-core/pull/5512) + +## v0.206.0, 10 August 2022 + +- Pin MessageBuilder cassette names [#5508](https://github.com/dependabot/dependabot-core/pull/5508) +- github_actions ecosystem was missing for debugging [#5505](https://github.com/dependabot/dependabot-core/pull/5505) +- Bump Elixir to `1.13.4` [#5502](https://github.com/dependabot/dependabot-core/pull/5502) +- build(deps-dev): update rubocop requirement from ~> 1.31.2 to ~> 1.33.0 in /common [#5498](https://github.com/dependabot/dependabot-core/pull/5498) +- build(deps): update pip requirement from <22.2.2,>=21.3.1 to >=21.3.1,<22.2.3 in /python/helpers [#5495](https://github.com/dependabot/dependabot-core/pull/5495) +- build(deps): bump flake8 from 5.0.3 to 5.0.4 in /python/helpers [#5496](https://github.com/dependabot/dependabot-core/pull/5496) +- Handle the new `go` build tag syntax [#4954](https://github.com/dependabot/dependabot-core/pull/4954) +- Tweak comment now that `pip` has a resolver [#5491](https://github.com/dependabot/dependabot-core/pull/5491) +- Bump to `go` `1.19` [#5490](https://github.com/dependabot/dependabot-core/pull/5490) +- Disable `pip` latest version check when building `python` native helper [#5493](https://github.com/dependabot/dependabot-core/pull/5493) +- [npm] Refactor with top-down traversal [#5439](https://github.com/dependabot/dependabot-core/pull/5439) +- build(deps): bump http from 0.13.4 to 0.13.5 in /pub/helpers [#5499](https://github.com/dependabot/dependabot-core/pull/5499) + +## v0.205.1, 8 August 2022 + +- Add a `.ruby-version` file [#5483](https://github.com/dependabot/dependabot-core/pull/5483) +- build(deps): update octokit requirement from ~> 4.6 to >= 4.6, < 6.0 in /common [#5370](https://github.com/dependabot/dependabot-core/pull/5370) +- Migrate from `actions/setup-ruby` to `ruby/setup-ruby` [#5433](https://github.com/dependabot/dependabot-core/pull/5433) +- Add support for multi-level wildcard paths in composer [#5484](https://github.com/dependabot/dependabot-core/pull/5484) +- Skip installing docs when installing Ruby [#5482](https://github.com/dependabot/dependabot-core/pull/5482) +- Suppress "detached head" advice during `git clone` [#5476](https://github.com/dependabot/dependabot-core/pull/5476) +- Bitbucket does not support HTML in pull request message (@stefangr) [#5481](https://github.com/dependabot/dependabot-core/pull/5481) + +## v0.205.0, 4 August 2022 + +- Downgrade bundler to 2.3.14 [#5479](https://github.com/dependabot/dependabot-core/pull/5479) +- build(deps): bump json-schema from 0.2.3 to 0.4.0 in /npm_and_yarn/helpers [#5425](https://github.com/dependabot/dependabot-core/pull/5425) +- Update ruby gems using the `--no-document` flag [#5471](https://github.com/dependabot/dependabot-core/pull/5471) +- build(deps-dev): bump eslint from 8.19.0 to 8.21.0 in /npm_and_yarn/helpers [#5455](https://github.com/dependabot/dependabot-core/pull/5455) +- build(deps): bump minimist from 1.2.5 to 1.2.6 in /npm_and_yarn/helpers [#5426](https://github.com/dependabot/dependabot-core/pull/5426) +- build(deps): bump cython from 0.29.30 to 0.29.32 in /python/helpers [#5457](https://github.com/dependabot/dependabot-core/pull/5457) +- build(deps): bump flake8 from 5.0.1 to 5.0.3 in /python/helpers [#5467](https://github.com/dependabot/dependabot-core/pull/5467) +- Allow Actions to be fetched from non-GitHub source [#5469](https://github.com/dependabot/dependabot-core/pull/5469) +- Reduce bundler version hardcoding (@deivid-rodriguez) [#4973](https://github.com/dependabot/dependabot-core/pull/4973) + +## v0.204.0, 3 August 2022 + +- use a "shim" to fix inability to rewrite git commands to use HTTPS URLs [#5332](https://github.com/dependabot/dependabot-core/pull/5332) + +## v0.203.0, 3 August 2022 + +- Make Dependabot watch the per-ecosystem gemspecs [#5460](https://github.com/dependabot/dependabot-core/pull/5460) +- build(deps): update pip requirement from <22.1.3,>=21.3.1 to >=21.3.1,<22.2.2 in /python/helpers [#5456](https://github.com/dependabot/dependabot-core/pull/5456) +- fix: set correct url for terraform module version download (@umglurf) [#5366](https://github.com/dependabot/dependabot-core/pull/5366) +- build(deps): bump @npmcli/arborist from 5.2.3 to 5.3.1 in /npm_and_yarn/helpers [#5458](https://github.com/dependabot/dependabot-core/pull/5458) +- build(deps): bump path-parse from 1.0.6 to 1.0.7 in /npm_and_yarn/helpers [#5427](https://github.com/dependabot/dependabot-core/pull/5427) +- GitLab: Extract local actions variable into method (@NobodysNightmare) [#5448](https://github.com/dependabot/dependabot-core/pull/5448) +- build(deps): bump flake8 from 4.0.1 to 5.0.1 in /python/helpers [#5454](https://github.com/dependabot/dependabot-core/pull/5454) +- Fix incomplete regular expression for hostnames [#5444](https://github.com/dependabot/dependabot-core/pull/5444) +- Bump base image in docker push workflow to `20.04` [#5432](https://github.com/dependabot/dependabot-core/pull/5432) +- Cache client-side timeouts when a remote host is unreachable for remaining ecosystems [#5408](https://github.com/dependabot/dependabot-core/pull/5408) +- Switch to weekly updates for Dependabot [#5435](https://github.com/dependabot/dependabot-core/pull/5435) +- Move comment to relevant section of code [#5434](https://github.com/dependabot/dependabot-core/pull/5434) +- Add dependabot updates for Dockerfiles [#5428](https://github.com/dependabot/dependabot-core/pull/5428) +- Re-order ecosystems lexicographically [#5429](https://github.com/dependabot/dependabot-core/pull/5429) +- build(deps): update faraday requirement from = 1.10.0 to = 2.3.0 in /common [#5197](https://github.com/dependabot/dependabot-core/pull/5197) + +## v0.202.0, 26 July 2022 + +- [cargo] Cache client-side timeouts when a remote host is unreachable [#5402](https://github.com/dependabot/dependabot-core/pull/5402) +- [gomod] Cache client-side timeouts when a remote host is unreachable [#5401](https://github.com/dependabot/dependabot-core/pull/5401) +- fix: regex to support Gitlab subgroups (@argoyle) [#5297](https://github.com/dependabot/dependabot-core/pull/5297) +- fix(terraform): correctly keep platform hashes when multiple providers are installed (@Flydiverny) [#5341](https://github.com/dependabot/dependabot-core/pull/5341) + +## v0.201.1, 25 July 2022 + +- [Cargo] Correctly handle unused subdependencies of path dependencies [#5414](https://github.com/dependabot/dependabot-core/pull/5414) +- [Nuget] Cache client-side timeouts when a remote host is unreachable [#5399](https://github.com/dependabot/dependabot-core/pull/5399) +- Tweak bump-version script to just push the newly-created tag [#5413](https://github.com/dependabot/dependabot-core/pull/5413) + +## v0.201.0, 22 July 2022 + +- [Composer] Cache client-side timeouts when a remote host is unreachable [#5400](https://github.com/dependabot/dependabot-core/pull/5400) + +## v0.200.0, 21 July 2022 + +- [Python] Cache client-side timeouts when a remote host is unreachable [#5374](https://github.com/dependabot/dependabot-core/pull/5374) +- Pip: Do not raise PathDependenciesNotReachable for missing setup.py [#5392](https://github.com/dependabot/dependabot-core/pull/5392) + +## v0.199.0, 19 July 2022 + +- Stop skipping requirements with `original_link` [#5385](https://github.com/dependabot/dependabot-core/pull/5385) + +## v0.198.0, 15 July 2022 + +- Bump go from 1.18.1 to 1.18.4 [#5379](https://github.com/dependabot/dependabot-core/pull/5379) +- [npm] Detect cycles when traversing vuln effects in helper and raise [#5321](https://github.com/dependabot/dependabot-core/pull/5321) + +## v0.197.0, 15 July 2022 + +- [Bundler] Cache client-side timeouts when a remote host is unreachable [#5375](https://github.com/dependabot/dependabot-core/pull/5375) +- Bump bundler from 2.3.13 to 2.3.18 and fix script [#5382](https://github.com/dependabot/dependabot-core/pull/5382) +- Use new pip resolver for pip-compile [#5358](https://github.com/dependabot/dependabot-core/pull/5358) + +## v0.196.4, 14 July 2022 + +- [NPM/YARN] Cache client-side timeouts when a remote host is unreachable [#5373](https://github.com/dependabot/dependabot-core/pull/5373) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.9.2 to 3.9.3 in /composer/helpers/v2 [#5378](https://github.com/dependabot/dependabot-core/pull/5378) +- build(deps-dev): bump jest from 28.1.2 to 28.1.3 in /npm_and_yarn/helpers [#5376](https://github.com/dependabot/dependabot-core/pull/5376) +- build(deps-dev): bump phpstan/phpstan from 1.8.0 to 1.8.1 in /composer/helpers/v2 [#5371](https://github.com/dependabot/dependabot-core/pull/5371) +- Update Ruby to version 2.7.6 [#5364](https://github.com/dependabot/dependabot-core/pull/5364) +- Install Ruby with ruby-install [#5356](https://github.com/dependabot/dependabot-core/pull/5356) +- Do not attribute `maintainers` in release notes [#5360](https://github.com/dependabot/dependabot-core/pull/5360) + +## v0.196.3, 12 July 2022 + +- Add support for Python 3.10.5 & 3.9.13 (@ulgens) [#5333](https://github.com/dependabot/dependabot-core/pull/5333) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.8.0 to 3.9.2 in /composer/helpers/v2 [#5357](https://github.com/dependabot/dependabot-core/pull/5357) +- build(deps): update pip-tools requirement from <=6.6.2,>=6.4.0 to >=6.4.0,<6.8.1 in /python/helpers [#5337](https://github.com/dependabot/dependabot-core/pull/5337) +- build(deps-dev): update rubocop requirement from ~> 1.30.1 to ~> 1.31.2 in /common [#5350](https://github.com/dependabot/dependabot-core/pull/5350) +- build(deps): bump poetry from 1.1.13 to 1.1.14 in /python/helpers [#5354](https://github.com/dependabot/dependabot-core/pull/5354) +- build(deps): update gitlab requirement from = 4.18.0 to = 4.19.0 in /common [#5355](https://github.com/dependabot/dependabot-core/pull/5355) +- build(deps): bump nock from 13.2.7 to 13.2.8 in /npm_and_yarn/helpers [#5336](https://github.com/dependabot/dependabot-core/pull/5336) +- build(deps-dev): bump eslint from 8.18.0 to 8.19.0 in /npm_and_yarn/helpers [#5343](https://github.com/dependabot/dependabot-core/pull/5343) +- build(deps): bump cython from 0.29.28 to 0.29.30 in /python/helpers [#5158](https://github.com/dependabot/dependabot-core/pull/5158) +- build(deps-dev): bump jest from 28.1.1 to 28.1.2 in /npm_and_yarn/helpers [#5328](https://github.com/dependabot/dependabot-core/pull/5328) +- build(deps-dev): bump phpstan/phpstan from 1.7.15 to 1.8.0 in /composer/helpers/v2 [#5330](https://github.com/dependabot/dependabot-core/pull/5330) +- build(deps): bump composer/composer from 2.3.5 to 2.3.9 in /composer/helpers/v2 [#5347](https://github.com/dependabot/dependabot-core/pull/5347) +- [go_mod] Stub failed response for initial go get call [#5335](https://github.com/dependabot/dependabot-core/pull/5335) +- [npm] Ensure 'fix_updates' field in `VulnerabilityAuditor#audit` response (@bdragon) [#5334](https://github.com/dependabot/dependabot-core/pull/5334) +- Disable potential script execution in arborist [#5327](https://github.com/dependabot/dependabot-core/pull/5327) + +## v0.196.2, 29 June 2022 + +- Configure arborist registries from npm config [#5313](https://github.com/dependabot/dependabot-core/pull/5313) +- Yarn: support recursive paths expansion (@FunkyloverOne) [#5231](https://github.com/dependabot/dependabot-core/pull/5231) + +## v0.196.1, 27 June 2022 + +- Fix rubocop configuration error [#5318](https://github.com/dependabot/dependabot-core/pull/5318) +- build(deps-dev): bump jest from 28.1.0 to 28.1.1 in /npm_and_yarn/helpers [#5243](https://github.com/dependabot/dependabot-core/pull/5243) +- build(deps-dev): bump phpstan/phpstan from 1.7.14 to 1.7.15 in /composer/helpers/v1 [#5290](https://github.com/dependabot/dependabot-core/pull/5290) +- build(deps-dev): bump phpstan/phpstan from 1.6.8 to 1.7.15 in /composer/helpers/v2 [#5291](https://github.com/dependabot/dependabot-core/pull/5291) +- build(deps): bump nock from 13.2.4 to 13.2.7 in /npm_and_yarn/helpers [#5316](https://github.com/dependabot/dependabot-core/pull/5316) +- build(deps): bump @npmcli/arborist from 5.2.0 to 5.2.3 in /npm_and_yarn/helpers [#5306](https://github.com/dependabot/dependabot-core/pull/5306) +- Prioritize target dependency in transitive dependency updates [#5311](https://github.com/dependabot/dependabot-core/pull/5311) + +## v0.196.0, 24 June 2022 + +- [npm] Initial support for locked transitive dependency updates [#5239](https://github.com/dependabot/dependabot-core/pull/5239) + +## v0.195.0, 24 June 2022 + +- Rebuild dependabot-core image in CI Workflow (@mattt) [#5307](https://github.com/dependabot/dependabot-core/pull/5307) +- Update logo in README (@mattt) [#5298](https://github.com/dependabot/dependabot-core/pull/5298) +- Update pub revision (@sigurdm) [#5272](https://github.com/dependabot/dependabot-core/pull/5272) +- Remove Image Caching from CI Workflow (@mattt) [#5295](https://github.com/dependabot/dependabot-core/pull/5295) + +## v0.194.1, 20 June 2022 + +- build(deps-dev): update debase-ruby_core_source requirement from = 0.10.14 to = 0.10.16 in /common [#5173](https://github.com/dependabot/dependabot-core/pull/5173) +- build(deps-dev): bump eslint from 8.15.0 to 8.18.0 in /npm_and_yarn/helpers [#5285](https://github.com/dependabot/dependabot-core/pull/5285) +- build(deps-dev): update rubocop requirement from ~> 1.29.1 to ~> 1.30.1 in /common [#5235](https://github.com/dependabot/dependabot-core/pull/5235) +- Setup Dependabot for the Pub helpers [#5289](https://github.com/dependabot/dependabot-core/pull/5289) +- Handle beta dart releases (@sigurdm) [#5286](https://github.com/dependabot/dependabot-core/pull/5286) + +## v0.194.0, 17 June 2022 + +- Updates TERRAFORM_VERSION in Dockerfile to version 1.2.3 (@joberget) [#5274](https://github.com/dependabot/dependabot-core/pull/5274) + +## v0.193.0, 16 June 2022 + +- Revert "build(deps-dev): bump phpstan/phpstan from 1.6.8 to 1.7.14 in /composer/helpers/v2" (@jakecoffman) [#5278](https://github.com/dependabot/dependabot-core/pull/5278) +- build(deps-dev): bump phpstan/phpstan from 1.6.8 to 1.7.14 in /composer/helpers/v2 [#5266](https://github.com/dependabot/dependabot-core/pull/5266) +- Update NPM package name validation rules (@mattt) [#5259](https://github.com/dependabot/dependabot-core/pull/5259) +- build(deps-dev): bump phpstan/phpstan from 1.6.8 to 1.7.14 in /composer/helpers/v1 [#5267](https://github.com/dependabot/dependabot-core/pull/5267) +- build(deps-dev): bump prettier from 2.6.2 to 2.7.1 in /npm_and_yarn/helpers [#5270](https://github.com/dependabot/dependabot-core/pull/5270) +- cargo: handle patch with path that is a submodule (@jakecoffman) [#5250](https://github.com/dependabot/dependabot-core/pull/5250) + +## v0.192.1, 14 June 2022 + +- Bump pub revision to fix error without lockfile [#5263](https://github.com/dependabot/dependabot-core/pull/5263) + +## v0.192.0, 13 June 2022 + +- Use inferred flutter version (@sigurdm) [#5207](https://github.com/dependabot/dependabot-core/pull/5207) + +## v0.191.1, 13 June 2022 + +- Only report conflicting dependencies when update is not possible (@deivid-rodriguez) [#5237](https://github.com/dependabot/dependabot-core/pull/5237) +- build(deps): update pip requirement from <=22.1.1,>=21.3.1 to >=21.3.1,<22.1.3 in /python/helpers [#5212](https://github.com/dependabot/dependabot-core/pull/5212) +- Fix Yarn ignored path checking (@FunkyloverOne) [#5220](https://github.com/dependabot/dependabot-core/pull/5220) + +## v0.191.0, 7 June 2022 + +- poetry: fixes for broken lockfile and leaked credentials (@jakecoffman) [#5222](https://github.com/dependabot/dependabot-core/pull/5222) +- Check if updated file exists before adding to list of terraform updated files (@dwc0011) [#5168](https://github.com/dependabot/dependabot-core/pull/5168) +- Print package manager version instrumentation events in the dry runner (@Nishnha) [#5194](https://github.com/dependabot/dependabot-core/pull/5194) +- Instrument npm version (@Nishnha) [#5187](https://github.com/dependabot/dependabot-core/pull/5187) + +## v0.190.1, 31 May 2022 + +- Update pub revision (@sigurdm) [#5203](https://github.com/dependabot/dependabot-core/pull/5203) +- Update test cases with new hashes returned from npm registry [#5208](https://github.com/dependabot/dependabot-core/pull/5208) +- Upgrade pip inside of any newly created pyenv (@pavera) [#5195](https://github.com/dependabot/dependabot-core/pull/5195) +- Document why the link needs to be unescaped (@jeffwidman) [#5186](https://github.com/dependabot/dependabot-core/pull/5186) +- URL decode Nuget API v2 "next" link when paging version results (@tomcain) [#5174](https://github.com/dependabot/dependabot-core/pull/5174) + +## v0.190.0, 23 May 2022 + +- Git dependency support for pub (@sigurdm) [#5102](https://github.com/dependabot/dependabot-core/pull/5102) +- Remove versions from comments (@jeffwidman) [#5181](https://github.com/dependabot/dependabot-core/pull/5181) +- Cargo: Update rust toolchain to 1.61.0 (@DarkKirb) [#5180](https://github.com/dependabot/dependabot-core/pull/5180) +- Bump Terraform from 1.0.16 to 1.2.0 (@andrassy) [#5170](https://github.com/dependabot/dependabot-core/pull/5170) +- fix required checks not run during a release (@jakecoffman) [#5144](https://github.com/dependabot/dependabot-core/pull/5144) + +## v0.189.0, 17 May 2022 + +- Revert "Strip UTF-8 BOM from file contents" (@mattt) [#5145](https://github.com/dependabot/dependabot-core/pull/5145) +- [Maven] Cache client-side timeouts when a remote host is unreachable (@brrygrdn) [#5142](https://github.com/dependabot/dependabot-core/pull/5142) +- build(deps): bump @npmcli/arborist from 5.1.0 to 5.2.0 in /npm_and_yarn/helpers [#5133](https://github.com/dependabot/dependabot-core/pull/5133) + +## v0.188.0, 16 May 2022 + +- Dwc0011/fix codecommit error (@dwc0011) [#4926](https://github.com/dependabot/dependabot-core/pull/4926) +- Upgrade Python to 3.10.4 and support newer releases (@henrikhorluck) [#4976](https://github.com/dependabot/dependabot-core/pull/4976) +- build(deps): bump npm from 6.14.16 to 6.14.17 in /npm_and_yarn/helpers [#5067](https://github.com/dependabot/dependabot-core/pull/5067) +- build(deps-dev): bump eslint from 8.13.0 to 8.15.0 in /npm_and_yarn/helpers [#5106](https://github.com/dependabot/dependabot-core/pull/5106) +- build(deps-dev): bump jest from 27.5.1 to 28.1.0 in /npm_and_yarn/helpers [#5105](https://github.com/dependabot/dependabot-core/pull/5105) +- build(deps-dev): bump phpstan/phpstan from 1.6.4 to 1.6.8 in /composer/helpers/v2 [#5126](https://github.com/dependabot/dependabot-core/pull/5126) +- build(deps-dev): bump phpstan/phpstan from 1.6.4 to 1.6.8 in /composer/helpers/v1 [#5127](https://github.com/dependabot/dependabot-core/pull/5127) +- build(deps-dev): update rubocop requirement from ~> 1.28.2 to ~> 1.29.1 in /common [#5136](https://github.com/dependabot/dependabot-core/pull/5136) +- skip CI workflow when creating release notes (@jakecoffman) [#5139](https://github.com/dependabot/dependabot-core/pull/5139) +- Strip UTF-8 BOM from file contents (@mattt) [#5129](https://github.com/dependabot/dependabot-core/pull/5129) + +## v0.187.0, 13 May 2022 + +- Fix Bundler v2 related TODOs (@deivid-rodriguez) [#5034](https://github.com/dependabot/dependabot-core/pull/5034) +- Add --network-trace to dry-run (@brrygrdn) [#5131](https://github.com/dependabot/dependabot-core/pull/5131) +- [Maven] Fix some malformed memoizations (@brrygrdn) [#5132](https://github.com/dependabot/dependabot-core/pull/5132) +- bundler: upgrade to 2.3.13 for rubygems/rubygems#5492 (@jakecoffman) [#5134](https://github.com/dependabot/dependabot-core/pull/5134) +- [Maven] Avoid retrying requests to repos excessively (@brrygrdn) [#5130](https://github.com/dependabot/dependabot-core/pull/5130) +- Fix Dependabot ignoring scoped registries if the lockfile resolved uri contains a port number (@brrygrdn) [#5124](https://github.com/dependabot/dependabot-core/pull/5124) + +## v0.186.1, 10 May 2022 + +- Validate before creating version objects in `Dependabot::NpmAndYarn::UpdateChecker::VersionResolver` (@mattt) [#5120](https://github.com/dependabot/dependabot-core/pull/5120) +- Fix implementation of `PackageName#library_name` (@mattt) [#5119](https://github.com/dependabot/dependabot-core/pull/5119) +- Clarify comment and remove TODO (@jeffwidman) [#5031](https://github.com/dependabot/dependabot-core/pull/5031) +- Bump `go` to `1.18.1` (@jeffwidman) [#5029](https://github.com/dependabot/dependabot-core/pull/5029) + +## v0.186.0, 10 May 2022 + +- Updating a package and its related @types package simultaneously (@pavera) [#5000](https://github.com/dependabot/dependabot-core/pull/5000) +- Remove and ignore `.tool-versions` (@mattt) [#5114](https://github.com/dependabot/dependabot-core/pull/5114) +- Add fixtures to `paths-ignore` for CodeQL workflow (@mattt) [#5113](https://github.com/dependabot/dependabot-core/pull/5113) +- Fix code scanning alerts for incomplete sanitization of URL substrings (@mattt) [#5108](https://github.com/dependabot/dependabot-core/pull/5108) + +## v0.185.0, 9 May 2022 + +- fix DependencyFileNotParseable due to 1MB file limit change (@jakecoffman) [#5107](https://github.com/dependabot/dependabot-core/pull/5107) +- pin debase version to avoid build errors (@pavera) [#5086](https://github.com/dependabot/dependabot-core/pull/5086) + +## v0.184.0, 4 May 2022 + +- nuget: fix PR missing commits in message when using private registry (@jakecoffman) [#5072](https://github.com/dependabot/dependabot-core/pull/5072) +- [Maven] Avoid an infinite loop if the default branch for a dependency 404s (@brrygrdn) [#5091](https://github.com/dependabot/dependabot-core/pull/5091) +- build(deps): bump github/codeql-action from 1 to 2 [#5053](https://github.com/dependabot/dependabot-core/pull/5053) +- Prevent Dependabot from downgrading Dockerfiles if the repository doesn't have the tag yet (@brrygrdn) [#5087](https://github.com/dependabot/dependabot-core/pull/5087) +- build(deps-dev): update rubocop requirement from ~> 1.27.0 to ~> 1.28.2 in /common [#5050](https://github.com/dependabot/dependabot-core/pull/5050) +- build(deps-dev): bump phpstan/phpstan from 1.5.6 to 1.6.4 in /composer/helpers/v2 [#5080](https://github.com/dependabot/dependabot-core/pull/5080) +- build(deps-dev): bump phpstan/phpstan from 1.5.6 to 1.6.4 in /composer/helpers/v1 [#5081](https://github.com/dependabot/dependabot-core/pull/5081) +- remove multiplicative retries to improve system health (@jakecoffman) [#5085](https://github.com/dependabot/dependabot-core/pull/5085) +- fix debase build errors (@jakecoffman) [#5078](https://github.com/dependabot/dependabot-core/pull/5078) + +## v0.183.0, 29 April 2022 + +- fix unsafe directory git issues during updates (@jakecoffman) [#5065](https://github.com/dependabot/dependabot-core/pull/5065) + +## v0.182.4, 26 April 2022 + +- Rollback RubyGems from 3.3.11 to 3.2.20 (@mctofu) [#5048](https://github.com/dependabot/dependabot-core/pull/5048) + +## v0.182.3, 25 April 2022 + +- Set BUNDLER_VERSION to the specific installed version in native helpers (@brrygrdn) [#5044](https://github.com/dependabot/dependabot-core/pull/5044) + +## v0.182.2, 25 April 2022 + +- Manually revert "nuget: fix PR missing commits in message when using private registry" (@brrygrdn) [#5040](https://github.com/dependabot/dependabot-core/pull/5040) + +## v0.182.1, 25 April 2022 + +- Prevent KeyError when checking search results (@brrygrdn) [#5038](https://github.com/dependabot/dependabot-core/pull/5038) +- Update RubyGems and use `--no-document` for updating it (@deivid-rodriguez) [#5035](https://github.com/dependabot/dependabot-core/pull/5035) +- Translate from `@types` package to library name (@landongrindheim) [#5025](https://github.com/dependabot/dependabot-core/pull/5025) +- Add ecosystem-specific code owners (@mattt) [#4614](https://github.com/dependabot/dependabot-core/pull/4614) +- fix typos in GitHub issue bug report template (@tyrann0us) [#5015](https://github.com/dependabot/dependabot-core/pull/5015) +- Update Bundler from 2.3.10 to 2.3.12 (@deivid-rodriguez) [#5018](https://github.com/dependabot/dependabot-core/pull/5018) +- build(deps): bump @npmcli/arborist from 5.0.6 to 5.1.0 in /npm_and_yarn/helpers [#5020](https://github.com/dependabot/dependabot-core/pull/5020) +- Use a temporary Ruby requirement for updating lockfile (@deivid-rodriguez) [#5019](https://github.com/dependabot/dependabot-core/pull/5019) + +## v0.182.0, 19 April 2022 + +- Automate Terraform Platform Detection for Lockfile Hashes [#4905](https://github.com/dependabot/dependabot-core/pull/4905) + +## v0.181.0, 19 April 2022 + +- nuget: fix PR missing commits in message when using private registry [#5002](https://github.com/dependabot/dependabot-core/pull/5002) +- Map Package Name to Types Package Name [#5001](https://github.com/dependabot/dependabot-core/pull/5001) +- build(deps-dev): bump phpstan/phpstan from 1.5.5 to 1.5.6 in /composer/helpers/v2 [#5010](https://github.com/dependabot/dependabot-core/pull/5010) +- build(deps-dev): bump phpstan/phpstan from 1.5.5 to 1.5.6 in /composer/helpers/v1 [#5007](https://github.com/dependabot/dependabot-core/pull/5007) +- build(deps-dev): bump phpstan/phpstan from 1.5.4 to 1.5.5 in /composer/helpers/v1 [#5005](https://github.com/dependabot/dependabot-core/pull/5005) +- build(deps-dev): bump phpstan/phpstan from 1.5.4 to 1.5.5 in /composer/helpers/v2 [#5004](https://github.com/dependabot/dependabot-core/pull/5004) +- build(deps): bump composer/composer from 1.10.25 to 1.10.26 in /composer/helpers/v1 [#4996](https://github.com/dependabot/dependabot-core/pull/4996) +- build(deps): bump @npmcli/arborist from 5.0.5 to 5.0.6 in /npm_and_yarn/helpers [#4994](https://github.com/dependabot/dependabot-core/pull/4994) +- build(deps): bump composer/composer from 2.3.4 to 2.3.5 in /composer/helpers/v2 [#4995](https://github.com/dependabot/dependabot-core/pull/4995) +- build(deps): bump semver from 7.3.6 to 7.3.7 in /npm_and_yarn/helpers [#4990](https://github.com/dependabot/dependabot-core/pull/4990) +- Adds failing tests for Typescript @types updates [#4992](https://github.com/dependabot/dependabot-core/pull/4992) +- handle multiple python manifests containing the same dependency [#4969](https://github.com/dependabot/dependabot-core/pull/4969) +- Python: unwrap arbitrary parentheses from requirement string [#4988](https://github.com/dependabot/dependabot-core/pull/4988) +- Adding ability to debug into tests from VS Code [#4971](https://github.com/dependabot/dependabot-core/pull/4971) +- build(deps): bump composer/composer from 2.3.3 to 2.3.4 in /composer/helpers/v2 [#4978](https://github.com/dependabot/dependabot-core/pull/4978) +- build(deps): bump @npmcli/arborist from 5.0.4 to 5.0.5 in /npm_and_yarn/helpers [#4977](https://github.com/dependabot/dependabot-core/pull/4977) +- build(deps-dev): update rubocop requirement from ~> 1.26.0 to ~> 1.27.0 in /common [#4986](https://github.com/dependabot/dependabot-core/pull/4986) +- build(deps): bump pipenv from 2022.3.28 to 2022.4.8 in /python/helpers [#4985](https://github.com/dependabot/dependabot-core/pull/4985) +- build(deps-dev): bump eslint from 8.12.0 to 8.13.0 in /npm_and_yarn/helpers [#4984](https://github.com/dependabot/dependabot-core/pull/4984) +- pub: Bump when publish to none (@sigurdm) [#4981](https://github.com/dependabot/dependabot-core/pull/4981) +- Fix terraform update_range function [#4982](https://github.com/dependabot/dependabot-core/pull/4982) +- Restore python 3.6 support [#4958](https://github.com/dependabot/dependabot-core/pull/4958) + +## v0.180.5, 7 April 2022 + +- Actions: Fix failed update if version was a partial match for a branch [#4972](https://github.com/dependabot/dependabot-core/pull/4972) +- build(deps-dev): bump eslint-config-prettier from 8.3.0 to 8.5.0 in /npm_and_yarn/helpers [#4788](https://github.com/dependabot/dependabot-core/pull/4788) +- build(deps-dev): bump jest from 27.4.7 to 27.5.1 in /npm_and_yarn/helpers [#4719](https://github.com/dependabot/dependabot-core/pull/4719) +- build(deps-dev): bump eslint from 8.7.0 to 8.12.0 in /npm_and_yarn/helpers [#4918](https://github.com/dependabot/dependabot-core/pull/4918) +- added php mcrypt extension (@oleg-andreyev) [#4170](https://github.com/dependabot/dependabot-core/pull/4170) +- build(deps): bump actions/checkout from 2 to 3 [#4783](https://github.com/dependabot/dependabot-core/pull/4783) +- build(deps): bump semver from 7.3.5 to 7.3.6 in /npm_and_yarn/helpers [#4965](https://github.com/dependabot/dependabot-core/pull/4965) +- Allow open_timeout to be configured by ENV var [#4964](https://github.com/dependabot/dependabot-core/pull/4964) +- code is unsused: main packages have no particular effect on dependencies [#4962](https://github.com/dependabot/dependabot-core/pull/4962) + +## v0.180.4, 6 April 2022 + +- Actions: Consider precision of current version when selecting latest [#4953](https://github.com/dependabot/dependabot-core/pull/4953) +- build(deps): bump composer/composer from 2.2.9 to 2.3.3 in /composer/helpers/v2 [#4944](https://github.com/dependabot/dependabot-core/pull/4944) +- Update bundler from 2.3.9 to 2.3.10 (@schinery) [#4961](https://github.com/dependabot/dependabot-core/pull/4961) +- build(deps): bump @npmcli/arborist from 5.0.3 to 5.0.4 in /npm_and_yarn/helpers [#4960](https://github.com/dependabot/dependabot-core/pull/4960) +- Update pub dependency service (@sigurdm) [#4957](https://github.com/dependabot/dependabot-core/pull/4957) +- build(deps-dev): bump phpstan/phpstan from 1.4.10 to 1.5.4 in /composer/helpers/v2 [#4946](https://github.com/dependabot/dependabot-core/pull/4946) +- build(deps-dev): bump phpstan/phpstan from 1.4.10 to 1.5.4 in /composer/helpers/v1 [#4945](https://github.com/dependabot/dependabot-core/pull/4945) +- build(deps-dev): bump prettier from 2.6.0 to 2.6.2 in /npm_and_yarn/helpers [#4943](https://github.com/dependabot/dependabot-core/pull/4943) +- build(deps): bump github.com/Masterminds/vcs from 1.13.1 to 1.13.3 in /go_modules/helpers [#4942](https://github.com/dependabot/dependabot-core/pull/4942) +- Cargo: Update specs to reference latest version of dependency used [#4956](https://github.com/dependabot/dependabot-core/pull/4956) + +## v0.180.3, 4 April 2022 + +- Add support for Python packages with epoch version [#4928](https://github.com/dependabot/dependabot-core/pull/4928) +- fix error due to not handling case statements in Gemfile [#4949](https://github.com/dependabot/dependabot-core/pull/4949) +- Remove unnecessary get_directory special cases for npm_and_yarn (@ianlyons) [#4840](https://github.com/dependabot/dependabot-core/pull/4840) +- Dockerfile: arm64 support (@thepwagner) [#4858](https://github.com/dependabot/dependabot-core/pull/4858) +- Bump bundler from 2.3.8 to 2.3.9 and automate it [#4884](https://github.com/dependabot/dependabot-core/pull/4884) +- Remove workaround for broken ruby gems compare (@jeffwidman) [#4933](https://github.com/dependabot/dependabot-core/pull/4933) +- Fix typo (@jeffwidman) [#4932](https://github.com/dependabot/dependabot-core/pull/4932) +- Add Ruby 3.1.1 to RubyRequirementSetter version requirements (@schinery) [#4912](https://github.com/dependabot/dependabot-core/pull/4912) +- Cargo: Update rust toolchain to 1.59.0 [#4921](https://github.com/dependabot/dependabot-core/pull/4921) +- Metadetafinders: Use the default branch instead of master for gitlab (@dennisvandehoef) [#4916](https://github.com/dependabot/dependabot-core/pull/4916) +- build(deps): bump pip from 21.3.1 to 22.0.4 in /python/helpers [#4809](https://github.com/dependabot/dependabot-core/pull/4809) +- Add option `get` to regex that match the `go` cmd (@jeffwidman) [#4911](https://github.com/dependabot/dependabot-core/pull/4911) +- Handle when `go: downloading` is emitted before an unknown revision error (@jeffwidman) [#4910](https://github.com/dependabot/dependabot-core/pull/4910) +- build(deps): bump pipenv from 2022.3.24 to 2022.3.28 in /python/helpers [#4919](https://github.com/dependabot/dependabot-core/pull/4919) +- Bump eslint-plugin-prettier from 2.0.1 to 2.1.1 in /helpers/javascript (@dependabot-preview) [#1](https://github.com/dependabot/dependabot-core/pull/1) + +## v0.180.2, 28 March 2022 + +- Add raise_on_ignore support to Pub [#4894](https://github.com/dependabot/dependabot-core/pull/4894) +- Bump Dart and Flutter to latest stable versions [#4904](https://github.com/dependabot/dependabot-core/pull/4904) +- Explicitly import process in npm_and_yarn helper [#4892](https://github.com/dependabot/dependabot-core/pull/4892) +- build(deps): bump pipenv from 2022.1.8 to 2022.3.24 in /python/helpers [#4900](https://github.com/dependabot/dependabot-core/pull/4900) + +## v0.180.1, 23 March 2022 + +- Npm: Handle `.tar.gz` extensions for path dependencies [#4889](https://github.com/dependabot/dependabot-core/pull/4889) +- Update pub dependency_service (@sigurdm) [#4890](https://github.com/dependabot/dependabot-core/pull/4890) +- fixed a bug and improved testing around NuGet version compare [#4881](https://github.com/dependabot/dependabot-core/pull/4881) +- Fix Ruby version conflict error detection for new Bundler versions (@deivid-rodriguez) [#4820](https://github.com/dependabot/dependabot-core/pull/4820) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.4.0 to 3.8.0 in /composer/helpers/v2 [#4883](https://github.com/dependabot/dependabot-core/pull/4883) +- Reenable commented out failing specs (@deivid-rodriguez) [#4882](https://github.com/dependabot/dependabot-core/pull/4882) +- Update Gitlab approvers logic on pr creation (@andrcuns) [#4747](https://github.com/dependabot/dependabot-core/pull/4747) +- build(deps): update gitlab requirement from = 4.17.0 to = 4.18.0 in /common [#4872](https://github.com/dependabot/dependabot-core/pull/4872) +- build(deps-dev): bump phpstan/phpstan from 1.4.2 to 1.4.10 in /composer/helpers/v1 [#4850](https://github.com/dependabot/dependabot-core/pull/4850) +- Improve file_fetcher for GitHub Actions (@JonasAlfredsson) [#4815](https://github.com/dependabot/dependabot-core/pull/4815) +- build(deps-dev): bump phpstan/phpstan from 1.4.2 to 1.4.10 in /composer/helpers/v2 [#4849](https://github.com/dependabot/dependabot-core/pull/4849) +- build(deps): update faraday requirement from = 1.7.0 to = 1.10.0 in /common [#4871](https://github.com/dependabot/dependabot-core/pull/4871) +- build(deps-dev): update rubocop requirement from ~> 1.23.0 to ~> 1.26.0 in /common [#4870](https://github.com/dependabot/dependabot-core/pull/4870) +- build(deps): bump composer/composer from 2.2.6 to 2.2.9 in /composer/helpers/v2 [#4861](https://github.com/dependabot/dependabot-core/pull/4861) +- build(deps-dev): bump prettier from 2.5.1 to 2.6.0 in /npm_and_yarn/helpers [#4880](https://github.com/dependabot/dependabot-core/pull/4880) +- pub metadata_finder: Fall back to `homepage` if `repository` is not present (@sigurdm) [#4879](https://github.com/dependabot/dependabot-core/pull/4879) + +## v0.180.0, 18 March 2022 + +- Upgrade main Python version to 3.10.3 (@ulgens) [#4874](https://github.com/dependabot/dependabot-core/pull/4874) +- build(deps): bump @npmcli/arborist from 4.2.1 to 5.0.3 in /npm_and_yarn/helpers [#4877](https://github.com/dependabot/dependabot-core/pull/4877) +- Modify ENV in a friendlier way during specs (@deivid-rodriguez) [#4865](https://github.com/dependabot/dependabot-core/pull/4865) +- Bump to `go` `1.18` (@jeffwidman) [#4853](https://github.com/dependabot/dependabot-core/pull/4853) +- Fix Bundler 1 spec failures (@deivid-rodriguez) [#4869](https://github.com/dependabot/dependabot-core/pull/4869) +- Require Ruby 2.7 (@deivid-rodriguez) [#4864](https://github.com/dependabot/dependabot-core/pull/4864) +- Bugfix: Include space in regex capturing group (@jeffwidman) [#4868](https://github.com/dependabot/dependabot-core/pull/4868) +- Get bundler specs green when run on Ruby 3.1 (@deivid-rodriguez) [#4841](https://github.com/dependabot/dependabot-core/pull/4841) +- NuGet version comparison fix [#4862](https://github.com/dependabot/dependabot-core/pull/4862) + +## v0.179.0, 16 March 2022 + +- Bump Ubuntu to 20.04 (@jeffwidman) [#4394](https://github.com/dependabot/dependabot-core/pull/4394) +- Use expanded path when DEPENDABOT_NATIVE_HELPERS_PATH not set (@deivid-rodriguez) [#4844](https://github.com/dependabot/dependabot-core/pull/4844) +- Fix flaky spec failure on Bundler 1 suite (@deivid-rodriguez) [#4846](https://github.com/dependabot/dependabot-core/pull/4846) +- Unify RSpec requirements in helpers Gemfiles to match dependabot-common (@deivid-rodriguez) [#4843](https://github.com/dependabot/dependabot-core/pull/4843) +- Remove duplicated spec (@deivid-rodriguez) [#4839](https://github.com/dependabot/dependabot-core/pull/4839) +- Fix webmock requirement in helpers Gemfiles to match dependabot-common (@deivid-rodriguez) [#4838](https://github.com/dependabot/dependabot-core/pull/4838) +- Enable codeql [#4817](https://github.com/dependabot/dependabot-core/pull/4817) +- Improve `DEBUG_HELPERS` output (@deivid-rodriguez) [#4827](https://github.com/dependabot/dependabot-core/pull/4827) +- Fix some specs to pass outside of Docker (@deivid-rodriguez) [#4835](https://github.com/dependabot/dependabot-core/pull/4835) + +## v0.178.1, 11 March 2022 + +- Fixes comparison between prerelease identifiers for NuGet [#4833](https://github.com/dependabot/dependabot-core/pull/4833) + +## v0.178.0, 10 March 2022 + +- Disable spec fetching retries which are not functioning properly [#4823](https://github.com/dependabot/dependabot-core/pull/4823) +- build(deps): bump cython from 0.29.27 to 0.29.28 in /python/helpers [#4750](https://github.com/dependabot/dependabot-core/pull/4750) +- Update ci-test script to use bundler 2.3.8 (@deivid-rodriguez) [#4824](https://github.com/dependabot/dependabot-core/pull/4824) +- Bump erlang from 23.3.4.5 to 24.2.1 [#4816](https://github.com/dependabot/dependabot-core/pull/4816) +- Remove unnecessary pub cert config [#4814](https://github.com/dependabot/dependabot-core/pull/4814) +- Pin nuget vcr cassette names [#4818](https://github.com/dependabot/dependabot-core/pull/4818) +- github_actions: Add support for Composite Actions (@JonasAlfredsson) [#4755](https://github.com/dependabot/dependabot-core/pull/4755) +- Note that the `--dir` flag is required for subdirs (@jeffwidman) [#4812](https://github.com/dependabot/dependabot-core/pull/4812) +- Fix `detect_indentation` nil access error [#4802](https://github.com/dependabot/dependabot-core/pull/4802) + +## v0.177.0, 4 March 2022 + +- Pub: use system root certificates [#4794](https://github.com/dependabot/dependabot-core/pull/4794) +- Bump bundler to 2.3.8 [#4786](https://github.com/dependabot/dependabot-core/pull/4786) +- pub support for requirement_update_strategy (@sigurdm) [#4778](https://github.com/dependabot/dependabot-core/pull/4778) +- Attempt to fix `*-*` range handling (@Danielku15) [#4749](https://github.com/dependabot/dependabot-core/pull/4749) +- Update NuGet to fetch packages using SemVer 2 [#4255](https://github.com/dependabot/dependabot-core/pull/4255) +- Update npm 7 references to npm 8 [#4771](https://github.com/dependabot/dependabot-core/pull/4771) +- build(deps): bump object-path from 0.11.5 to 0.11.8 in /npm_and_yarn/helpers [#4772](https://github.com/dependabot/dependabot-core/pull/4772) + +## v0.176.0, 28 February 2022 + +- Beta: Dart/Flutter pub support (@sigurdm) [#4510](https://github.com/dependabot/dependabot-core/pull/4510) + While now available in dependabot-core, this will require some more work before we + can roll this out in the GitHub-hosted version of Dependabot. +- Disable flaky bundler1 test [#4767](https://github.com/dependabot/dependabot-core/pull/4767) + +## v0.175.0, 25 February 2022 + +- Update to npm 8 [#4763](https://github.com/dependabot/dependabot-core/pull/4763) + This includes a subtle change with how indentation in lockfiles is handled, in + npm 8 the indentation from the package.json file is used, whereas before the + package-lock.json would keep it's own indentation. Other than that 8 should be + mostly backwards compatible. We suggest updating to npm 8 though, as 7 is no + longer officially supported by the npm team. + +## v0.174.1, 22 February 2022 + +- Temporarily revert Docker arg from support [#4759](https://github.com/dependabot/dependabot-core/pull/4759) +- Fix references to changelog path/contents in bump_version.rb [#4756](https://github.com/dependabot/dependabot-core/pull/4756) + +## v0.174.0, 18 February 2022 + +- Bump Terraform from 1.0.11 to 1.1.6 [#4748](https://github.com/dependabot/dependabot-core/pull/4748) +- Codecommit pr release bugfix (@dwc0011) [#4745](https://github.com/dependabot/dependabot-core/pull/4745) +- Support depname.version = "1.2.3" syntax in TOML (@roblabla) [#4738](https://github.com/dependabot/dependabot-core/pull/4738) +- Add `--dry-run` flag to `bump-version` script [#4736](https://github.com/dependabot/dependabot-core/pull/4736) + +## v0.173.0, 14 February 2022 + +- Update node to latest LTS version (16.x) [#4733](https://github.com/dependabot/dependabot-core/pull/4733) +- build(deps): bump poetry from 1.1.12 to 1.1.13 in /python/helpers [#4732](https://github.com/dependabot/dependabot-core/pull/4732) + +## v0.172.2, 10 February 2022 + +- Bump go from 1.17.5 to 1.17.7 [#4730](https://github.com/dependabot/dependabot-core/pull/4730) + +## v0.172.1, 9 February 2022 + +- Docker: Ignore ARGs without default values [#4723](https://github.com/dependabot/dependabot-core/pull/4723) +- build(deps): bump pip-tools from 6.5.0 to 6.5.1 in /python/helpers [#4718](https://github.com/dependabot/dependabot-core/pull/4718) + +## v0.172.0, 9 February 2022 + +- Verify the right version of composer is installed in helper and docker [#4716](https://github.com/dependabot/dependabot-core/pull/4716) +- Bump composer v1 binary from 1.10.24 to 1.10.25 [#4717](https://github.com/dependabot/dependabot-core/pull/4717) +- Docker: Support ARG FROM (@hfhbd) [#4598](https://github.com/dependabot/dependabot-core/pull/4598) +- Fix peer dependency regex for cases with 2 semver constraints (@FaHeymann) [#4693](https://github.com/dependabot/dependabot-core/pull/4693) +- build(deps): bump composer/composer from 2.2.5 to 2.2.6 in /composer/helpers/v2 [#4708](https://github.com/dependabot/dependabot-core/pull/4708) +- Link to GitHub feedback discussion for Dependabot [#4714](https://github.com/dependabot/dependabot-core/pull/4714) +- Fix Running with Docker section to find the image that was just pulled (@joshuabremerdexcom) [#4694](https://github.com/dependabot/dependabot-core/pull/4694) +- build(deps): bump cython from 0.29.26 to 0.29.27 in /python/helpers [#4686](https://github.com/dependabot/dependabot-core/pull/4686) +- build(deps): bump pip-tools from 6.4.0 to 6.5.0 in /python/helpers [#4706](https://github.com/dependabot/dependabot-core/pull/4706) + +## v0.171.5, 7 February 2022 + +- Optimize rust toolchain installation [#4711](https://github.com/dependabot/dependabot-core/pull/4711) +- Fix typo: `developerment` -> `development` (@jeffwidman) [#4705](https://github.com/dependabot/dependabot-core/pull/4705) +- Fix typo: `is does` --> `executes` (@jeffwidman) [#4704](https://github.com/dependabot/dependabot-core/pull/4704) +- Add support for Python 3.9.10 (@Dresdn) [#4692](https://github.com/dependabot/dependabot-core/pull/4692) +- Bump cargo from 1.51.0 to 1.58.0 [#4677](https://github.com/dependabot/dependabot-core/pull/4677) + +## v0.171.4, 27 January 2022 + +- Nuget: Adding "devDependencies" support (@mwaddell) [#4671](https://github.com/dependabot/dependabot-core/pull/4671) +- Support `releases` to list of supported changelog files (@nipunn1313) [#4599](https://github.com/dependabot/dependabot-core/pull/4599) +- Composer v2: Prevent unnecessary package downloads (@driskell) [#4635](https://github.com/dependabot/dependabot-core/pull/4635) +- Python: Upgrade to 3.10.2 (@ulgens) [#4646](https://github.com/dependabot/dependabot-core/pull/4646) + +## v0.171.3, 26 January 2022 + +- Update GitHub Actions label description [#4661](https://github.com/dependabot/dependabot-core/pull/4661) +- build(deps): bump hashin from 0.15.0 to 0.17.0 in /python/helpers [#4619](https://github.com/dependabot/dependabot-core/pull/4619) +- build(deps): bump lodash from 4.17.20 to 4.17.21 in /npm_and_yarn/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested [#4668](https://github.com/dependabot/dependabot-core/pull/4668) +- build(deps): bump extend from 3.0.0 to 3.0.2 in /npm_and_yarn/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple [#4667](https://github.com/dependabot/dependabot-core/pull/4667) +- build(deps-dev): bump eslint from 8.6.0 to 8.7.0 in /npm_and_yarn/helpers [#4637](https://github.com/dependabot/dependabot-core/pull/4637) +- build(deps-dev): bump phpstan/phpstan from 1.3.3 to 1.4.2 in /composer/helpers/v2 [#4644](https://github.com/dependabot/dependabot-core/pull/4644) +- build(deps-dev): bump phpstan/phpstan from 1.3.3 to 1.4.2 in /composer/helpers/v1 [#4645](https://github.com/dependabot/dependabot-core/pull/4645) +- build(deps): bump npm from 6.14.14 to 6.14.16 in /npm_and_yarn/helpers [#4651](https://github.com/dependabot/dependabot-core/pull/4651) +- build(deps): bump @npmcli/arborist from 4.1.1 to 4.2.1 in /npm_and_yarn/helpers [#4655](https://github.com/dependabot/dependabot-core/pull/4655) +- build(deps): bump composer/composer from 2.2.4 to 2.2.5 in /composer/helpers/v2 [#4657](https://github.com/dependabot/dependabot-core/pull/4657) +- build(deps): bump composer/composer from 1.10.24 to 1.10.25 in /composer/helpers/v1 [#4658](https://github.com/dependabot/dependabot-core/pull/4658) +- npm7: Fix subdependency versoion resolver [#4664](https://github.com/dependabot/dependabot-core/pull/4664) +- Add section to debug native helper scripts [#4665](https://github.com/dependabot/dependabot-core/pull/4665) +- Bitbucket: creating pull-request-creator fails on labeler not supporting bitbucket (@stefangr) [#4608](https://github.com/dependabot/dependabot-core/pull/4608) + +## v0.171.2, 14 January 2022 + +- Support npm lockfile v3 format [#4630](https://github.com/dependabot/dependabot-core/pull/4630) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.3.2 to 3.4.0 in /composer/helpers/v2 [#4516](https://github.com/dependabot/dependabot-core/pull/4516) +- Terraform unknown git repo dependency name (@dwc0011) [#4493](https://github.com/dependabot/dependabot-core/pull/4493) +- build(deps-dev): bump jest from 27.4.5 to 27.4.7 in /npm_and_yarn/helpers [#4594](https://github.com/dependabot/dependabot-core/pull/4594) +- build(deps-dev): bump eslint from 8.5.0 to 8.6.0 in /npm_and_yarn/helpers [#4577](https://github.com/dependabot/dependabot-core/pull/4577) +- build(deps): bump jason from 1.2.2 to 1.3.0 in /hex/helpers [#4557](https://github.com/dependabot/dependabot-core/pull/4557) + +## v0.171.1, 12 January 2022 + +- build(deps): bump composer/composer from 1.10.23 to 1.10.24 in /composer/helpers/v1 [#4509](https://github.com/dependabot/dependabot-core/pull/4509) +- build(deps-dev): bump phpstan/phpstan from 1.3.1 to 1.3.3 in /composer/helpers/v1 [#4613](https://github.com/dependabot/dependabot-core/pull/4613) +- build(deps-dev): bump phpstan/phpstan from 1.3.1 to 1.3.3 in /composer/helpers/v2 [#4612](https://github.com/dependabot/dependabot-core/pull/4612) +- Refresh the workflow for native helpers within the docker dev shell, Consistency pass on native dev [#4556](https://github.com/dependabot/dependabot-core/pull/4556) +- build(deps): bump composer/composer from 2.1.14 to 2.2.4 in /composer/helpers/v2 [#4611](https://github.com/dependabot/dependabot-core/pull/4611) + +## v0.171.0, 11 January 2022 + +- Consistency pass on composer native helper build [#4554](https://github.com/dependabot/dependabot-core/pull/4554) + - NOTE: If you are using the `dependabot-composer` gem in your Dependabot scripts, you must ensure you upgrade + both the gem and the `dependabot/dependabot-core` image to v0.171.0 at the same time as this change modifies the + install path for composer's native helpers in both. + +## v0.170.2, 11 January 2022 + +- build(deps): bump pipenv from 2021.11.23 to 2022.1.8 in /python/helpers [#4609](https://github.com/dependabot/dependabot-core/pull/4609) + +## v0.170.1, 10 January 2022 + +- Ensure CI builds pick up native helper changes [#4618](https://github.com/dependabot/dependabot-core/pull/4618) +- Fix poetry secondary source bug (@isobelhooper) [#4323](https://github.com/dependabot/dependabot-core/pull/4323) +- build(deps-dev): bump phpstan/phpstan from 1.2.0 to 1.3.1 in /composer/helpers/v2 [#4583](https://github.com/dependabot/dependabot-core/pull/4583) +- Ensure CI uses the latest image built on that branch [#4596](https://github.com/dependabot/dependabot-core/pull/4596) + +## v0.170.0, 5 January 2022 + +- Allow configuration of GOPRIVATE [#4568](https://github.com/dependabot/dependabot-core/pull/4568) +- build(deps-dev): bump phpstan/phpstan from 1.2.0 to 1.3.1 in /composer/helpers/v1 [#4582](https://github.com/dependabot/dependabot-core/pull/4582) +- Simplify Dockerfile a little bit (@PeterDaveHello) [#4584](https://github.com/dependabot/dependabot-core/pull/4584) +- Check for access before ghcr push [#4569](https://github.com/dependabot/dependabot-core/pull/4569) +- Cleanup after byebug removal [#4567](https://github.com/dependabot/dependabot-core/pull/4567) +- build(deps): bump cython from 0.29.25 to 0.29.26 in /python/helpers [#4540](https://github.com/dependabot/dependabot-core/pull/4540) +- build(deps): bump wheel from 0.37.0 to 0.37.1 in /python/helpers [#4562](https://github.com/dependabot/dependabot-core/pull/4562) +- Enable support for ActiveSupport 7 [#4559](https://github.com/dependabot/dependabot-core/pull/4559) +- Python: Move some more tests to the slow suite [#4564](https://github.com/dependabot/dependabot-core/pull/4564) +- Use GHCR as the canonical source for CI images [#4560](https://github.com/dependabot/dependabot-core/pull/4560) +- Python: Quarantine slow tests into their own CI run [#4558](https://github.com/dependabot/dependabot-core/pull/4558) +- Update the CI workflow to use GHPR for branch images and as a mirror for CI images [#4524](https://github.com/dependabot/dependabot-core/pull/4524) + +## v0.169.8, 21 December 2021 + +- Bundler: update bundler to 2.2.33 [#4534](https://github.com/dependabot/dependabot-core/pull/4534) +- Bundler: Fix syntax for setting bundle config [#4552](https://github.com/dependabot/dependabot-core/pull/4552) +- Common: Consider all failed requests to check enterprise source as false [#4551](https://github.com/dependabot/dependabot-core/pull/4551) +- build(deps-dev): bump eslint from 8.4.1 to 8.5.0 in /npm_and_yarn/helpers [#4547](https://github.com/dependabot/dependabot-core/pull/4547) + +## v0.169.7, 19 December 2021 + +- Common: Constrain activesupport to < 7 [#4541](https://github.com/dependabot/dependabot-core/pull/4541) +- Dev: Avoid setting HTTP_PROXY for docker in the dev shell [#4533](https://github.com/dependabot/dependabot-core/pull/4533) +- Python: Upgrade pyenv to 2.2.2 (@Dresdn) [#4526](https://github.com/dependabot/dependabot-core/pull/4526) +- Cargo: Allow whitespace at beginning of Cargo dependency declarations [#4528](https://github.com/dependabot/dependabot-core/pull/4528) +- Terraform: Return name unless contains git dependency name notation (@dwc0011) [#4527](https://github.com/dependabot/dependabot-core/pull/4527) +- Dev: Fix conditional in `docker` workflow [#4529](https://github.com/dependabot/dependabot-core/pull/4529) +- Dev: build(deps-dev): bump jest from 27.4.3 to 27.4.5 in /npm_and_yarn/helpers [#4522](https://github.com/dependabot/dependabot-core/pull/4522) +- Dev: Disable `docker` workflow on forks [#4525](https://github.com/dependabot/dependabot-core/pull/4525) +- Dev: Push dependabot/dependabot-core to GHCR in order to provide a mirror [#4523](https://github.com/dependabot/dependabot-core/pull/4523) +- Dev: Reinstate the dev container build, pushing to GHCR [#4517](https://github.com/dependabot/dependabot-core/pull/4517) + +## v0.169.6, 13 December 2021 + +- Python invalid url [#4514](https://github.com/dependabot/dependabot-core/pull/4514) +- Fix failing Cargo test [#4520](https://github.com/dependabot/dependabot-core/pull/4520) +- Bump go from 1.17.4 to 1.17.5 [#4512](https://github.com/dependabot/dependabot-core/pull/4512) +- Remove the developer image docker build [#4513](https://github.com/dependabot/dependabot-core/pull/4513) +- Prebuild and publish the dependabot/dependabot-core-development container [#4511](https://github.com/dependabot/dependabot-core/pull/4511) +- build(deps): bump composer/composer from 2.1.12 to 2.1.14 in /composer/helpers/v2 [#4473](https://github.com/dependabot/dependabot-core/pull/4473) + +## v0.169.5, 9 December 2021 + +- build(deps): bump @npmcli/arborist from 4.0.5 to 4.1.1 in /npm_and_yarn/helpers [#4505](https://github.com/dependabot/dependabot-core/pull/4505) +- build(deps-dev): update rubocop requirement from ~> 1.18.0 to ~> 1.23.0 in /common [#4413](https://github.com/dependabot/dependabot-core/pull/4413) +- Autofix all rubocop lint [#4499](https://github.com/dependabot/dependabot-core/pull/4499) +- build(deps-dev): bump jest from 27.2.5 to 27.4.3 in /npm_and_yarn/helpers [#4478](https://github.com/dependabot/dependabot-core/pull/4478) +- feat(:git): do not decline valid git@... source (@sebbrandt87) [#4490](https://github.com/dependabot/dependabot-core/pull/4490) +- build(deps-dev): bump prettier from 2.4.1 to 2.5.1 in /npm_and_yarn/helpers [#4489](https://github.com/dependabot/dependabot-core/pull/4489) +- build(deps-dev): bump eslint from 8.3.0 to 8.4.1 in /npm_and_yarn/helpers [#4494](https://github.com/dependabot/dependabot-core/pull/4494) +- build(deps): bump cython from 0.29.24 to 0.29.25 in /python/helpers [#4495](https://github.com/dependabot/dependabot-core/pull/4495) +- Bump to go 1.17.4 (@jeffwidman) [#4492](https://github.com/dependabot/dependabot-core/pull/4492) + +## v0.169.4, 7 December 2021 + +- Maven: Handle nested plugin declarations [#4487](https://github.com/dependabot/dependabot-core/pull/4487) + +## v0.169.3, 2 December 2021 + +- Test for updating version of a parent pom [#4477](https://github.com/dependabot/dependabot-core/pull/4477) +- Revert "Maven: Correctly handle nested declarations" [#4479](https://github.com/dependabot/dependabot-core/pull/4479) +- Fix terraform dependency checker (@dwc0011) [#4440](https://github.com/dependabot/dependabot-core/pull/4440) +- Add tech-debt issue template (@jeffwidman) [#4470](https://github.com/dependabot/dependabot-core/pull/4470) +- Add bundler/helpers directory to devcontainer.json for VSCode (@dwc0011) [#4471](https://github.com/dependabot/dependabot-core/pull/4471) +- Limit the GitHub PR description message to API max [#4450](https://github.com/dependabot/dependabot-core/pull/4450) + +## v0.169.2, 30 November 2021 + +- Hex: Handle additional dynamic version reading approaches [#4442](https://github.com/dependabot/dependabot-core/pull/4442) +- Update contributor from Dependabot Ltd to GitHub Inc (@jjcaine) [#4463](https://github.com/dependabot/dependabot-core/pull/4463) +- Bump Terraform from 1.0.8 to 1.0.11 [#4464](https://github.com/dependabot/dependabot-core/pull/4464) +- Introduce dependabot-fixture for npm6 unpinned git source test [#4466](https://github.com/dependabot/dependabot-core/pull/4466) + +## v0.169.1, 29 November 2021 + +- build(deps): bump poetry from 1.1.11 to 1.1.12 in /python/helpers [#4461](https://github.com/dependabot/dependabot-core/pull/4461) +- build(deps): bump composer/composer from 2.1.9 to 2.1.12 in /composer/helpers/v2 [#4395](https://github.com/dependabot/dependabot-core/pull/4395) +- build(deps-dev): bump phpstan/phpstan from 0.12.93 to 1.2.0 in /composer/helpers/v2 [#4431](https://github.com/dependabot/dependabot-core/pull/4431) +- build(deps-dev): bump phpstan/phpstan from 0.12.99 to 1.2.0 in /composer/helpers/v1 [#4430](https://github.com/dependabot/dependabot-core/pull/4430) +- build(deps-dev): bump eslint from 8.0.0 to 8.3.0 in /npm_and_yarn/helpers [#4436](https://github.com/dependabot/dependabot-core/pull/4436) +- build(deps): bump pipenv from 2021.11.15 to 2021.11.23 in /python/helpers [#4452](https://github.com/dependabot/dependabot-core/pull/4452) +- Go modules: Bump minimum to 1.17 (@jeffwidman) [#4447](https://github.com/dependabot/dependabot-core/pull/4447) + +## v0.169.0, 23 November 2021 + +- Use `go list -m -versions` to determine available versions of a go module [#4434](https://github.com/dependabot/dependabot-core/pull/4434) +- python: Upgrade to pip 21.3.1 (@rouge8) [#4444](https://github.com/dependabot/dependabot-core/pull/4444) + +## v0.168.0, 23 November 2021 + +- [Azure] Check & Raise TagsCreationForbidden Exception (@AlekhyaYalla) [#4352](https://github.com/dependabot/dependabot-core/pull/4352) +- Use redirect.github.com for redirect service [#4441](https://github.com/dependabot/dependabot-core/pull/4441) +- Python: Honour `--strip-extras` flag of `pip-compile` (@NicolasT) [#4439](https://github.com/dependabot/dependabot-core/pull/4439) +- build(deps): bump pipenv from 2021.5.29 to 2021.11.15 in /python/helpers [#4408](https://github.com/dependabot/dependabot-core/pull/4408) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 2.19.2 to 2.19.3 in /composer/helpers/v1 [#4415](https://github.com/dependabot/dependabot-core/pull/4415) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.2.1 to 3.3.2 in /composer/helpers/v2 [#4414](https://github.com/dependabot/dependabot-core/pull/4414) +- Run YarnUpdate only once for a version requirement (@AlekhyaYalla) [#4409](https://github.com/dependabot/dependabot-core/pull/4409) +- Do not freeze file-based Poetry dependency version (@phillipuniverse) [#4334](https://github.com/dependabot/dependabot-core/pull/4334) +- Remove reliance on `PandocRuby` [#4433](https://github.com/dependabot/dependabot-core/pull/4433) +- build(deps): bump @npmcli/arborist from 3.0.0 to 4.0.5 in /npm_and_yarn/helpers [#4429](https://github.com/dependabot/dependabot-core/pull/4429) +- Add support for custom commit message trailers (@andrcuns) [#4432](https://github.com/dependabot/dependabot-core/pull/4432) +- Support updating dependencies on settings file (@anatawa12) [#4374](https://github.com/dependabot/dependabot-core/pull/4374) +- Remove the dependabot migration issue template [#4422](https://github.com/dependabot/dependabot-core/pull/4422) + +## v0.167.0, 16 November 2021 + +- Maven: Correctly handle nested declarations [#4417](https://github.com/dependabot/dependabot-core/pull/4417) +- Add parsing of MSBuild SDK dependencies (NuGet) (@Zastai) [#2849](https://github.com/dependabot/dependabot-core/pull/2849) +- fix: remove fixed error message check [#4412](https://github.com/dependabot/dependabot-core/pull/4412) + +## v0.166.1, 12 November 2021 + +- Terraform: Improve file updater and registry request error handling [#4405](https://github.com/dependabot/dependabot-core/pull/4405) +- Explicitly ignore metadata detection for fuchsia.googlesource.com [#4402](https://github.com/dependabot/dependabot-core/pull/4402) + +## v0.166.0, 11 November 2021 + +- Ignore errors from Source enterprise check and ignore known failures [#4401](https://github.com/dependabot/dependabot-core/pull/4401) +- Bump to go 1.17.3 (@jeffwidman) [#4393](https://github.com/dependabot/dependabot-core/pull/4393) +- Move composer-not-found fixture from decommissioned dependabot.com [#4399](https://github.com/dependabot/dependabot-core/pull/4399) + +## v0.165.0, 8 November 2021 + +- Add timeout per operation [#4362](https://github.com/dependabot/dependabot-core/pull/4362) + +## v0.164.1, 2 November 2021 + +- Only check auth for github.com when running `bump-version` [#4347](https://github.com/dependabot/dependabot-core/pull/4347) +- Ensure we cleanup tmp directories after use [#4356](https://github.com/dependabot/dependabot-core/pull/4356) +- Treat GHES hosted sources as github sources [#4335](https://github.com/dependabot/dependabot-core/pull/4335) + +## v0.164.0, 27 October 2021 + +- Add license to image and gemspec [#4317](https://github.com/dependabot/dependabot-core/pull/4317) +- Gitlab: add support for creating merge requests for forks (@andrcuns) [#4324](https://github.com/dependabot/dependabot-core/pull/4324) +- update Elixir from 1.12.2 -> 1.12.3 (@baseballlover723) [#4250](https://github.com/dependabot/dependabot-core/pull/4250) +- build(deps): bump flake8 from 4.0.0 to 4.0.1 in /python/helpers [#4308](https://github.com/dependabot/dependabot-core/pull/4308) +- Bump Terraform from 1.0.6 to 1.0.8 [#4310](https://github.com/dependabot/dependabot-core/pull/4310) +- build(deps): bump pip-tools from 6.3.1 to 6.4.0 in /python/helpers [#4312](https://github.com/dependabot/dependabot-core/pull/4312) +- Python: Upgrade pyenv to 2.1.0 (@Parnassius) [#4307](https://github.com/dependabot/dependabot-core/pull/4307) +- Upgrade OTP to latest minor: 23.3.4.5 (@tomaspinho) [#4306](https://github.com/dependabot/dependabot-core/pull/4306) +- hex: handle support files with macro in umbrellas (@nirev) [#4213](https://github.com/dependabot/dependabot-core/pull/4213) +- Describe workaround for cloning with long file names on Windows (@Marcono1234) [#4198](https://github.com/dependabot/dependabot-core/pull/4198) +- build(deps): bump golang.org/x/mod from 0.5.0 to 0.5.1 in /go_modules/helpers [#4254](https://github.com/dependabot/dependabot-core/pull/4254) +- build(deps): bump pip from 21.1.3 to 21.2.4 in /python/helpers [#4136](https://github.com/dependabot/dependabot-core/pull/4136) +- build(deps-dev): bump eslint from 7.32.0 to 8.0.0 in /npm_and_yarn/helpers [#4301](https://github.com/dependabot/dependabot-core/pull/4301) +- build(deps): bump flake8 from 3.9.2 to 4.0.0 in /python/helpers [#4303](https://github.com/dependabot/dependabot-core/pull/4303) +- build(deps-dev): bump jest from 27.2.4 to 27.2.5 in /npm_and_yarn/helpers [#4304](https://github.com/dependabot/dependabot-core/pull/4304) +- build(deps): bump pip-tools from 6.3.0 to 6.3.1 in /python/helpers [#4302](https://github.com/dependabot/dependabot-core/pull/4302) +- Clarify that Remote Containers Clone Repository commands are not supported (@Marcono1234) [#4199](https://github.com/dependabot/dependabot-core/pull/4199) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 2.19.0 to 2.19.2 in /composer/helpers/v1 [#4152](https://github.com/dependabot/dependabot-core/pull/4152) +- build(deps): bump wheel from 0.36.2 to 0.37.0 in /python/helpers [#4128](https://github.com/dependabot/dependabot-core/pull/4128) +- build(deps-dev): bump prettier from 2.3.2 to 2.4.1 in /npm_and_yarn/helpers [#4233](https://github.com/dependabot/dependabot-core/pull/4233) + +## v0.163.0, 7 October 2021 + +- build(deps): bump composer/composer from 2.1.3 to 2.1.9 in /composer/helpers/v2 [#4286](https://github.com/dependabot/dependabot-core/pull/4286) +- Bitbucket: Fix unsupported labels error (@meladRaouf) [#4236](https://github.com/dependabot/dependabot-core/pull/4236) +- build(deps): bump pip-tools from 6.2.0 to 6.3.0 in /python/helpers [#4251](https://github.com/dependabot/dependabot-core/pull) +- build(deps): bump poetry from 1.1.7 to 1.1.11 in /python/helpers [#4281](https://github.com/dependabot/dependabot-core/pull/4281) +- build(deps-dev): bump jest from 27.0.6 to 27.2.4 in /npm_and_yarn/helpers [#4271](https://github.com/dependabot/dependabot-core/pull/4271) +- Poetry: Fix unreachable git deps error [#4295](https://github.com/dependabot/dependabot-core/pull/4295) +- Elm: Fix failing tests [#4294](https://github.com/dependabot/dependabot-core/pull/4294) +- build(deps-dev): bump friendsofphp/php-cs-fixer from 3.0.0 to 3.2.1 in /composer/helpers/v2 [#4285](https://github.com/dependabot/dependabot-core/pull/4285) +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers [#4284](https://github.com/dependabot/dependabot-core/pull/4284) +- build(deps): bump composer/composer from 1.10.22 to 1.10.23 in /composer/helpers/v1 [#4283](https://github.com/dependabot/dependabot-core/pull/4283) +- npm: Handle .tar path dependency (@AlekhyaYalla) [#4246](https://github.com/dependabot/dependabot-core/pull/4246) +- build(deps-dev): bump jest in /npm_and_yarn/helpers [#4271](https://github.com/dependabot/dependabot-core/pull/4271) +- Gradle: Add support for `gradlePluginPortal()` (@zbynek) [#4268](https://github.com/dependabot/dependabot-core/pull/4268) +- Gradle: Support Gradle files with no top level build.gradle file (@zbynek) [#4256](https://github.com/dependabot/dependabot-core/pull/4256) + +## v0.162.2, 29 September 2021 + +- Ignore replaced dependencies in go.mod (@jerbob92) [#4140](https://github.com/dependabot/dependabot-core/pull/4140) +- Treat hyphens and underscores the same in Gradle versioning (@zbynek) [#4257](https://github.com/dependabot/dependabot-core/pull/4257) + +## v0.162.1, 20 September 2021 + +- Fix minor typos in changelog (@zbynek) [#4237](https://github.com/dependabot/dependabot-core/pull/4237) +- Bump golang from 1.17 to 1.17.1 [#4231](https://github.com/dependabot/dependabot-core/pull/4231) +- build(deps): bump github.com/dependabot/gomodules-extracted from 1.4.1 to 1.4.2 in /go_modules/helpers [#4235](https://github.com/dependabot/dependabot-core/pull/4235) +- Improved support `apply from` in gradle files (@zbynek) [#4155](https://github.com/dependabot/dependabot-core/pull/4155) +- Escape paths passed to VendorUpdater [#4221](https://github.com/dependabot/dependabot-core/pull/4221) +- bin/dry-run.rb requires a development container to run [#4215](https://github.com/dependabot/dependabot-core/pull/4215) +- Python: Upgrade pyenv to 2.0.6 (@pauloromeira) [#4207](https://github.com/dependabot/dependabot-core/pull/4207) +- handle terraform module versions with a 'v' prefix (@declan-fitzpatrick) [#4191](https://github.com/dependabot/dependabot-core/pull/4191) + +## v0.162.0, 7 September 2021 + +- Python: Raise resolvability error with explanation when update is not possible [#4206](https://github.com/dependabot/dependabot-core/pull/4206) +- chore: run builds on a regular basis to detect anomalies [#4185](https://github.com/dependabot/dependabot-core/pull/4185) +- fix: Parse multiple requirements from a poetry dependency [#4179](https://github.com/dependabot/dependabot-core/pull/4179) +- Bump terraform CLI from 1.0.0 to 1.0.6 [#4205](https://github.com/dependabot/dependabot-core/pull/4205) + +## v0.161.0, 1 September 2021 + +- Upgrade npm to 7.21.0 +- Pin Faraday to 1.7.0 +- chore: fix typo in documentation (@rethab) [#4172](https://github.com/dependabot/dependabot-core/pull/4172) +- build(deps): update commonmarker requirement from >= 0.20.1, < 0.23.0 to >= 0.20.1, < 0.24.0 + +## v0.160.1, 25 August 2021 + +- build(deps): bump github.com/dependabot/gomodules-extracted from 1.3.0 to 1.4.1 in /go_modules/helpers [#4157](https://github.com/dependabot/dependabot-core/pull/4157) +- Add a minimal test for go 1.17 module handling [#4159](https://github.com/dependabot/dependabot-core/pull/4159) +- Bump bundler from 2.2.20 to 2.2.25 [#4132](https://github.com/dependabot/dependabot-core/pull/4132) + +## v0.160.0, 18 August 2021 + +- Bump go from 1.16.7 to 1.17 (@obalunenko) [#4149](https://github.com/dependabot/dependabot-core/pull/4149) +- build(deps): bump golang.org/x/mod from 0.4.2 to 0.5.0 in /go_modules/helpers [#4139](https://github.com/dependabot/dependabot-core/pull/4139) + +## v0.159.2, 17 August 2021 + +- Bump go from 1.16.3 to 1.16.7 [#4145](https://github.com/dependabot/dependabot-core/pull/4145) +- Handle unreachable go module dependencies in LatestVersionFinder [#4142](https://github.com/dependabot/dependabot-core/pull/4142) +- Fix failing go modules tests [#4141](https://github.com/dependabot/dependabot-core/pull/4141) + +## v0.159.1, 12 August 2021 + +- gomod: Handle errors where go module dependencies are unreachable [#4130](https://github.com/dependabot/dependabot-core/pull/4130) + +## v0.159.0, 4 August 2021 + +- Remove go dep entirely (@jeffwidman) [#3538](https://github.com/dependabot/dependabot-core/pull/3538) +- Skip classifier when checking for internal dep (@honnix) [#4117](https://github.com/dependabot/dependabot-core/pull/4117) +- Improve argument sanitation [#4121](https://github.com/dependabot/dependabot-core/pull/4121) + +## v0.158.0, 3 August 2021 + +- Npm: Bump npm from 7.19.1 to 7.20.3 [#4110](https://github.com/dependabot/dependabot-core/pull/4110) +- Terraform: Pin fixture to range to prevent tests failing [#4115](https://github.com/dependabot/dependabot-core/pull/4115) +- build(deps-dev): bump eslint from 7.31.0 to 7.32.0 in /npm_and_yarn/helpers [#4112](https://github.com/dependabot/dependabot-core/pull/4112) +- build(deps): bump @npmcli/arborist from 2.7.1 to 2.8.0 in /npm_and_yarn/helpers [#4098](https://github.com/dependabot/dependabot-core/pull/4098) +- build(deps): bump npm from 6.14.13 to 6.14.14 in /npm_and_yarn/helpers [#4099](https://github.com/dependabot/dependabot-core/pull/4099) + +## v0.157.2, 28 July 2021 + +- fix(terraform): exclude path source types in update check [#4097](https://github.com/dependabot/dependabot-core/pull/4097) +- Document pinned OTP version [#4092](https://github.com/dependabot/dependabot-core/pull/4092) + +## v0.157.1, 27 July 2021 + +- Upgrade elixir to v1.12.2 [#4093](https://github.com/dependabot/dependabot-core/pull/4093) +- Revert "Elixir version upgrades" [#4091](https://github.com/dependabot/dependabot-core/pull/4091) + +## v0.157.0, 26 July 2021 + +- Elixir version upgrades (@baseballlover723) [#4089](https://github.com/dependabot/dependabot-core/pull/4089) + +## v0.156.10, 26 July 2021 +- Make native-mt and agp version types for Maven and Gradle (@greysteil) [#4077](https://github.com/dependabot/dependabot-core/pull/4077) +- Python: Upgrade pyenv to 2.0.4 [#4086](https://github.com/dependabot/dependabot-core/pull/4086) +- build(deps-dev): bump phpstan/phpstan from 0.12.92 to 0.12.93 in /composer/helpers/v2 [#4067](https://github.com/dependabot/dependabot-core/pull/4067) +- build(deps-dev): bump phpstan/phpstan from 0.12.92 to 0.12.93 in /composer/helpers/v1 [#4068](https://github.com/dependabot/dependabot-core/pull/4068) + +## v0.156.9, 20 July 2021 + +- build(deps): bump @npmcli/arborist from 2.7.0 to 2.7.1 in /npm_and_yarn/helpers [#4055](https://github.com/dependabot/dependabot-core/pull/4055) +- build(deps-dev): bump eslint from 7.30.0 to 7.31.0 in /npm_and_yarn/helpers [#4060](https://github.com/dependabot/dependabot-core/pull/4060) +- npm: prevent scoped registries becoming global [#4061](https://github.com/dependabot/dependabot-core/pull/4061) + +## v0.156.8, 15 July 2021 + +- Terraform: ignore symlinks in file fetcher [#4053](https://github.com/dependabot/dependabot-core/pull/4053) +- Bump npm from 7.10.0 to 7.19.1 [#4052](https://github.com/dependabot/dependabot-core/pull/4052) +- Dry-run: cache cloned repos [#4050](https://github.com/dependabot/dependabot-core/pull/4050) + +## v0.156.7, 15 July 2021 + +- Terraform: support updating local path modules [#4048](https://github.com/dependabot/dependabot-core/pull/4048) +- build(deps): bump cython from 0.29.23 to 0.29.24 in /python/helpers [#4047](https://github.com/dependabot/dependabot-core/pull/4047) +- build(deps): bump @npmcli/arborist from 2.6.4 to 2.7.0 in /npm_and_yarn/helpers [#4046](https://github.com/dependabot/dependabot-core/pull/4046) + +## v0.156.6, 13 July 2021 + +- Terraform: handle mixed case providers [#4044](https://github.com/dependabot/dependabot-core/pull/4044) + +## v0.156.5, 12 July 2021 + +- fix(poetry): Detect relative project paths [#4018](https://github.com/dependabot/dependabot-core/pull/4018) +- Add Forbidden error type to Azure client (@wolf-cola) [#4029](https://github.com/dependabot/dependabot-core/pull/4029) +- build(deps-dev): bump phpstan/phpstan from 0.12.90 to 0.12.92 in /composer/helpers/v2 [#4036](https://github.com/dependabot/dependabot-core/pull/4036) +- build(deps-dev): bump jest from 27.0.5 to 27.0.6 in /npm_and_yarn/helpers [#4003](https://github.com/dependabot/dependabot-core/pull/4003) +- build(deps-dev): bump eslint from 7.29.0 to 7.30.0 in /npm_and_yarn/helpers [#4021](https://github.com/dependabot/dependabot-core/pull/4021) +- build(deps-dev): bump phpstan/phpstan from 0.12.90 to 0.12.92 in /composer/helpers/v1 [#4037](https://github.com/dependabot/dependabot-core/pull/4037) +- Gomod: Handle unrecognized import path error [#4016](https://github.com/dependabot/dependabot-core/pull/4016) +- Fix for Azure client trying to parse 401 responses (@wolf-cola) [#4012](https://github.com/dependabot/dependabot-core/pull/4012) + +## v0.156.4, 30 June 2021 + +- build(deps): bump @npmcli/arborist from 2.6.3 to 2.6.4 in /npm_and_yarn/helpers [#3988](https://github.com/dependabot/dependabot-core/pull/3988) +- build(deps-dev): update rubocop requirement from ~> 1.17.0 to ~> 1.18.0 in /common [#4004](https://github.com/dependabot/dependabot-core/pull/4004) +- fix(Maven): Add support for updating Maven extensions.xml files (@britter) [#3366](https://github.com/dependabot/dependabot-core/pull/3366) + +## v0.156.3, 29 June 2021 + +- Python: bump poetry from 1.1.6 to 1.1.7 in /python/helpers [#3996](https://github.com/dependabot/dependabot-core/pull/3996) +- Python: bump pip from 21.1.2 to 21.1.3 in /python/helpers [#3997](https://github.com/dependabot/dependabot-core/pull/3997) +- PR Updater: Handle required status checks [#3998](https://github.com/dependabot/dependabot-core/pull/3998) + +## v0.156.2, 25 June 2021 + +- poetry: skip path and url dependencies [#3991](https://github.com/dependabot/dependabot-core/pull/3991) +- Terraform: Prevent `terraform init` from initializing backends (@hfurubotten) [#3986](https://github.com/dependabot/dependabot-core/pull/3986) + +## v0.156.1, 24 June 2021 + +- Terraform: Configure git for `terraform init` and capture errors [#3983](https://github.com/dependabot/dependabot-core/pull/3983) +- build(deps-dev): update rubocop requirement from ~> 1.16.0 to ~> 1.17.0 in /common [#3912](https://github.com/dependabot/dependabot-core/pull/3912) + +## v0.156.0, 23 June 2021 + +- Create changelog from merge commits [#3642](https://github.com/dependabot/dependabot-core/pull/3642) +- Terraform: always clone repository contents [#3978](https://github.com/dependabot/dependabot-core/pull/3978) +- build(deps): bump pip-tools from 6.1.0 to 6.2.0 in /python/helpers [#3974](https://github.com/dependabot/dependabot-core/pull/3974) +- Hex: Adds support for sub-projects without the need for umbrella applications (@gjsduarte) [#3944](https://github.com/dependabot/dependabot-core/pull/3944) + +## v0.155.1, 23 June 2021 + +- Terraform: fix module updates with a lockfile +- nuget: handle RepositoryDetails without BaseAddress +- bundler: GemspecSanitizer replace interpolated strings +- build(deps-dev): bump jest in /npm_and_yarn/helpers + +## v0.155.0, 22 June 2021 + +- Go: add security advisories +- Devcontainer: do not rename gemspec +- docker-dev-shell: do not rename gemspec + +## v0.154.5, 22 June 2021 + +- Terraform: install modules when updating lockfile + +## v0.154.4, 22 June 2021 + +- Terraform: handle nested module sources +- Common: refactor filter_vulnerable_version into a separate module +- Bundler: ignore invalid auth_uri + +## v0.154.3, 21 June 2021 + +- Terraform: handle missing source +- Terraform: handle unreachable private module proxy +- Terraform: handle dependencies without a namespace +- fix: Fetches upload-pack using git if http fails +- chore: shellcheck scripts +- chore: Replace wget with curl @PeterDaveHello +- chore: Double quote shell variables in Dockerfile @PeterDaveHello +- Returns basename and relative path in CodeCommit file fetcher @lorengordon +- build(deps-dev): bump phpstan/phpstan in /composer/helpers/v1 and /composer/helpers/v2 +- build(deps): update commonmarker requirement from >= 0.20.1, < 0.22.0 to >= 0.20.1, < 0.23.0 +- build(deps-dev): bump eslint in /npm_and_yarn/helpers +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers + +## v0.154.2, 17 June 2021 + +- Terraform: Handle 401 registry responses +- GitHub actions: Handle no latest version found +- Python: Fix ruby 2.7 deprecations +- Double quote variables in shellscript @PeterDaveHello +- Add `--no-install-recommends` to all `apt-get install` in Dockerfile @PeterDaveHello + +## v0.154.1, 16 June 2021 + +- Ruby: Fix 2.7 deprecation warnings in rubygems +- Bundler: Run native helper specs + +## v0.154.0, 15 June 2021 + +- Update ruby from 2.6 to 2.7 +- Bundler: add missing specs from bundler1 and load bundler2 fixtures +- Dockerfile improvements @PeterDaveHello + - Set SHELL option for shell pipe + - Add missing `-y` for apt-get install + - Fix npm cache clean up + - Add missing apt lists clean up + +## v0.153.0, 14 June 2021 + +- Bundler: Upgrade rubygems to 3.2.20 and bundler to 2.2.20 +- Python: Upgrade pyenv to 2.0.1 to add support for Python 3.9.5 +- build(deps-dev): bump phpstan/phpstan in /composer/helpers/v1 +- build(deps-dev): bump phpstan/phpstan in /composer/helpers/v2 +- build(deps): bump composer/composer in /composer/helpers/v2 + +## v0.152.1, 11 June 2021 + +- Tests: Allow profiling tests with stackprof when tagged +- Throw an error when using the deprecated terraform provider syntax, include upgrade instructions +- Update `bump-version` with instructions to checkout the new branch + +## v0.152.0, 10 June 2021 + +- Python: Upgrade pip to 21.1.2 +- Python: Upgrade pip-tools to 6.1.0 +- Python: Drop python 2.x support +- Python: Upgrade pipenv to 2021.5.29 +- Terraform: Add support for lockfiles +- Terraform: Upgrade and pin Terraform to version 1.0.0 + +## v0.151.1, 7 June 2021 + +fix(npm): Prevent unnecessary hash pinning in lock file constraint + +## v0.151.0, 7 June 2021 + +- Pin erlang to OTP 23 until we can resolve OTP 24 warning issues +- build(deps-dev): bump friendsofphp/php-cs-fixer in /composer/helpers/v2 + +## v0.150.0, 7 June 2021 + +- build(deps): bump composer/composer from 2.0.14 to 2.1.1 in /composer/helpers/v2 +- build(deps-dev): bump jest in /npm_and_yarn/helpers +- build(deps-dev): bump eslint in /npm_and_yarn/helpers +- build(deps-dev): bump prettier in /npm_and_yarn/helpers +- build(deps): bump dependabot/fetch-metadata from 1.0.2 to 1.0.3 +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers + +## v0.149.5, 2 June 2021 + +- build(deps): bump detect-indent in /npm_and_yarn/helpers +- chore(deps): bump composer/composer in /composer/helpers/v2 +- chore(deps-dev): update rubocop requirement from ~> 1.15.0 to ~> 1.16.0 +- refactor(Terraform): raise PrivateSourceAuthenticationFailure instead of DependabotError +- build(deps-dev): bump jest in /npm_and_yarn/helpers +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers + +## v0.149.4, 1 June 2021 + +- fix(Terraform): use service discovery protocol +- fix(Terraform): parse optional hostname from module/provider source address +- Bump composer/composer from 2.0.12 to 2.0.14 in /composer/helpers/v2 +- poetry: support pyproject.toml indentation + +## v0.149.3, 28 May 2021 + +- Bundler: handle required ruby version ranges in gemspecs +- Bundler: Bump to latest ruby versions +- Elixir: Bump version from 1.10.4 -> 1.11.4 +- gomod: UpdateChecker - handle invalid module path error on update +- Composer: handle git clone error in lockfile updater +- Bump eslint from 7.26.0 to 7.27.0 in /npm_and_yarn/helpers + +## v0.149.2, 27 May 2021 + +- Tests: avoid squatted repositories + +## v0.149.1, 27 May 2021 + +- Bundler: Fix ruby version patch for 2.2.18 +- Bundler: Update bundler to 2.2.18 + +## v0.149.0, 26 May 2021 + +- Terraform: Use registry credentials + +## v0.148.10, 26 May 2021 + +- Yarn: use .yarnrc file if present +- npm: handle latest version requirement + +## v0.148.9, 26 May 2021 + +- Terraform: Do not set dependency.version for version ranges +- Terraform: Parse lockfiles to get exact version when present + +## v0.148.8, 25 May 2021 + +- Composer: handle unreachable git vcs source +- Terraform: handle implicit (v0.12 style) provider sources + +## v0.148.7, 25 May 2021 + +- npm: Handle multiple sources in the update checker +- Composer: Handle invalid composer.json + +## v0.148.6, 21 May 2021 + +- Handle nil dependency version when raising AllVersionsIgnored + +## v0.148.5, 21 May 2021 + +- Terraform: Fix updating multiple providers +- Dockerfile: split up native helper build steps + +## v0.148.4, 21 May 2021 + +- Terraform: Improve updating provider requirements +- Bundler 2: No longer bump yanked gems when updating dependency +- Upgrade bundler to 2.2.17 +- Bump @npmcli/arborist from 2.5.0 to 2.6.0 in /npm_and_yarn/helpers + +## v0.148.3, 19 May 2021 + +- fix(common): skip validation on non-git sources +- fix(npm/yarn): prefer private registries over public ones + +## v0.148.2, 19 May 2021 + +- Terraform: Fix finding metadata for providers + +## v0.148.1, 19 May 2021 + +- npm: Handle nested workspace dependencies installed in the top-level + `node_modules` folder + +## v0.148.0, 19 May 2021 + +- Terraform: Support provider updates +- Terraform: Extract RegistryClient for communicating with terraform registry +- Go modules: Replace custom helper with `go get -d lib@version` @jeffwidman + +## v0.147.1, 18 May 2021 + +- Terraform: remove legacy terraform feature flag +- Terraform: Clean up support for legacy terragrunt files +- Hex: Fix version resolver specs +- Update rubocop requirement from ~> 1.14.0 to ~> 1.15.0 in /common +- Bump phpstan/phpstan from 0.12.85 to 0.12.88 in /composer/helpers/v1 +- Bump phpstan/phpstan from 0.12.85 to 0.12.88 in /composer/helpers/v2 +- build(deps-dev): bump eslint in /npm_and_yarn/helpers +- build(deps-dev): bump prettier in /npm_and_yarn/helpers +- build(deps): bump flake8 from 3.9.1 to 3.9.2 in /python/helpers +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers + +## v0.147.0, 13 May 2021 + +- Switch HCL2 parser to be the default for Terraform. Supports Terraform v0.12+ [(#3716)](https://github.com/dependabot/dependabot-core/pull/3716) + +## v0.146.1, 12 May 2021 + +- Actions: skip equivalent shorter semver tags, such as `v2` and `v2.1.0` +- Python: Run all pip-compile commands with options @JimNero009 +- Terraform (prerelease): Handle terragrunt HCL files + +## v0.146.0, 10 May 2021 + +- go_modules: Refactor go module version finder specs +- all: Filter lower versions when checking ignored versions +- Terraform: Document and improve coverage for RequirementsUpdater +- Revert "docker: FileParser consider image prefix/suffixes as unique" + +## v0.145.4, 10 May 2021 + +- Actions: accept semver versions +- Actions: detect workflow steps pinned to semver versions + +## v0.145.3, 7 May 2021 + +- go_modules: Gracefully handle +incompatible versions when checking for updates + +## v0.145.2, 7 May 2021 + +- Nuget: Handle paginated v2 nuget api responses +- maven: allow security updates to multi-dependency properties +- build(deps): bump lodash +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers +- build(deps-dev): update rubocop requirement from ~> 1.13.0 to ~> 1.14.0 + +## v0.145.1, 5 May 2021 + +- go_modules: don't filter the current version +- terraform: move fixtures to project folders +## v0.145.0, 5 May 2021 + +- go_modules: support version ignores +- Dev env: mount go helper source in dev shell +- docker: FileParser unique suffixes +- go_modules: helper updates +- GitHub PullRequestCreator: prepend refs/ +- build(deps): bump github.com/dependabot/gomodules-extracted + +## v0.144.0, 5 May 2021 + +- Elm: Drop support for Elm 0.18 +- Common: Handle nil dependency version when generating ignored versions +- Python: allow comments when parsing setup.cfg +- go_modules: stub consistently and ignore invalid modules +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers +- build(deps-dev): bump friendsofphp/php-cs-fixer in /composer/helpers/v1 +- build(deps-dev): bump friendsofphp/php-cs-fixer in /composer/helpers/v2 + +## v0.143.6, 30 April 2021 + +- Common: version-update:semver-major ignores all major version updates +- Document how to run tests within the dev docker container +- go_modules: Make error output more idiomatic +- Create CODE_OF_CONDUCT.md +- Common: IgnoreCondition: handle multi-length semver ranges +- Common: IgnoreCondition: don't ignore current version when ignoring patches + +## v0.143.5, 29 April 2021 + +- gradle: only treat commit-like versions as git repositories +- dry-run: change SECURITY_ADVISORIES to kebab-case +- go_modules: helper improvements @jeffwidman +- go_modules: require go.16 for helpers @jeffwidman +- go_modules: use go1.16.3 @jeffwidman +- docker: handle versions generated with `git describe --tags --long` @kd7lxl +- build(deps): bump composer/composer in /composer/helpers/v1 +- build(deps-dev): bump phpstan/phpstan in /composer/helpers + +## v0.143.4, 26 April 2021 + +- Common: Add IgnoreCondition.security_updates_only, which disables version updates filtering +- build(deps-dev): bump eslint-config-prettier in /npm_and_yarn/helpers +- build(deps-dev): bump eslint in /npm_and_yarn/helpers + +## v0.143.3, 23 April 2021 + +- Common: Do not transform update_types in IgnoreCondition +- build(deps): bump @npmcli/arborist in /npm_and_yarn/helpers + +## v0.143.2, 22 April 2021 + +- Dependabot::Config::IgnoreCondition support dependency wildcards +- Dependabot::Config::IgnoreCondition support `update-types` +- go_modules: clarify comment @jeffwidman + +## v0.143.1, 21 April 2021 + +- Gradle/Maven: Handle ruby style requirements with maven version +- Bundler: Add missing requirement_class for bundler latest version checker +- Add IgnoreCondition#dependency_name +- Dependabot::Config::File parse ignore_conditions +- Dependabot::Config::File parse commit_message_options + +## v0.143.0, 21 April 2021 + +- Python: Add support for updating `setup.cfg` files @honnix +- Gomod: Run `go mod tidy` with flag to allow errors +- Handle ruby and package manager specific version requirements from ignore conditions +- build(deps): bump poetry from 1.1.4 to 1.1.6 in /python/helpers +- build(deps-dev): update rubocop requirement from ~> 1.12.0 to ~> 1.13.0 +- build(deps-dev): bump friendsofphp/php-cs-fixer in /composer/helpers/v1 +- build(deps-dev): bump friendsofphp/php-cs-fixer in /composer/helpers/v2 +- build(deps-dev): bump phpstan/phpstan in /composer/helpers/v1 +- build(deps-dev): bump phpstan/phpstan in /composer/helpers/v2 +- dry-run: fetch ignore conditions and commit_message_options from `dependabot.yml` config file +- dry-run: set ignore conditions from `IGNORE_CONDITIONS` env +- Chore: Refactor `new_branch_name` function in branch_namer @milind009 +- Bundler: Remove unused `using_bundler2` arg from v1 helpers + +## v0.142.1, 16 April 2021 + +- Update npm from 7.7.4 to 7.10.0 +- build(deps): bump flake8 from 3.9.0 to 3.9.1 in /python/helpers +- Azure: Raise PullRequestUpdateFailed error when failing to update PR @milind009 +- Fix Dockerfile.development +- build(deps): bump cython from 0.29.22 to 0.29.23 in /python/helpers + +## v0.142.0, 15 April 2021 + +- Dockerfile: set WORKDIR to /home/dependabot to avoid permission errors when + consumers of the dependabot-core image run bundle install @baseballlover723 +- Dockerfile: Cache composer installs & install ca-certificates +- Dockerfile: shallow clone pyenv +- npm/yarn: Always use registry source when available +- build(deps-dev): bump eslint-config-prettier in /npm_and_yarn/helpers + +## v0.141.1, 13 April 2021 + +- Remove bundler/v1/.bundle +- Remove helpers ignore +- Remove python versions from ci image and split copy +- build(deps): bump npm from 6.14.12 to 6.14.13 in /npm_and_yarn/helpers +- fix(go mod): capture module mismatch error + +## v0.141.0, 12 April 2021 + +- Dockerfile: create a `dependabot` user and drop privileges + This is a potentially BREAKING change for consumers of the `dependabot/dependabot-core` docker image. +- Maven/Gradle: Add option to use GitLab access token for authentication against maven repositories @gringostar +- common: raise Dependabot::OutOfDisk on more out of space errors +- Bump eslint from 7.23.0 to 7.24.0 + +## v0.140.3, 9 April 2021 + +- fix(Go mod): detect when remote end hangs up + +## v0.140.2, 8 April 2021 + +- Go mod: Handle repo not found errors projects https://github.com/dependabot/dependabot-core/pull/3456 + +## v0.140.1, 8 April 2021 + +- Python: Disabled poetry experimental new installer @honnix +- GitLab: Implement delete/create action in client @jerbob92 + +## v0.140.0, 7 April 2021 + +- Bundler: Detecting and using the correct major Bundler version is now enabled by default +- Python: Add versions 3.8.9, 3.9.3 and 3.9.4 +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v1 +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v2 + +## v0.139.2, 6 April 2021 + +- Cargo: fix error when upgrading to a version with a build annotation (e.g. `0.7.0+zstd.1.4.9`) +- Maven: fix error when comparing string and integer versions +- Generate alternatives for every git source (thanks @jerbob92) +- CI: performance improvements +- Bump phpstan/phpstan from 0.12.82 to 0.12.83 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.82 to 0.12.83 in /composer/helpers/v1 +- Bump composer/composer from 2.0.11 to 2.0.12 in /composer/helpers/v2 +- Bump composer/composer from 1.10.20 to 1.10.21 in /composer/helpers/v1 +- Bump @npmcli/arborist from 2.2.9 to 2.3.0 in /npm_and_yarn/helpers + +## v0.139.1, 30 March 2021 + +- Pull Requests: Fix GitHub redirect for www.github.com links +- Pull Requests: Sanitize team mentions +- Bundler 2 [Beta]: Add test for bundler dependency + +## v0.139.0, 30 March 2021 + +- Bundler [Beta]: Detect and run Bundler V1 or V2 based on Gemfile.lock + - Requires `options: { bundler_2_available: true }` to be passed to Bundler classes for this release +- Dockerfile: promote software-properties-common + +## v0.138.7, 30 March 2021 + +- Go mod: Handle multi-line error messages +- Bump golang.org/x/mod from 0.4.1 to 0.4.2 in /go_modules/helpers +- Update rubocop requirement from ~> 1.11.0 to ~> 1.12.0 in /common +- Bump flake8 from 3.8.4 to 3.9.0 in /python/helpers +- Bump eslint from 7.22.0 to 7.23.0 in /npm_and_yarn/helpers +- Bundler [Prerelease]: Bump bundler to 2.2.15 +- Bundler: Use project fixtures +- Docs: change ci url @flaxel + +## v0.138.6, 26 March 2021 + +- chore: export LOCAL_GITHUB_ACCESS_TOKEN to docker dev container +- fix: Raise resolvability error when pseudo version does not match version control +- test: Add a helper method to load bundler fixtures by version +- test: Explicitly raise if attempting to load a missing project fixture +- test: Project fixtures for UpdateChecker spec + +## v0.138.5, 26 March 2021 + +- Maven/Gradle: Treat dev and pr as pre-releases for Gradle/Maven +- Bundler v2 [pre-release]: Add and test jfrog source helper +- Cargo: Update Rust to 1.51.0 (thanks @CryZe) +- Bump npm from 6.14.11 to 6.14.12 in /npm_and_yarn/helpers +- Internal: bump-version: re-tag the release notes ref +- Azure: adding azure pr updater reference in pr updater common class + +## v0.138.4, 25 March 2021 + +- Docker: fix invalid Accept header when checking for updates +- Bundler: fix invalid requirement replacement when using `!=` filters +- Bundler [Prerelease]: Add UpdateChecker for Bundler 2 +- Bundler [Prerelease]: Add version resolver for Bundler 2 +- Bundler [Prerelease]: Add file updater for Bundler 2 +- Dependabot::PullRequestCreator::MessageBuilder::new - github_redirection_service is a required argument +- CI: Fix flaky npm spec +- CI: Extend npm retries and max attempts +- CI: Skip coverage reports +- Update npm from 7.6.1 to 7.7.0 + +## v0.138.3, 24 March 2021 + +- Docker: Improve handling of tags with prefixes or suffixes +- Bump @npmcli/arborist from 2.2.6 to 2.2.9 in /npm_and_yarn/helpers +- Bump eslint from 7.21.0 to 7.22.0 in /npm_and_yarn/helpers +- Bundler: fix deprecated --without flag in build +- Bundler [Prerelease]: Add conflicting dependency resolver for Bundler 2 +- Bundler: Avoid subtle runtime failures by raising if bundler is improperly invoked + +## v0.138.2, 23 March 2021 + +- npm: support private registries using lowercase URI components (e.g. `%40dependabot%2fdependabot-core`) +- Bundler: [Prerelease] Add a file parser for Bundler 2 +- Nuget: add support for disablePackageSources in NuGet.Config (@AshleighAdams) +- Bump phpstan/phpstan from 0.12.81 to 0.12.82 +- Bump friendsofphp/php-cs-fixer to 2.18.4 +- CI: reduce disk space + +## v0.138.1, 17 March 2021 + +- Bundler: Add instrumentation to capture the bundler version being used +- Bundler: [Prerelease] Add a stubbed out native helper for Bundler 2 +- Bundler: [Prerelease] Allow the v2 native helper to be invoked via an options argument + +## v0.138.0, 16 March 2021 + +- Go: Bump golang to v1.16.2 + +## v0.137.2, 16 March 2021 + +- Bundler: Fix permission error when vendoring gems +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v1 +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v2 + +## v0.137.1, 15 March 2021 + +- Bundler: Install dependabot-core's gems using Bundler v2 (unused for updates) + +## v0.137.0, 15 March 2021 + +- Bump npm from 7.5.4 to 7.6.1 +- Python: Add python versions 3.9.2, 3.8.8, 3.7.10 and 3.6.13 +- Bundler: Run v1 native helpers with bundler v1 +- Bump composer/composer from 2.0.10 to 2.0.11 in /composer/helpers/v2 +- Bump eslint-config-prettier from 8.0.0 to 8.1.0 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.78 to 0.12.81 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.78 to 0.12.81 in /composer/helpers/v1 + +## v0.136.0, 8 March 2021 + +- Bundler: Run Bundler v1 native helpers with an explicit version setting the + stage for Bundler v2 support (take 2) #3223 +- Bundler: Fix gemspec sanitization bug when heredoc has methods chained onto it + #3220 + +## v0.135.0, 4 March 2021 + +- Gracefully handle cargo version conflicts #3213 +- Pull request updater for azure client #3153 (@milind009) + +## v0.134.2, 3 March 2021 + +- Revert: Run Bundler v1 native helpers with an explicit version +- Update rubocop requirement from ~> 1.10.0 to ~> 1.11.0 in /common +- Bump @npmcli/arborist from 2.2.4 to 2.2.6 in /npm_and_yarn/helpers + +## v0.134.1, 2 March 2021 + +- Run Bundler v1 native helpers with an explicit version setting the stage for + Bundler v2 support + +## v0.134.0, 1 March 2021 + +- Introduce `Dependabot::PullRequestCreator::Message` as an alternative to `Dependabot::PullRequestCreator::MessageBuilder` +- Test: convert Bundler specs to projects +- Test: fix npm6 fixture +- Bump composer/composer from 2.0.9 to 2.0.10 in /composer/helpers/v2 +- Bump @npmcli/arborist from 2.2.3 to 2.2.4 in /npm_and_yarn/helpers +- Bump eslint-config-prettier from 7.2.0 to 8.0.0 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.77 to 0.12.78 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.77 to 0.12.78 in /composer/helpers/v1 +- Bump cython from 0.29.21 to 0.29.22 in /python/helpers + +## v0.133.6, 22 February 2021 + +- npm: Use CLI for peer dep conflicts, and default to it without lockfile +- Bump @npmcli/arborist from 2.2.2 to 2.2.3 in /npm_and_yarn/helpers + +## v0.133.5, 19 February 2021 + +- Python: Raise UnexpectedExternalCode if `reject_external_code: true`, regardless of the update involving external code +- Hex: Raise UnexpectedExternalCode if `reject_external_code: true`, regardless of the update involving external code +- JS: fix npm file updater spec + +## v0.133.4, 18 February 2021 + +- Elixir: support projects using Nerves extensions (@fhunleth and @cblavier) +- Common: Insert zero-width space in @mentions when sanitizing GitHub pull request descriptions +- Azure: raise NotFound error when response status code is 400 for fetch_commit (@milind009) +- JS: Switch from yarn to npm for helper deps +- JS: Convert spec fixtures to project based +- Bump phpstan/phpstan from 0.12.74 to 0.12.77 in /composer/helpers/v1 +- Bump phpstan/phpstan from 0.12.76 to 0.12.77 in /composer/helpers/v2 +- Update rubocop requirement from ~> 1.9.0 to ~> 1.10.0 in /common + +## v0.133.3, 16 February 2021 + +- common: when detecting changes in vendored dependencies, assume resources are binary +- Bump phpstan/phpstan from 0.12.74 to 0.12.76 in /composer/helpers/v2 +- Bump eslint from 7.19.0 to 7.20.0 in /npm_and_yarn/helpers +- Bump @npmcli/arborist from 2.2.1 to 2.2.2 in /npm_and_yarn/helpers +- Only run flake8 on python helpers folder +- Add option to profile dry-run using Stackprof +- Fix go_modules flaky spec accessing archive.org +- Restore npm6/7 yanked version spec +- npm: Convert FileParser specs to project fixtures + +## v0.133.2, 11 February 2021 + +- Docker: Fix media types in Accept header for Docker Registry +- Convert LockfileParserSpec to use project based fixtures + +## v0.133.1, 10 February 2021 + +- npm: fix npm 7 workspace bug when updating nested packages +- npm: correctly parse npm 7 version from package dependencies +- npm: Refactor NpmLockfileUpdater +- Update npm from 7.5.2 to 7.5.3 +- Bump @npmcli/arborist from 2.2.0 to 2.2.1 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.71 to 0.12.74 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.71 to 0.12.74 in /composer/helpers/v1 + +## v0.133.0, 9 February 2021 + +- Bundler: Raise UnexpectedExternalCode if `reject_external_code: true` and the update involves external code + +## v0.132.0, 8 February 2021 + +- npm: Add support for updating npm 7 lockfiles + +## v0.131.3, 8 February 2021 + +- Nuget: handle version ranges in VersionFinder + +## v0.131.2, 5 February 2021 + +- Maven: handle invalid pom references +- Maven: Raise DependencyFileNotResolvable when invalid repo is specified +- Bump @npmcli/arborist from 2.1.1 to 2.2.0 in /npm_and_yarn/helpers + +## v0.131.1, 4 February 2021 + +- Composer: handle invalid version string +- Composer: Don't raise when adding temp platform extensions +- Composer: Handle version constraints with both caret and dev postfix +- Docker: Use the correct Docker digest when checking for updates + +## v0.131.0, 4 February 2021 + +- Composer: handle unreachable path vcs source +- Nuget: Parse floating notation when used in range +- Nuget: Ignore `Remove` ProjectReferences +- Gradle Kotlin DSL: Add Support for Named URL Parameter in Maven Repository (@hfhbd) +- Python: Add python 3.8.7 (@Parnassius) +- npm: Refactor specs to use project based fixtures +- Bump composer/composer from 1.10.19 to 1.10.20 in /composer/helpers/v1 +- Bump composer/composer from 2.0.8 to 2.0.9 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.68 to 0.12.71 in /composer/helpers/v1 and /composer/helpers/v2 +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v2 and /composer/helpers/v1 +- Update simplecov-console requirement from ~> 0.8.0 to ~> 0.9.1 +- Bump @npmcli/arborist from 2.0.6 to 2.1.1 in /npm_and_yarn/helpers +- Update rubocop requirement from ~> 1.8.0 to ~> 1.9.0 in /common + +## v0.130.3, 25 January 2021 + +- Extract yarn/npm lockfile updater specs from FileUpdater specs +- Bump @npmcli/arborist from 2.0.5 to 2.0.6 in /npm_and_yarn/helpers +- Gomod: go-1.15.7 +- Composer: Check for explicit composer plugin version before invalid plugins +- Update eslint prettier extension +- Fix JS debugging in vscode + +## v0.130.2, 19 January 2021 + +- gradle: repository url by assignment +- Bump pip-tools from 5.4.0 to 5.5.0 +- Bump eslint from 7.17.0 to 7.18.0 in /npm_and_yarn/helpers +- Bump golang.org/x/mod from 0.4.0 to 0.4.1 in /go_modules/helpers +- Bump @npmcli/arborist from 2.0.3 to 2.0.5 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.66 to 0.12.68 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.66 to 0.12.68 in /composer/helpers/v1 + +## v0.130.1, 14 January 2021 + +- npm: detect npm v7 lockfiles +- npm: Install npm v7 (unused) alongside npm v6 +- JS: Upgrade node to v14.15.4 +- Common: Added require "set" to utils.rb (@JohannesEH) +- Sanitize `@mentions` by wrapping them in codeblocks preventing notifications when replying to PR email notifications + +## v0.130.0, 13 January 2021 + +- npm: Support GitLab format npm registry (@danoe) +- npm: move native helpers to npm6 namespace +- Python: Use release version of pyenv (@ulgens) +- Gradle: Add support for Kotlin Plugins (@busches) +- Composer: Use composer v1 when any of the requirements are invalid on v2 +- docker-dev-shell: exclude dry-run files +- Bump @npmcli/arborist from 2.0.2 to 2.0.3 in /npm_and_yarn/helpers +- Bump npm from 6.14.10 to 6.14.11 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.64 to 0.12.66 in /composer/helpers/v1 and /composer/helpers/v2 +- Update rubocop requirement from ~> 1.7.0 to ~> 1.8.0 in /common + +## v0.129.5, 7 January 2021 + +- Bundler: support ruby 2.7 and 3.0 version requirements in gemspecs +- Update parser requirement from ~> 2.5 to >= 2.5, < 4.0 in /common + +## v0.129.4, 6 January 2021 + +- go_modules: raise Dependabot::GitDependenciesNotReachable for dependencies missing from github.com +- go_modules: fix regression when parsing go.mod files without dependencies +- Bitbucket: support for PR creation (@iinuwa) + +## v0.129.3, 5 January 2021 + +- Bump eslint-plugin-prettier from 3.3.0 to 3.3.1 in /npm_and_yarn/helpers +- Gradle: Handle missing required manifest file +- Actions: Accept shortref hashes + +## v0.129.2, 4 January 2021 + +- go_modules: return tidied `go.mod` contents directly +- go_modules: fix nested module detection from a monorepo root +- go_modules: stop parsing indirect dependencies (previous: parsed but not updated) +- gradle: fix whitespace matching in settings (@bountin) +- Add token support for BitBucket (@iinuwa) +- Add retries for Azure client (@GiriB) +- CI: Add Python flake8 linting +- Bundler: fix bundler gem when invoked as standalone gem +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v2 +- Bump friendsofphp/php-cs-fixer in /composer/helpers/v1 +- Bump node-notifier from 8.0.0 to 8.0.1 in /npm_and_yarn/helpers +- Update rubocop requirement from ~> 1.6.0 to ~> 1.7.0 in /common +- Update simplecov requirement from ~> 0.20.0 to ~> 0.21.0 in /common +- Bump eslint from 7.16.0 to 7.17.0 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.63 to 0.12.64 in /composer/helpers/v2 +- Bump phpstan/phpstan from 0.12.63 to 0.12.64 in /composer/helpers/v1 + +## v0.129.1, 21 December 2020 + +- Bump phpstan/phpstan from 0.12.59 to 0.12.63 +- Bump friendsofphp/php-cs-fixer +- Composer: Verify if composer name is compatible with v2 +- Python: Upgrade Python version to 3.9.1 (@ulgens) +- Bump npm from 6.14.9 to 6.14.10 in /npm_and_yarn/helpers +- Bump eslint from 7.15.0 to 7.16.0 in /npm_and_yarn/helpers +- Sanitize creds from DependabotError +- Bump composer/composer from 1.10.16 to 1.10.19 in /composer/helpers/v1 +- Bump pip from 20.3.1 to 20.3.3 in /python/helpers +- Bump @npmcli/arborist from 2.0.1 to 2.0.2 in /npm_and_yarn/helpers +- go_modules: limit GitDeps to repo +- go_modules: fix test warning + +## v0.129.0, 15 December 2020 + +- Composer: Support composer v2 alongside v1 (Thanks for helping out @WyriHaximus) + +## v0.128.2, 14 December 2020 + +- go_modules: fix regression with stubbing local replace paths + +## v0.128.1, 14 December 2020 + +- go_modules: only stub modules outside this repo + +## v0.128.0, 14 December 2020 + +- Gradle: Support Kotlin manifest files (thanks, @shakhar!) + +## v0.127.1, 14 December 2020 + +- Bump wheel from 0.36.1 to 0.36.2 in /python/helpers +- Bump eslint-plugin-prettier from 3.2.0 to 3.3.0 in /npm_and_yarn/helpers +- Bump @npmcli/arborist from 2.0.0 to 2.0.1 in /npm_and_yarn/helpers + +## v0.127.0, 11 December 2020 + +- go_modules: raise Dependabot::OutOfDisk error when we're fairly sure that the failure occurred due to running out of disk space +- Bump ini from 1.3.5 to 1.3.7 in /npm_and_yarn/helpers + +## v0.126.1, 10 December 2020 + +- go_modules: don't raise error for `go mod tidy` executions + +## v0.126.0, 8 December 2020 + +- pip-compile: Fix building native python dependencies +- pipenv: handle installs with missing system dependencies +- docker: support platform option in from line @ttshivers +- Bump pip from 20.1.1 to 20.3.1 in /python/helpers +- Bump golang.org/x/mod from 0.3.0 to 0.4.0 in /go_modules/helpers +- Bump @npmcli/arborist from 1.0.13 to 1.0.14 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.58 to 0.12.59 in /composer/helpers +- Bump friendsofphp/php-cs-fixer in /composer/helpers +- Bump eslint from 7.14.0 to 7.15.0 in /npm_and_yarn/helpers +- Bump eslint-plugin-prettier from 3.1.4 to 3.2.0 in /npm_and_yarn/helpers +- Bump semver from 7.3.2 to 7.3.4 in /npm_and_yarn/helpers +- Update rubocop requirement from ~> 1.4.2 to ~> 1.5.0 in /common + +## v0.125.7, 30 November 2020 + +- Bump jest from 26.6.2 to 26.6.3 in /npm_and_yarn/helpers +- Bump prettier from 2.1.2 to 2.2.1 in /npm_and_yarn/helpers +- Bump @npmcli/arborist from 1.0.12 to 1.0.13 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.53 to 0.12.58 in /composer/helpers +- Bump pip-tools from 5.3.1 to 5.4.0 in /python/helpers +- Update rubocop requirement from ~> 0.93.0 to ~> 1.4.2 in /common +- Update simplecov requirement from ~> 0.19.0 to ~> 0.20.0 in /common +- Update gitlab requirement from = 4.16.1 to = 4.17.0 in /common +- Bundler: filter relevant credentials for all native helpers @baseballlover723 +- CI: Fix dependabot-core-ci build by removing buildkit caching + +## v0.125.6, 27 November 2020 + +- Pip compile: raise DependencyFileNotResolvable error when initial manifest + files are unresolvable +- JS: Handle rate limited npm package requests +- Go mod: verify Dependabot::GitDependenciesNotReachable from versioned +- dry-run: add exception handling and re-raise on unknown errors + +## v0.125.5, 25 November 2020 + +- go_modules: raise Dependabot::GitDependenciesNotReachable for dependencies missing from github.com +- JS: Prefer the npm conflicting dependency parser +- Clean go_modules build cache in dependabot/dependabot-core docker image +- Check Azure PR description against utf-16 encoded length +- Bump @npmcli/arborist from 1.0.10 to 1.0.12 in /npm_and_yarn/helpers +- Bump npm from 6.14.8 to 6.14.9 in /npm_and_yarn/helpers +- Bump eslint from 7.12.1 to 7.14.0 in /npm_and_yarn/helpers + +## v0.125.4, 17 November 2020 + +- Yarn: Explain conflicting top-level dependency + +## v0.125.3, 16 November 2020 + +- Bundler: Add top-level dependency to conflict explanation +- Use conflicting deps explanation in the dry-run script +- Bundler: Add explanation message to conflicting dependencies +- Add js helper README with debugging tips. +- JS: Include the top-level npm dependency for conflicting dependencies +- Hex: support reading files in elixir supporting files like in mixfiles (@baseballlover723) +- Update simplecov-console requirement from ~> 0.7.2 to ~> 0.8.0 +- Bump @npmcli/arborist from 1.0.9 to 1.0.10 in /npm_and_yarn/helpers +- Hex: support elixir `Code.require_file` like `Code.eval_file` (@baseballlover723) + +## v0.125.2, 11 November 2020 + +- Update CI jobs env variable assignment (@baseballlover723) +- Hex: Support elixir `Code.eval_file` without specifying a relative directory (@baseballlover723) +- JS: Explain update not possible for yarn and npm +- Extract DependencyFileBuilder to remove duplication + +## v0.125.1, 5 November 2020 + +- Escape `SharedHelpers.run_shell_command` with shellwords + +## v0.125.0, 5 November 2020 + +- Bundler: Explain why security update was not possible +- Raise descriptive error when update is not possible +- Go mod: Handle post-v0 module path updates + +## v0.124.8, 4 November 2020 + +- Add missing python versions: 3.6.12 3.6.11 3.6.10, 3.5.10 and 3.5.8 + +## v0.124.7, 3 November 2020 + +- composer: assume a helper terminated by `SIGKILL` is OutOfMemory +- dry-run: handle comma separated list of deps +- Bump jest from 26.6.1 to 26.6.2 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.49 to 0.12.53 in /composer/helpers +- Bump npm-user-validate from 1.0.0 to 1.0.1 in /npm_and_yarn/helpers + +## v0.124.6, 2 November 2020 + +- Go mod: handle major version mismatch +- Cargo: handle caret version requirements + +## v0.124.5, 30 October 2020 + +- Go mod: Bump gomodules-extracted [from commit](https://github.com/golang/go/commit/5b509d993d3a3a212b4033815be8b7b439fac672) +- Go mod: Add/fix specs for missing meta tag and packages that 404 + +## v0.124.4, 30 October 2020 + +- Ignore go files that start with underscore or dot +- Go mod: handle missing package url meta tags +- Ignore go files tagged with `+build` +- Handle missing VCS when converting git_source path +- Fix relative dir on mac where tmp is in /private +- Handle missing directory in cloned repo +- Improve relative path code in vendor updater +- Correctly handle vendored updates in nested directory +- Raise generic DependabotError when all else fails +- Mark unknown revision errors as DependencyFileNotResolvable +- Include backtrace from native bundler helpers +- Mount native bundler helpers in dev shell +- Bump friendsofphp/php-cs-fixer in /composer/helpers + +## v0.124.3, 27 October 2020 + +- Rename fixes_advisory? to fixed_by? and handle mixed case names +- dry-run: add security_updates_only +- Bump eslint from 7.12.0 to 7.12.1 in /npm_and_yarn/helpers + +## v0.124.2, 26 October 2020 + +- Add fixes_advisory? and affects_version? to security advisory +- Bump jest from 26.6.0 to 26.6.1 in /npm_and_yarn/helpers +- Bump composer/composer from 1.10.15 to 1.10.16 in /composer/helpers +- Bump poetry from 1.1.2 to 1.1.4 in /python/helpers +- Bump eslint from 7.11.0 to 7.12.0 in /npm_and_yarn/helpers + +## v0.124.1, 22 October 2020 + +- Add lowest_security_fix_version method to update checkers + +## v0.124.0, 20 October 2020 + +- Go: Promote experimental `go mod tidy` support to stable + (i.e., always tidy if repo_contents_path is given) +- Go: Promote experimental `go mod vendor` support to stable + (i.e., always vendor if repo_contents_path is given and vendor/modules.txt is present) +- Bump jest from 26.5.3 to 26.6.0 in /npm_and_yarn/helpers +- Bump object-path from 0.11.4 to 0.11.5 in /npm_and_yarn/helpers +- Bump composer/composer from 1.10.10 to 1.10.15 in /composer/helpers + +## v0.123.1, 19 October 2020 + +- Go mod: Handle `cannot find module` during go mod tidy +- Python: Add 3.9.0 and upgrade pyenv to v1.2.21 (@ulgens) +- Bundler: Ignore changed .gemspec from vendor/cache folder + +## v0.123.0, 13 October 2020 + +- Bundler: Refactored Dependabot's use of Bundler commands to shell out instead + of running in a forked process. + - This aligns Bundler with other package managers and will enable us to + support other Bundler versions in future. + +## v0.122.1, 13 October 2020 + +- Bump phpstan/phpstan from 0.12.48 to 0.12.49 in /composer/helpers +- Gracefully handle gomod package import that has changed +- Treat .bundlecache files as binary +- Check if files are binary using the `file` util +- Bump jest from 26.5.2 to 26.5.3 in /npm_and_yarn/helpers +- Bump eslint from 7.10.0 to 7.11.0 in /npm_and_yarn/helpers +- Update tests and fixtures for new Cargo.lock format +- Explicitly install version of rust toolchain +- Rust toolchain has been upgraded to 1.47.0. This means PRs will now try to + upgrade the lockfile to cargo's v2 format. +- Update rubocop requirement from ~> 0.92.0 to ~> 0.93.0 in /common +- Add a fingerprint to generated gitconfigs +- If there isn't a backup gitconfig, remove the generated one +- dry-run: updater-opts via option + +## v0.122.0, 7 October 2020 + +- Add experimental support for `go mod vendor` +- Enable code coverage reporting of dependabot-core + +## v0.121.1, 7 October 2020 + +- Configure git when creating a temp repo for gomod updates +- Bump jest from 26.5.0 to 26.5.2 in /npm_and_yarn/helpers +- Bump poetry from 1.1.1 to 1.1.2 in /python/helpers +- Refactor: reusable VendorDependencies object + +## v0.121.0, 6 October 2020 + +- Add experimental support for `go mod tidy` + +## v0.120.5, 6 October 2020 + +- Allow requirements.txt files of up to 200kb +- Bump poetry from 1.0.10 to 1.1.1 in /python/helpers +- Bump jest from 26.4.2 to 26.5.0 in /npm_and_yarn/helpers +- Reduce docker image size (@wreulicke) +- Bump phpstan/phpstan from 0.12.47 to 0.12.48 in /composer/helpers +- Update rubocop requirement from ~> 0.91.0 to ~> 0.92.0 in /common +- Adds python 3.7.9. (@jeremiq) + +## v0.120.4, 1 October 2020 + +- Go: Bump golang to v1.15.2 +- Bump phpstan/phpstan from 0.12.45 to 0.12.47 in /composer/helpers +- Upgrade Python to 3.8.6 (@ulgens) +- Handle empty pipfile requirement string +- Teach FileFetcher to fetch from disk if local repository clone is present +- Bundler: refactor DependencySource from LatestVersionFinder + +## v0.120.3, 28 September 2020 + +- Fix uninitialized constant error (`Dependabot::VERSION`) when using `SharedHelpers` +- Fix `SharedHelpers.excon_defaults` when passing in extra headers +- Bump phpstan/phpstan from 0.12.44 to 0.12.45 in /composer/helpers +- Bump eslint from 7.9.0 to 7.10.0 in /npm_and_yarn/helpers + +## v0.120.2, 25 September 2020 + +- Add trailing slash to pypi.org index requests +- Add a default User-Agent header to excon requests +- Bump phpstan/phpstan from 0.12.43 to 0.12.44 in /composer/helpers + +## v0.120.1, 25 September 2020 + +- Default to pypi.org instead of pypi.python.org + +## v0.120.0, 24 September 2020 + +- BREAKING: New exception `Dependabot::PullRequestCreator::AnnotationError` + Raised when a pull request is created but fails further steps (e.g. assigning reviewer) + Code that rescues from `PullRequestCreator` can use the `pull_request` property for the + incomplete PR, and the `cause` property for the original error. +- Allow Azure client to set linked work item (@JamieMagee) +- Bump eslint from 7.8.1 to 7.9.0 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.42 to 0.12.43 in /composer/helpers +- Bump prettier from 2.1.1 to 2.1.2 in /npm_and_yarn/helpers +- Bump rubocop from ~> 0.90.0 to ~> 0.91.0 in /common +- Bump jason from 1.2.1 to 1.2.2 in /hex/helpers + +## v0.119.6, 21 September 2020 + +- Fix a bug generating commit messages introduced in v0.119.5 +- bundler: add temporary support for persistent_gems_after_clean + +## v0.119.5, 21 September 2020 + +- Fix missing notice in PR content when source text is truncated +- composer: remove root cache +- nuget: Force encode nuspec files to utf-8 for regex matching + +## v0.119.4, 15 September 2020 + +- hex: fix lockfile updating transitive dependencies +- python: fix python path dependencies with file (@lfdebrux) +- Upgrade elixir/mix to 1.10.4 +- Bump rubocop from ~> 0.88.0 to ~> 0.90.0 in /common + +## v0.119.3, 10 September 2020 + +- Fix for nuget v2 responses that don't specify a base (@ppejovic) +- formatting changes to avoid linting errors +- Upgrade elixir/mix to 1.10.0 +- Add OAuth support to Azure client +- Bump eslint from 7.7.0 to 7.8.1 in /npm_and_yarn/helpers +- Bump prettier from 2.0.5 to 2.1.1 in /npm_and_yarn/helpers + +## v0.119.2, 2 September 2020 + +- Support cargo 1.46.0 ref not found message +- Don't downgrade a pinned commit to a tag. (@reitermarkus) +- Dockerfile.dev: set git author + +## v0.119.1, 28 August 2020 + +- Bump phpstan/phpstan from 0.12.37 to 0.12.39 in /composer/helpers +- Update to poetry to 1.0.10 +- Add beta support for vendoring git dependencies in Bundler + +## v0.119.0, 26 August 2020 + +- Only replace version part of cargo line +- Add beta support for vendoring dependencies in Bundler + +## v0.118.16, 20 August 2020 + +- Add a optional repo_contents_path attribute to the file parser/fetcher/updater + +## v0.118.15, 20 August 2020 + +- Handle deleting binary files in the PR creator/updater + +## v0.118.14, 20 August 2020 + +- Support binary and deleted files in PR updater/creator + +## v0.118.13, 19 August 2020 + +- Add deleted and content_encoding properties to dependency_file +- Bump npm from 6.14.4 to 6.14.8 in /npm_and_yarn/helpers +- Bump eslint from 7.6.0 to 7.7.0 in /npm_and_yarn/helpers +- Bump jest from 26.2.2 to 26.4.0 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.34 to 0.12.37 in /composer/helpers +- Add python 3.7.8 +- Test caching strategy from old circle config + +## v0.118.12, 7 August 2020 + +- docker: consistent indentation of Dockerfile (@localheinz) +- python: properly escape username nad password in auth URL +- CI: publish versioned images to DockerHub +- CI: performance improvements + +## v0.118.11, 6 August 2020 + +- common: increase default http client read timeout +- go_modules: always return a Version object for indirect dependencies +- Bump composer/composer from 1.10.9 to 1.10.10 in /composer/helpers +- Bump pip-tools from 5.3.0 to 5.3.1 in /python/helpers +- CI: performance improvements + +## v0.118.10, 3 August 2020 + +- Bump jest from 26.2.1 to 26.2.2 in /npm_and_yarn/helpers +- Bump eslint from 7.5.0 to 7.6.0 in /npm_and_yarn/helpers +- Encode '@' in python HTTP basic auth passwords + +## v0.118.9, 3 August 2020 + +- CI: Move from Circle CI to actions +- CI: Use job matrix @localheinz +- Composer: Best practices for 7.4 @localheinz +- Composer: Explicitly require latest stable version of composer/composer @localheinz +- Actions: Fix updating actions that are quoted +- Bump jest from 26.1.0 to 26.2.1 in /npm_and_yarn/helpers +- Bump phpstan/phpstan from 0.12.33 to 0.12.34 in /composer/helpers +- Bump pip-tools from 5.2.1 to 5.3.0 in /python/helpers + ## v0.118.8, 24 July 2020 - Upgrade Python version to 3.8.5 (@ulgens) diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000000..248dab4bfd8 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @dependabot/maintainers diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..6ce6763756d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +opensource@github.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5177905a099..e230c07f9d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,10 +4,40 @@ #### Overview +- [Contributing new ecosystems](#contributing-new-ecosystems) - [Contribution workflow](#contribution-workflow) - [Setup instructions](#setup-instructions) - [Project layout](#project-layout) +## Contributing new ecosystems + +We are not currently accepting new ecosystems into `dependabot-core`, starting in December 2020. + +### Why have we paused accepting new ecosystems? + +Dependabot has grown dramatically in the last two years since integrating with GitHub. We are now [used by millions of repositories](https://octoverse.github.com/#securing-software) across [16 package managers](https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-dependabot-version-updates#supported-repositories-and-ecosystems). We aim to provide the best user experience +possible for each of these, but we have found we've lacked the capacity – and in some cases the in-house expertise – to support new ecosystems in the last year. We want to be +confident we can support each ecosystem we merge. + +In the immediate future, we want to focus more of our resources on merging improvements to the ecosystems we already support. This does not mean that we are stopping work or investing less in this space - in fact, we're investing more, to make it a great user experience. This tough call means we can also provide a better experience for our contributors, where PRs don't go stale while waiting for a review. + +If you are an ecosystem maintainer and are interested in integrating with Dependabot, and are willing to help provide the expertise necessary to build and support it, please open an issue and let us know. + +We hope to be able to accept community contributions for ecosystem support again soon. + +### What's next? + +In `dependabot-core`, each ecosystem implementation is in its own gem so you can use Dependabot for a language +we have not merged by creating a [script](https://github.com/dependabot/dependabot-script) to run your own gem or +fork of core, e.g. [dependabot-lein-runner](https://github.com/CGA1123/dependabot-lein-runner) + +Our plan in the year ahead is to invest more developer time directly in `dependabot-core` to improve our architecture so +each ecosystem is more isolated and testable. We also want to make a consistency pass on existing ecosystems so that there +is a clearer interface between core and the language-specific tooling. + +Our goal is make it easier to create and test Dependabot extensions so there is a paved path for running additional +ecosystems in the future. + ## Contribution workflow * Fork the project. @@ -25,7 +55,7 @@ Assuming you're working on a single language, the best thing to do is just to in * [Install the latest Ruby](https://github.com/rbenv/rbenv#installing-ruby-versions) * Install Bundler with `gem install bundler` (this is Ruby's package manager) * Install Dependabot's Ruby dependencies with `bundle install` -* Install the language dependencies for whatever languages you're working on (see [how we do it in CI](.circleci/config.yml)) +* Install the language dependencies for whatever languages you're working on (see [how we do it in CI](.github/workflows/ci.yml)) * Run the tests for the file you're working on with `bundle exec rspec spec/dependabot/file_updaters/elixir/` (for example). They should be green (although might need an internet connection). ## Project layout diff --git a/Dockerfile b/Dockerfile index 554e39e01db..b970bbc47f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,159 +1,334 @@ -FROM ubuntu:18.04 +FROM ubuntu:20.04 + +ARG TARGETARCH=amd64 + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] ### SYSTEM DEPENDENCIES ENV DEBIAN_FRONTEND="noninteractive" \ - LC_ALL="en_US.UTF-8" \ - LANG="en_US.UTF-8" - -# Everything from `make` onwards in apt-get install is only installed to ensure -# Python support works with all packages (which may require specific libraries -# at install time). + LC_ALL="en_US.UTF-8" \ + LANG="en_US.UTF-8" RUN apt-get update \ - && apt-get upgrade -y \ - && apt-get install -y --no-install-recommends \ - build-essential \ - dirmngr \ - git \ - bzr \ - mercurial \ - gnupg2 \ - curl \ - wget \ - zlib1g-dev \ - liblzma-dev \ - tzdata \ - zip \ - unzip \ - locales \ - openssh-client \ - make \ - libpq-dev \ - libssl-dev \ - libbz2-dev \ - libffi-dev \ - libreadline-dev \ - libsqlite3-dev \ - libcurl4-openssl-dev \ - llvm \ - libncurses5-dev \ - libncursesw5-dev \ - libmysqlclient-dev \ - xz-utils \ - tk-dev \ - libxml2-dev \ - libxmlsec1-dev \ - libgeos-dev \ - python3-enchant \ - && locale-gen en_US.UTF-8 + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + build-essential \ + dirmngr \ + git \ + git-lfs \ + bzr \ + mercurial \ + gnupg2 \ + ca-certificates \ + curl \ + file \ + zlib1g-dev \ + liblzma-dev \ + libyaml-dev \ + libgdbm-dev \ + bison \ + tzdata \ + zip \ + unzip \ + locales \ + openssh-client \ + software-properties-common \ + # Everything from here onwards is only installed to ensure + # Python support works with all packages (which may require + # specific libraries at install time). + make \ + libpq-dev \ + libssl-dev \ + libbz2-dev \ + libffi-dev \ + libreadline-dev \ + libsqlite3-dev \ + libcurl4-openssl-dev \ + llvm \ + libncurses5-dev \ + libncursesw5-dev \ + libmysqlclient-dev \ + xz-utils \ + tk-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libgeos-dev \ + python3-enchant \ + && locale-gen en_US.UTF-8 \ + && rm -rf /var/lib/apt/lists/* + +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +RUN if ! getent group "$USER_GID"; then groupadd --gid "$USER_GID" dependabot ; \ + else GROUP_NAME=$(getent group $USER_GID | awk -F':' '{print $1}'); groupmod -n dependabot "$GROUP_NAME" ; fi \ + && useradd --uid "${USER_UID}" --gid "${USER_GID}" -m dependabot \ + && mkdir -p /opt && chown dependabot:dependabot /opt ### RUBY -# Install Ruby 2.6.6, update RubyGems, and install Bundler +# When bumping Ruby minor, need to also add the previous version to `bundler/helpers/v{1,2}/monkey_patches/definition_ruby_version_patch.rb` +ARG RUBY_VERSION=3.1.2 +ARG RUBY_INSTALL_VERSION=0.8.5 + +ARG BUNDLER_V1_VERSION=1.17.3 +# When bumping Bundler, need to also regenerate `updater/Gemfile.lock` via `bundle update --bundler` +ARG BUNDLER_V2_VERSION=2.3.25 ENV BUNDLE_SILENCE_ROOT_WARNING=1 -RUN apt-get install -y software-properties-common \ - && apt-add-repository ppa:brightbox/ruby-ng \ - && apt-get update \ - && apt-get install -y ruby2.6 ruby2.6-dev \ - && gem update --system 3.0.3 \ - && gem install bundler -v 1.17.3 --no-document +# Allow gem installs as the dependabot user +ENV BUNDLE_PATH=".bundle" + +# Install Ruby, update RubyGems, and install Bundler +RUN mkdir -p /tmp/ruby-install \ + && cd /tmp/ruby-install \ + && curl -fsSL "https://github.com/postmodern/ruby-install/archive/v$RUBY_INSTALL_VERSION.tar.gz" -o ruby-install-$RUBY_INSTALL_VERSION.tar.gz \ + && tar -xzvf ruby-install-$RUBY_INSTALL_VERSION.tar.gz \ + && cd ruby-install-$RUBY_INSTALL_VERSION/ \ + && make \ + && ./bin/ruby-install --system --cleanup ruby $RUBY_VERSION -- --disable-install-doc \ + && gem install bundler -v $BUNDLER_V1_VERSION --no-document \ + && gem install bundler -v $BUNDLER_V2_VERSION --no-document \ + && rm -rf /var/lib/gems/*/cache/* \ + && rm -rf /tmp/ruby-install ### PYTHON - -# Install Python 2.7 and 3.8 with pyenv. Using pyenv lets us support multiple Pythons +COPY --chown=dependabot:dependabot python/helpers /opt/python/helpers +# Install Python with pyenv. +USER root ENV PYENV_ROOT=/usr/local/.pyenv \ - PATH="/usr/local/.pyenv/bin:$PATH" -RUN git clone https://github.com/pyenv/pyenv.git /usr/local/.pyenv \ - && cd /usr/local/.pyenv && git checkout v1.2.20 && cd - \ - && pyenv install 3.8.5 \ - && pyenv install 2.7.18 \ - && pyenv global 3.8.5 - - + PATH="/usr/local/.pyenv/bin:$PATH" +RUN mkdir -p "$PYENV_ROOT" && chown dependabot:dependabot "$PYENV_ROOT" +USER dependabot +ENV DEPENDABOT_NATIVE_HELPERS_PATH="/opt" +RUN git -c advice.detachedHead=false clone https://github.com/pyenv/pyenv.git --branch v2.3.6 --single-branch --depth=1 /usr/local/.pyenv \ + # This is the version of CPython that gets installed + && pyenv install 3.11.0 \ + && pyenv global 3.11.0 \ + && pyenv install 3.10.8 \ + && pyenv install 3.9.15 \ + && pyenv install 3.8.15 \ + && pyenv install 3.7.15 \ + && rm -Rf /tmp/python-build* \ + && bash /opt/python/helpers/build \ + && cd /usr/local/.pyenv \ + && tar czf 3.10.tar.gz versions/3.10.8 \ + && tar czf 3.9.tar.gz versions/3.9.15 \ + && tar czf 3.8.tar.gz versions/3.8.15 \ + && tar czf 3.7.tar.gz versions/3.7.15 \ + && rm -Rf versions/3.10.8 \ + && rm -Rf versions/3.9.15 \ + && rm -Rf versions/3.8.15 \ + && rm -Rf versions/3.7.15 + +USER root ### JAVASCRIPT -# Install Node 10.0 and Yarn -RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ - && apt-get install -y nodejs \ - && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ - && apt-get update && apt-get install -y yarn +# Install Node and npm +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \ + && apt-get install -y --no-install-recommends nodejs \ + && rm -rf /var/lib/apt/lists/* \ + && npm install -g npm@8.19.2 \ + && rm -rf ~/.npm +# Install yarn berry and set it to a stable version +RUN corepack enable \ + && corepack prepare yarn@3.2.3 --activate ### ELM -# Install Elm 0.18 and Elm 0.19 +# Install Elm +# This is currently amd64 only, see: +# - https://github.com/elm/compiler/issues/2007 +# - https://github.com/elm/compiler/issues/2232 ENV PATH="$PATH:/node_modules/.bin" -RUN npm install elm@0.18.0 \ - && wget "https://github.com/elm/compiler/releases/download/0.19.0/binaries-for-linux.tar.gz" \ - && tar xzf binaries-for-linux.tar.gz \ - && mv elm /usr/local/bin/elm19 \ - && rm -f binaries-for-linux.tar.gz +RUN [ "$TARGETARCH" != "amd64" ] \ + || (curl -sSLfO "https://github.com/elm/compiler/releases/download/0.19.0/binaries-for-linux.tar.gz" \ + && tar xzf binaries-for-linux.tar.gz \ + && mv elm /usr/local/bin/elm19 \ + && rm -f binaries-for-linux.tar.gz) ### PHP -# Install PHP 7.4 and Composer +# Install PHP and Composer ENV COMPOSER_ALLOW_SUPERUSER=1 -COPY --from=composer:1.10.9 /usr/bin/composer /usr/local/bin/composer RUN add-apt-repository ppa:ondrej/php \ - && apt-get update \ - && apt-get install -y php7.4 php7.4-cli php7.4-xml php7.4-json php7.4-zip php7.4-mbstring php7.4-intl php7.4-common php7.4-gettext php7.4-curl php7.4-bcmath php7.4-gmp php7.4-imagick php7.4-gd php7.4-redis php7.4-soap php7.4-ldap php7.4-memcached php7.4-sqlite3 php7.4-apcu php7.4-tidy php7.4-mongodb php7.4-zmq php7.4-mysql php7.4-imap php7.4-geoip + && apt-get update \ + && apt-get install -y --no-install-recommends \ + php7.4 \ + php7.4-apcu \ + php7.4-bcmath \ + php7.4-cli \ + php7.4-common \ + php7.4-curl \ + php7.4-gd \ + php7.4-geoip \ + php7.4-gettext \ + php7.4-gmp \ + php7.4-imagick \ + php7.4-imap \ + php7.4-intl \ + php7.4-json \ + php7.4-ldap \ + php7.4-mbstring \ + php7.4-memcached \ + php7.4-mongodb \ + php7.4-mysql \ + php7.4-redis \ + php7.4-soap \ + php7.4-sqlite3 \ + php7.4-tidy \ + php7.4-xml \ + php7.4-zip \ + php7.4-zmq \ + php7.4-mcrypt \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer1 --version=1.10.26 +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer --version=2.3.9 + +USER dependabot +# Perform a fake `composer update` to warm ~/dependabot/.cache/composer/repo +# with historic data (we don't care about package files here) +RUN mkdir /tmp/composer-cache \ + && cd /tmp/composer-cache \ + && echo '{"require":{"psr/log": "^1.1.3"}}' > composer.json \ + && composer update --no-scripts --dry-run \ + && cd /tmp \ + && rm -rf /home/dependabot/.cache/composer/files \ + && rm -rf /tmp/composer-cache +USER root ### GO -# Install Go and dep -RUN curl https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz | tar -xz -C /opt \ - && wget -O /opt/go/bin/dep https://github.com/golang/dep/releases/download/v0.5.4/dep-linux-amd64 \ - && chmod +x /opt/go/bin/dep \ - && mkdir /opt/go/gopath -ENV PATH=/opt/go/bin:$PATH GOPATH=/opt/go/gopath +# Install Go +ARG GOLANG_VERSION=1.19 +# You can find the sha here: https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-amd64.tar.gz.sha256 +ARG GOLANG_AMD64_CHECKSUM=464b6b66591f6cf055bc5df90a9750bf5fbc9d038722bb84a9d56a2bea974be6 +ARG GOLANG_ARM64_CHECKSUM=efa97fac9574fc6ef6c9ff3e3758fb85f1439b046573bf434cccb5e012bd00c8 + +ENV PATH=/opt/go/bin:$PATH +RUN cd /tmp \ + && curl --http1.1 -o go-${TARGETARCH}.tar.gz https://dl.google.com/go/go${GOLANG_VERSION}.linux-${TARGETARCH}.tar.gz \ + && printf "$GOLANG_AMD64_CHECKSUM go-amd64.tar.gz\n$GOLANG_ARM64_CHECKSUM go-arm64.tar.gz\n" | sha256sum -c --ignore-missing - \ + && tar -xzf go-${TARGETARCH}.tar.gz -C /opt \ + && rm go-${TARGETARCH}.tar.gz ### ELIXIR -# Install Erlang, Elixir and Hex +# Install Erlang and Elixir ENV PATH="$PATH:/usr/local/elixir/bin" -RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb \ - && dpkg -i erlang-solutions_1.0_all.deb \ - && apt-get update \ - && apt-get install -y esl-erlang \ - && wget https://github.com/elixir-lang/elixir/releases/download/v1.9.1/Precompiled.zip \ - && unzip -d /usr/local/elixir -x Precompiled.zip \ - && rm -f Precompiled.zip \ - && mix local.hex --force +# https://github.com/elixir-lang/elixir/releases +ARG ELIXIR_VERSION=v1.14.2 +ARG ELIXIR_CHECKSUM=2e4addb85de85218d32c16b3710e8087f5b18b3b1560742137ad4c41bbbea63a +ARG ERLANG_MAJOR_VERSION=24 +ARG ERLANG_VERSION=1:${ERLANG_MAJOR_VERSION}.2.1-1 +RUN curl -sSLfO https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb \ + && dpkg -i erlang-solutions_2.0_all.deb \ + && apt-get update \ + && apt-get install -y --no-install-recommends esl-erlang=${ERLANG_VERSION} \ + && curl -sSLfO https://github.com/elixir-lang/elixir/releases/download/${ELIXIR_VERSION}/elixir-otp-${ERLANG_MAJOR_VERSION}.zip \ + && echo "$ELIXIR_CHECKSUM elixir-otp-${ERLANG_MAJOR_VERSION}.zip" | sha256sum -c - \ + && unzip -d /usr/local/elixir -x elixir-otp-${ERLANG_MAJOR_VERSION}.zip \ + && rm -f elixir-otp-${ERLANG_MAJOR_VERSION}.zip erlang-solutions_2.0_all.deb \ + && rm -rf /var/lib/apt/lists/* ### RUST -# Install Rust 1.37.0 +# Install Rust ENV RUSTUP_HOME=/opt/rust \ - PATH="${PATH}:/opt/rust/bin" -RUN export CARGO_HOME=/opt/rust ; curl https://sh.rustup.rs -sSf | sh -s -- -y - - -### NEW NATIVE HELPERS - -COPY terraform/helpers /opt/terraform/helpers -COPY python/helpers /opt/python/helpers -COPY dep/helpers /opt/dep/helpers -COPY go_modules/helpers /opt/go_modules/helpers -COPY hex/helpers /opt/hex/helpers -COPY composer/helpers /opt/composer/helpers -COPY npm_and_yarn/helpers /opt/npm_and_yarn/helpers - -ENV DEPENDABOT_NATIVE_HELPERS_PATH="/opt" \ - PATH="$PATH:/opt/terraform/bin:/opt/python/bin:/opt/go_modules/bin:/opt/dep/bin" \ - MIX_HOME="/opt/hex/mix" - -RUN bash /opt/terraform/helpers/build /opt/terraform && \ - bash /opt/python/helpers/build /opt/python && \ - bash /opt/dep/helpers/build /opt/dep && \ - bash /opt/go_modules/helpers/build /opt/go_modules && \ - bash /opt/npm_and_yarn/helpers/build /opt/npm_and_yarn && \ - bash /opt/hex/helpers/build /opt/hex && \ - bash /opt/composer/helpers/build /opt/composer + CARGO_HOME=/opt/rust \ + PATH="${PATH}:/opt/rust/bin" +RUN mkdir -p "$RUSTUP_HOME" && chown dependabot:dependabot "$RUSTUP_HOME" +USER dependabot +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.64.0 --profile minimal + + +### Terraform + +USER root +ARG TERRAFORM_VERSION=1.3.6 +ARG TERRAFORM_AMD64_CHECKSUM=bb44a4c2b0a832d49253b9034d8ccbd34f9feeb26eda71c665f6e7fa0861f49b +ARG TERRAFORM_ARM64_CHECKSUM=f4b1af29094290f1b3935c29033c4e5291664ee2c015ca251a020dd425c847c3 +RUN cd /tmp \ + && curl -o terraform-${TARGETARCH}.tar.gz https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip \ + && printf "$TERRAFORM_AMD64_CHECKSUM terraform-amd64.tar.gz\n$TERRAFORM_ARM64_CHECKSUM terraform-arm64.tar.gz\n" | sha256sum -c --ignore-missing - \ + && unzip -d /usr/local/bin terraform-${TARGETARCH}.tar.gz \ + && rm terraform-${TARGETARCH}.tar.gz + +### DART + +# Install Dart +ENV PUB_CACHE=/opt/dart/pub-cache \ + PUB_ENVIRONMENT="dependabot" \ + PATH="${PATH}:/opt/dart/dart-sdk/bin" + +# https://dart.dev/get-dart/archive +ARG DART_VERSION=2.18.5 +# TODO Dart now publishes SHA256 checksums for their releases, we should validate against those. +RUN DART_ARCH=${TARGETARCH} \ + && if [ "$TARGETARCH" = "amd64" ]; then DART_ARCH=x64; fi \ + && curl --connect-timeout 15 --retry 5 "https://storage.googleapis.com/dart-archive/channels/stable/release/${DART_VERSION}/sdk/dartsdk-linux-${DART_ARCH}-release.zip" > "/tmp/dart-sdk.zip" \ + && mkdir -p "$PUB_CACHE" \ + && chown dependabot:dependabot "$PUB_CACHE" \ + && unzip "/tmp/dart-sdk.zip" -d "/opt/dart" > /dev/null \ + && chmod -R o+rx "/opt/dart/dart-sdk" \ + && rm "/tmp/dart-sdk.zip" \ + && dart --version + +COPY --chown=dependabot:dependabot LICENSE /home/dependabot + +USER dependabot + +ENV DEPENDABOT_NATIVE_HELPERS_PATH="/opt" + +COPY --chown=dependabot:dependabot composer/helpers /opt/composer/helpers +RUN bash /opt/composer/helpers/v1/build \ + && bash /opt/composer/helpers/v2/build + +COPY --chown=dependabot:dependabot bundler/helpers /opt/bundler/helpers +RUN bash /opt/bundler/helpers/v1/build \ + && bash /opt/bundler/helpers/v2/build + +COPY --chown=dependabot:dependabot go_modules/helpers /opt/go_modules/helpers +RUN bash /opt/go_modules/helpers/build + +COPY --chown=dependabot:dependabot hex/helpers /opt/hex/helpers +ENV MIX_HOME="/opt/hex/mix" +# https://github.com/hexpm/hex/releases +ENV HEX_VERSION="1.0.1" +RUN bash /opt/hex/helpers/build + +COPY --chown=dependabot:dependabot pub/helpers /opt/pub/helpers +RUN bash /opt/pub/helpers/build + +COPY --chown=dependabot:dependabot npm_and_yarn/helpers /opt/npm_and_yarn/helpers +RUN bash /opt/npm_and_yarn/helpers/build +# Our native helpers pull in yarn 1, so we need to reset the version globally to +# 3.2.3. +RUN corepack prepare yarn@3.2.3 --activate + +COPY --chown=dependabot:dependabot terraform/helpers /opt/terraform/helpers +RUN bash /opt/terraform/helpers/build + +ENV PATH="$PATH:/opt/terraform/bin:/opt/python/bin:/opt/go_modules/bin" + +ENV HOME="/home/dependabot" + +WORKDIR ${HOME} + +# Place a git shim ahead of git on the path to rewrite git arguments to use HTTPS. +ARG SHIM="https://github.com/dependabot/git-shim/releases/download/v1.4.0/git-v1.4.0-linux-amd64.tar.gz" +RUN curl -sL $SHIM -o git-shim.tar.gz && mkdir -p ~/bin && tar -xvf git-shim.tar.gz -C ~/bin && rm git-shim.tar.gz +ENV PATH="$HOME/bin:$PATH" +# Configure cargo to use git CLI so the above takes effect +RUN mkdir -p ~/.cargo && printf "[net]\ngit-fetch-with-cli = true\n" >> ~/.cargo/config.toml +# Disable automatic pulling of files stored with Git LFS +# This avoids downloading large files not necessary for the dependabot scripts +ENV GIT_LFS_SKIP_SMUDGE=1 diff --git a/Dockerfile.ci b/Dockerfile.ci index 6a3a75e088d..3eb3157734e 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,122 +1,28 @@ FROM dependabot/dependabot-core -RUN useradd -m dependabot -RUN chown -R dependabot:dependabot /usr/local/.pyenv /opt/go/gopath -USER dependabot - -RUN mkdir -p /home/dependabot/dependabot-core/common/lib/dependabot -WORKDIR /home/dependabot/dependabot-core - -ENV BUNDLE_PATH="/home/dependabot/.bundle" \ - BUNDLE_BIN=".bundle/binstubs" \ - PATH=".bundle/binstubs:$PATH:/home/dependabot/.bundle/bin" - -RUN gem install --user rake - -COPY common/Gemfile common/dependabot-common.gemspec /home/dependabot/dependabot-core/common/ -COPY common/lib/dependabot/version.rb /home/dependabot/dependabot-core/common/lib/dependabot/ -RUN cd common && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/terraform -COPY terraform/Gemfile \ - terraform/dependabot-terraform.gemspec \ - /home/dependabot/dependabot-core/terraform/ -RUN cd terraform && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/elm -COPY elm/Gemfile \ - elm/dependabot-elm.gemspec \ - /home/dependabot/dependabot-core/elm/ -RUN cd elm && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/python -COPY python/Gemfile \ - python/dependabot-python.gemspec \ - /home/dependabot/dependabot-core/python/ -RUN cd python && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/docker -COPY docker/Gemfile \ - docker/dependabot-docker.gemspec \ - /home/dependabot/dependabot-core/docker/ -RUN cd docker && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/git_submodules -COPY git_submodules/Gemfile \ - git_submodules/dependabot-git_submodules.gemspec \ - /home/dependabot/dependabot-core/git_submodules/ -RUN cd git_submodules && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/github_actions -COPY github_actions/Gemfile \ - github_actions/dependabot-github_actions.gemspec \ - /home/dependabot/dependabot-core/github_actions/ -RUN cd github_actions && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/maven -COPY maven/Gemfile \ - maven/dependabot-maven.gemspec \ - /home/dependabot/dependabot-core/maven/ -RUN cd maven && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/gradle -COPY gradle/Gemfile \ - gradle/dependabot-gradle.gemspec \ - /home/dependabot/dependabot-core/gradle/ -RUN cd gradle && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/hex -COPY hex/Gemfile \ - hex/dependabot-hex.gemspec \ - /home/dependabot/dependabot-core/hex/ -RUN cd hex && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/nuget -COPY nuget/Gemfile \ - nuget/dependabot-nuget.gemspec \ - /home/dependabot/dependabot-core/nuget/ -RUN cd nuget && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/composer -COPY composer/Gemfile \ - composer/dependabot-composer.gemspec \ - /home/dependabot/dependabot-core/composer/ -RUN cd composer && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/cargo -COPY cargo/Gemfile \ - cargo/dependabot-cargo.gemspec \ - /home/dependabot/dependabot-core/cargo/ -RUN cd cargo && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/dep -COPY dep/Gemfile \ - dep/dependabot-dep.gemspec \ - /home/dependabot/dependabot-core/dep/ -RUN cd dep && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/go_modules -COPY go_modules/Gemfile \ - go_modules/dependabot-go_modules.gemspec \ - /home/dependabot/dependabot-core/go_modules/ -RUN cd go_modules && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/npm_and_yarn -COPY npm_and_yarn/Gemfile \ - npm_and_yarn/dependabot-npm_and_yarn.gemspec \ - /home/dependabot/dependabot-core/npm_and_yarn/ -RUN cd npm_and_yarn && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/bundler -COPY bundler/Gemfile \ - bundler/dependabot-bundler.gemspec \ - /home/dependabot/dependabot-core/bundler/ -RUN cd bundler && bundle install - -RUN mkdir -p /home/dependabot/dependabot-core/omnibus -COPY omnibus/Gemfile \ - omnibus/dependabot-omnibus.gemspec \ - /home/dependabot/dependabot-core/omnibus/ -RUN cd omnibus && bundle install - -COPY --chown=dependabot . /home/dependabot/dependabot-core/ +RUN git config --global user.name dependabot-ci \ + && git config --global user.email no-reply@github.com + +ARG CODE_DIR=/home/dependabot/dependabot-core +WORKDIR ${CODE_DIR} + +COPY --chown=dependabot:dependabot .ruby-version ${CODE_DIR}/.ruby-version +COPY --chown=dependabot:dependabot .rubocop.yml ${CODE_DIR}/.rubocop.yml +COPY --chown=dependabot:dependabot omnibus ${CODE_DIR}/omnibus +COPY --chown=dependabot:dependabot git_submodules ${CODE_DIR}/git_submodules +COPY --chown=dependabot:dependabot terraform ${CODE_DIR}/terraform +COPY --chown=dependabot:dependabot github_actions ${CODE_DIR}/github_actions +COPY --chown=dependabot:dependabot hex ${CODE_DIR}/hex +COPY --chown=dependabot:dependabot elm ${CODE_DIR}/elm +COPY --chown=dependabot:dependabot docker ${CODE_DIR}/docker +COPY --chown=dependabot:dependabot nuget ${CODE_DIR}/nuget +COPY --chown=dependabot:dependabot maven ${CODE_DIR}/maven +COPY --chown=dependabot:dependabot gradle ${CODE_DIR}/gradle +COPY --chown=dependabot:dependabot cargo ${CODE_DIR}/cargo +COPY --chown=dependabot:dependabot composer ${CODE_DIR}/composer +COPY --chown=dependabot:dependabot go_modules ${CODE_DIR}/go_modules +COPY --chown=dependabot:dependabot python ${CODE_DIR}/python +COPY --chown=dependabot:dependabot pub ${CODE_DIR}/pub +COPY --chown=dependabot:dependabot npm_and_yarn ${CODE_DIR}/npm_and_yarn +COPY --chown=dependabot:dependabot bundler ${CODE_DIR}/bundler +COPY --chown=dependabot:dependabot common ${CODE_DIR}/common diff --git a/Dockerfile.development b/Dockerfile.development index ef1a159b2a9..b58cb862b65 100644 --- a/Dockerfile.development +++ b/Dockerfile.development @@ -2,99 +2,62 @@ FROM dependabot/dependabot-core # Temporarily switch to root user in order to install packages USER root - -# Add debugging tools -RUN apt-get update && apt-get install -y vim strace ltrace gdb - -# This Dockerfile adds a non-root 'dependabot' user. However, for Linux, -# this user's GID/UID must match your local user UID/GID to avoid permission issues -# with bind mounts. Update USER_UID / USER_GID if yours is not 1000. -# USER_UID should be the value of $UID from the host environment and -# USER_GID the value of `id -g`. -# See https://aka.ms/vscode-remote/containers/non-root-user for details. -ARG USER_UID=1000 -ARG USER_GID=$USER_UID -ARG USERNAME=dependabot - -RUN groupadd -o --gid "${USER_GID}" "${USERNAME}" && \ - useradd --uid "${USER_UID}" --gid "${USER_GID}" -m "${USERNAME}" -RUN chown -R "${USERNAME}":"${USERNAME}" \ - /usr/local/.pyenv \ - /opt/go/gopath \ - /opt/rust/ -USER $USERNAME - -ARG CODE_DIR=/home/$USERNAME/dependabot-core - -RUN curl -L -o ~/.vimrc https://github.com/hmarr/dotfiles/raw/master/vimrc-vanilla.vim && \ - echo 'export PS1="[dependabot-core-dev] \w \[$(tput setaf 4)\]$ \[$(tput sgr 0)\]"' >> ~/.bashrc - -RUN mkdir -p ${CODE_DIR}/common/lib/dependabot +RUN apt-get update \ + && apt-get install -y vim strace ltrace gdb shellcheck \ + && rm -rf /var/lib/apt/lists/* +USER dependabot + +RUN git config --global user.name dependabot-ci \ + && git config --global user.email no-reply@github.com +RUN curl -L -o ~/.vimrc https://github.com/hmarr/dotfiles/raw/main/vimrc-vanilla.vim && \ + echo 'export PS1="[dependabot-core-dev] \w \[$(tput setaf 4)\]$ \[$(tput sgr 0)\]"' >> ~/.bashrc + +ARG CODE_DIR=${HOME}/dependabot-core + +COPY --chown=dependabot:dependabot common/Gemfile common/dependabot-common.gemspec ${CODE_DIR}/common/ +COPY --chown=dependabot:dependabot common/lib/dependabot/version.rb ${CODE_DIR}/common/lib/dependabot/ + +COPY --chown=dependabot:dependabot bundler/Gemfile bundler/dependabot-bundler.gemspec ${CODE_DIR}/bundler/ +COPY --chown=dependabot:dependabot cargo/Gemfile cargo/dependabot-cargo.gemspec ${CODE_DIR}/cargo/ +COPY --chown=dependabot:dependabot composer/Gemfile composer/dependabot-composer.gemspec ${CODE_DIR}/composer/ +COPY --chown=dependabot:dependabot docker/Gemfile docker/dependabot-docker.gemspec ${CODE_DIR}/docker/ +COPY --chown=dependabot:dependabot elm/Gemfile elm/dependabot-elm.gemspec ${CODE_DIR}/elm/ +COPY --chown=dependabot:dependabot git_submodules/Gemfile git_submodules/dependabot-git_submodules.gemspec ${CODE_DIR}/git_submodules/ +COPY --chown=dependabot:dependabot github_actions/Gemfile github_actions/dependabot-github_actions.gemspec ${CODE_DIR}/github_actions/ +COPY --chown=dependabot:dependabot go_modules/Gemfile go_modules/dependabot-go_modules.gemspec ${CODE_DIR}/go_modules/ +COPY --chown=dependabot:dependabot gradle/Gemfile gradle/dependabot-gradle.gemspec ${CODE_DIR}/gradle/ +COPY --chown=dependabot:dependabot hex/Gemfile hex/dependabot-hex.gemspec ${CODE_DIR}/hex/ +COPY --chown=dependabot:dependabot maven/Gemfile maven/dependabot-maven.gemspec ${CODE_DIR}/maven/ +COPY --chown=dependabot:dependabot npm_and_yarn/Gemfile npm_and_yarn/dependabot-npm_and_yarn.gemspec ${CODE_DIR}/npm_and_yarn/ +COPY --chown=dependabot:dependabot nuget/Gemfile nuget/dependabot-nuget.gemspec ${CODE_DIR}/nuget/ +COPY --chown=dependabot:dependabot python/Gemfile python/dependabot-python.gemspec ${CODE_DIR}/python/ +COPY --chown=dependabot:dependabot pub/Gemfile pub/dependabot-pub.gemspec ${CODE_DIR}/pub/ +COPY --chown=dependabot:dependabot terraform/Gemfile terraform/dependabot-terraform.gemspec ${CODE_DIR}/terraform/ + +COPY --chown=dependabot:dependabot omnibus/Gemfile omnibus/dependabot-omnibus.gemspec ${CODE_DIR}/omnibus/ WORKDIR ${CODE_DIR} -ENV BUNDLE_PATH="/home/$USERNAME/.bundle" \ - BUNDLE_BIN=".bundle/binstubs" -ENV PATH="$BUNDLE_BIN:$PATH:$BUNDLE_PATH/bin" - -COPY common/Gemfile common/dependabot-common.gemspec ${CODE_DIR}/common/ -COPY common/lib/dependabot/version.rb ${CODE_DIR}/common/lib/dependabot/ -RUN cd common && bundle install +RUN cd omnibus \ + && bundle install \ + && BUNDLE_BIN=.bundle/bin bundle binstubs --all \ + && rm .bundle/bin/bundle # let RubyGems manage Bundler -RUN mkdir -p ${CODE_DIR}/bundler \ - ${CODE_DIR}/cargo \ - ${CODE_DIR}/composer \ - ${CODE_DIR}/dep \ - ${CODE_DIR}/docker \ - ${CODE_DIR}/elm \ - ${CODE_DIR}/git_submodules \ - ${CODE_DIR}/github_actions \ - ${CODE_DIR}/go_modules \ - ${CODE_DIR}/gradle \ - ${CODE_DIR}/hex \ - ${CODE_DIR}/maven \ - ${CODE_DIR}/npm_and_yarn \ - ${CODE_DIR}/nuget \ - ${CODE_DIR}/omnibus \ - ${CODE_DIR}/python \ - ${CODE_DIR}/terraform - -COPY bundler/Gemfile bundler/dependabot-bundler.gemspec ${CODE_DIR}/bundler/ -COPY cargo/Gemfile cargo/dependabot-cargo.gemspec ${CODE_DIR}/cargo/ -COPY composer/Gemfile composer/dependabot-composer.gemspec ${CODE_DIR}/composer/ -COPY dep/Gemfile dep/dependabot-dep.gemspec ${CODE_DIR}/dep/ -COPY docker/Gemfile docker/dependabot-docker.gemspec ${CODE_DIR}/docker/ -COPY elm/Gemfile elm/dependabot-elm.gemspec ${CODE_DIR}/elm/ -COPY git_submodules/Gemfile git_submodules/dependabot-git_submodules.gemspec ${CODE_DIR}/git_submodules/ -COPY github_actions/Gemfile github_actions/dependabot-github_actions.gemspec ${CODE_DIR}/github_actions/ -COPY go_modules/Gemfile go_modules/dependabot-go_modules.gemspec ${CODE_DIR}/go_modules/ -COPY gradle/Gemfile gradle/dependabot-gradle.gemspec ${CODE_DIR}/gradle/ -COPY hex/Gemfile hex/dependabot-hex.gemspec ${CODE_DIR}/hex/ -COPY maven/Gemfile maven/dependabot-maven.gemspec ${CODE_DIR}/maven/ -COPY npm_and_yarn/Gemfile npm_and_yarn/dependabot-npm_and_yarn.gemspec ${CODE_DIR}/npm_and_yarn/ -COPY nuget/Gemfile nuget/dependabot-nuget.gemspec ${CODE_DIR}/nuget/ -COPY omnibus/Gemfile omnibus/dependabot-omnibus.gemspec ${CODE_DIR}/omnibus/ -COPY python/Gemfile python/dependabot-python.gemspec ${CODE_DIR}/python/ -COPY terraform/Gemfile terraform/dependabot-terraform.gemspec ${CODE_DIR}/terraform/ +ENV PATH="${CODE_DIR}/omnibus/.bundle/bin:$PATH" RUN GREEN='\033[0;32m'; NC='\033[0m'; \ - for d in `find ${CODE_DIR} -type f -mindepth 2 -maxdepth 2 \ - -not -path "${CODE_DIR}/omnibus/Gemfile" \ - -not -path "${CODE_DIR}/common/Gemfile" \ - -name 'Gemfile' | xargs dirname`; do \ - echo && \ - echo "---------------------------------------------------------------------------" && \ - echo "Installing gems for ${GREEN}$(realpath --relative-to=${CODE_DIR} $d)${NC}..." && \ - echo "---------------------------------------------------------------------------" && \ - cd $d && bundle install; \ - done - -RUN cd omnibus && bundle install -# Make omnibus gems available to bundler in root directory -RUN echo 'eval_gemfile File.join(File.dirname(__FILE__), "omnibus/Gemfile")' > Gemfile + for d in `find ${CODE_DIR} -type f -mindepth 2 -maxdepth 2 \ + -not -path "${CODE_DIR}/omnibus/Gemfile" \ + -name 'Gemfile' | xargs dirname`; do \ + echo && \ + echo "---------------------------------------------------------------------------" && \ + echo "Installing gems for ${GREEN}$(realpath --relative-to=${CODE_DIR} $d)${NC}..." && \ + echo "---------------------------------------------------------------------------" && \ + cd $d && bundle config path ${CODE_DIR}/omnibus/.bundle; \ + done # Create directory for volume containing VS Code extensions, to avoid reinstalling on image rebuilds RUN mkdir -p ~/.vscode-server ~/.vscode-server-insiders # Declare pass-thru environment variables used for debugging ENV LOCAL_GITHUB_ACCESS_TOKEN="" \ - LOCAL_CONFIG_VARIABLES="" + LOCAL_CONFIG_VARIABLES="" diff --git a/Dockerfile.updater b/Dockerfile.updater new file mode 100644 index 00000000000..609ee7aed9a --- /dev/null +++ b/Dockerfile.updater @@ -0,0 +1,62 @@ +ARG OMNIBUS_VERSION=required:fail_if_not_provided +FROM dependabot/dependabot-core:$OMNIBUS_VERSION + +ENV DEPENDABOT_HOME /home/dependabot + +RUN mkdir $DEPENDABOT_HOME/dependabot-updater + +COPY --chown=dependabot:dependabot updater/Gemfile updater/Gemfile.lock $DEPENDABOT_HOME/dependabot-updater/ + +COPY --chown=dependabot:dependabot .ruby-version ${DEPENDABOT_HOME}/.ruby-version +COPY --chown=dependabot:dependabot .rubocop.yml ${DEPENDABOT_HOME}/.rubocop.yml + +WORKDIR ${DEPENDABOT_HOME} +COPY --chown=dependabot:dependabot omnibus ${DEPENDABOT_HOME}/omnibus +COPY --chown=dependabot:dependabot git_submodules ${DEPENDABOT_HOME}/git_submodules +COPY --chown=dependabot:dependabot terraform ${DEPENDABOT_HOME}/terraform +COPY --chown=dependabot:dependabot github_actions ${DEPENDABOT_HOME}/github_actions +COPY --chown=dependabot:dependabot hex ${DEPENDABOT_HOME}/hex +COPY --chown=dependabot:dependabot elm ${DEPENDABOT_HOME}/elm +COPY --chown=dependabot:dependabot docker ${DEPENDABOT_HOME}/docker +COPY --chown=dependabot:dependabot nuget ${DEPENDABOT_HOME}/nuget +COPY --chown=dependabot:dependabot maven ${DEPENDABOT_HOME}/maven +COPY --chown=dependabot:dependabot gradle ${DEPENDABOT_HOME}/gradle +COPY --chown=dependabot:dependabot cargo ${DEPENDABOT_HOME}/cargo +COPY --chown=dependabot:dependabot composer ${DEPENDABOT_HOME}/composer +COPY --chown=dependabot:dependabot go_modules ${DEPENDABOT_HOME}/go_modules +COPY --chown=dependabot:dependabot python ${DEPENDABOT_HOME}/python +COPY --chown=dependabot:dependabot pub ${DEPENDABOT_HOME}/pub +COPY --chown=dependabot:dependabot npm_and_yarn ${DEPENDABOT_HOME}/npm_and_yarn +COPY --chown=dependabot:dependabot bundler ${DEPENDABOT_HOME}/bundler +COPY --chown=dependabot:dependabot common ${DEPENDABOT_HOME}/common + +WORKDIR $DEPENDABOT_HOME/dependabot-updater + +RUN bundle config set --local path 'vendor' && \ +bundle config set --local frozen 'true' && \ +bundle config set --local without 'development' && \ +bundle install + + +# START: HACKY WORKAROUND FOR NPM GIT INSTALLS SPAWNING CHILD PROCESS + +# TODO: Remove these hacks once we've deprecated npm 6 support as it no longer +# spawns a child process to npm install git dependencies. + +# Create the config file manually intead of using yarn/npm config set as this +# executes the package manager outputs to every job log +COPY --chown=dependabot:dependabot updater/config/.yarnrc updater/config/.npmrc $DEPENDABOT_HOME/ + +# For Yarn Berry we can set this via an environment variable +ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt + +# END: HACKY WORKAROUND FOR NPM GIT INSTALLS SPAWNING CHILD PROCESS + +# Add project +COPY --chown=dependabot:dependabot updater /home/dependabot/dependabot-updater + +# Fix for git vulnerability since we run as root +# see https://github.blog/2022-04-12-git-security-vulnerability-announced/ +RUN git config --global --add safe.directory /home/dependabot/dependabot-updater/repo + +CMD ["bundle", "exec", "ruby", "bin/dependabot_update.rb"] diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000000..c1296342ad4 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +eval_gemfile File.join(File.dirname(__FILE__), "omnibus/Gemfile") diff --git a/LICENSE b/LICENSE index 193822793b1..c3f2c9d3c09 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The Prosperity Public License 2.0.0 -Contributor: Dependabot Ltd +Contributor: GitHub Inc. Source Code: https://github.com/dependabot/dependabot-core diff --git a/README.md b/README.md index c23a74bfc05..2cc1d85ca6d 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,25 @@ -

- Dependabot -

- -# Dependabot +

+ + + + Dependabot + +

Welcome to the public home of Dependabot. This repository serves 2 purposes: 1. It houses the source code for Dependabot Core, which is the heart of [Dependabot][dependabot]. Dependabot Core handles the logic for updating dependencies on GitHub (including GitHub Enterprise), GitLab, and Azure DevOps. If you want to host your own automated dependency update bot then this repo should give you the tools you need. A reference implementation is available [here][dependabot-script]. -2. It is the public issue tracker for all things Dependabot, replacing the now-archived [feedback](https://github.com/dependabot/feedback/) repository. +2. It is the public issue tracker for issues related to Dependabot's updating logic. For issues about Dependabot the service, please contact [GitHub support][support]. While the distinction between Dependabot Core and the service can be fuzzy, a good rule of thumb is if your issue is with the _diff_ that Dependabot created, it belongs here and for most other things the GitHub support team is best equipped to help you. ## Got feedback? -Please file an issue. Bug reports, feature requests, and general feedback are all welcome. +https://github.com/github/feedback/discussions/categories/dependabot-feedback + +## Contributing to Dependabot + +Currently, the Dependabot team is not accepting support for new ecosystems. We are prioritising upgrades to already supported ecosystems at this time. -Currently the Dependabot team is at reduced capacity, because of this our response times on issues and contributions will be slower than we'd like. +Please refer to the [CONTRIBUTING][contributing] guidelines for more information. ### Disclosing security issues @@ -33,12 +39,24 @@ Highlights include: ## Other Dependabot resources -In addition to this library, you may be interested in: +In addition to this library, you may be interested in the [dependabot-script][dependabot-script] repo, +which provides a collection of scripts that use this library to update dependencies on GitHub Enterprise, GitLab, +BitBucket or Azure DevOps. + +## Cloning the repository +Clone the repository with Git using: + +``` +git clone https://github.com/dependabot/dependabot-core.git +``` + +On Windows this might fail with "Filename too long". To solve this, run the +following commands in the cloned Git repository: + +1. `git config core.longpaths true` +2. `git reset --hard` -- The [dependabot-script][dependabot-script] repo, which provides a collection - of scripts that use this library to update dependencies on GitHub Enterprise, - GitLab or Azure DevOps -- The [API docs][api-docs] for Dependabot's hosted instance (dependabot.com) +You can read more about this in the [Git for Windows wiki](https://github.com/git-for-windows/git/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path). ## Setup @@ -46,30 +64,121 @@ To run all of Dependabot Core, you'll need Ruby, Python, PHP, Elixir, Node, Go, Elm, and Rust installed. However, if you just wish to run it for a single language you can get away with just having that language and Ruby. -The main library is written in Ruby, while JavaScript, Python, PHP, Elm, -Elixir, Go, and Rust are required for dealing with updates for their respective -languages. +While you can run Dependabot Core without Docker, we provide a development +Dockerfile that bakes in all required dependencies. In most cases this is the +best way to work with the project. -To install the helpers for each language: +## Running with Docker -1. `cd npm_and_yarn/helpers && yarn install --production && cd -` -2. `cd composer/helpers && composer install --no-dev && cd -` -3. `cd python/helpers && pyenv exec pip install -r requirements.txt && cd -` -4. `cd hex/helpers && mix deps.get && cd -` -5. `cd terraform && helpers/build "$(pwd)/helpers/install-dir/terraform" && cd -` -6. `cd go_modules && helpers/build "$(pwd)/helpers/install-dir/go_modules" && cd -` +Start by pulling the developer image from the [GitHub Container Registry][ghcr-core-dev] and then start the developer shell: -## Local development +```shell +$ docker pull ghcr.io/dependabot/dependabot-core-development:latest +$ docker tag ghcr.io/dependabot/dependabot-core-development dependabot/dependabot-core-development +$ bin/docker-dev-shell +=> running docker development shell +[dependabot-core-dev] ~/dependabot-core $ +``` -Run the tests by running `rspec spec` inside each of the packages. Style is -enforced by RuboCop. To check for style violations, simply run `rubocop` in -each of the packages. +### Dry run script -### Running with Docker +You can use the "dry-run" script to simulate a dependency update job, printing +the diff that would be generated to the terminal. It takes two positional +arguments: the package manager and the GitHub repo name (including the +account): -While you can run Dependabot Core without Docker, we also provide a development -Dockerfile. In most cases, you'll be better off running Dependabot in the -development Docker container as it bakes in all required dependencies. +```bash +$ bin/docker-dev-shell +=> running docker development shell +$ bin/dry-run.rb go_modules rsc/quote +=> fetching dependency files +=> parsing dependency files +=> updating 2 dependencies +... +``` + +Note: If the dependency files are not in the top-level directory, then you must +also pass the path to the subdirectory as an argument: `--dir /`. + +### Running the tests + +Run the tests by running `rspec spec` inside each of the packages, e.g. + +```bash +$ cd go_modules +$ bundle exec rspec spec +``` + +Style is enforced by RuboCop. To check for style violations, simply run `rubocop` in +each of the packages, e.g. + +```bash +$ cd go_modules +$ bundle exec rubocop +``` + +### Making changes to native helpers + +Several Dependabot packages make use of 'native helpers', small executables in their host language. + +**Changes to these files are not automatically reflected inside the development container** + +Once you have made any edits to the helper files, run the appropriate build script to update the +installed version with your changes like so: + +```bash +$ bin/docker-dev-shell +=> running docker development shell +$ bundler/helpers/v1/build +$ bin/dry-run.rb bundler dependabot/demo --dir="/ruby" +``` + +### Debugging native helpers + +When you're making changes to native helpers or debugging a customer issue you often need to peek inside these scripts that run in a separate process. + +Print all log statements from native helpers: + +```bash +DEBUG_HELPERS=true bin/dry-run.rb bundler dependabot/demo --dir="/ruby" +``` + +Pause execution to debug a single native helper function: + +```bash +DEBUG_FUNCTION=parsed_gemfile bin/dry-run.rb bundler dependabot/demo --dir="/ruby" +``` + +The function maps to a native helper function name, for example, one of the functions in `bundler/helpers/v2/lib/functions.rb`. + +When this function is being executed a `debugger` is inserted, pausing execution of the `bin/dry-run.rb` script, this leaves the current updates tmp directory in place allowing you to cd into the directory and run the native helper function directly: + +```bash + DEBUG_FUNCTION=parsed_gemfile bin/dry-run.rb bundler dependabot/demo --dir="/ruby" +=> fetching dependency files +=> dumping fetched dependency files: ./dry-run/dependabot/demo/ruby +=> parsing dependency files +$ cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo "{\"function\":\"parsed_gemfile\",\"args\":{\"gemfile_name\":\"Gemfile\",\"lockfile_name\":\"Gemfile.lock\",\"dir\":\"/home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby\"}}" | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb +``` + +Copy and run the `cd... ` command: + +```bash +cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo "{\"function\":\"parsed_gemfile\",\"args\":{\"gemfile_name\":\"Gemfile\",\"lockfile_name\":\"Gemfile.lock\",\"dir\":\"/home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby\"}}" | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb +``` + +This should log out the output of the `parsed_gemfile` function: + +``` +{"result":[{"name":"business","requirement":"~> 1.0.0","groups":["default"],"source":null,"type":"runtime"},{"name":"uk_phone_numbers","requirement":"~> 0.1.0","groups":["default"],"source":null,"type":"runtime"}]} +``` + +Edit the native helper function and re-run the above, for example: `vi /opt/bundler/v1/lib/functions/file_parser.rb`. + +### Building the development image from source + +The developer shell uses volume mounts to incorporate your local changes to Dependabot's source +code. If you need to make changes to the development shell itself, you can rebuild it locally. Start by building the initial Dependabot Core image, or pull it from the Docker registry. @@ -92,32 +201,20 @@ $ bin/docker-dev-shell => building image from Dockerfile.development => running docker development shell [dependabot-core-dev] ~/dependabot-core $ +[dependabot-core-dev] ~/dependabot-core $ cd go_modules && rspec spec # to run tests for a particular package ``` -### Dry run script +## Running locally on your computer -*Note: you must have run `bundle install` in the `omnibus` directory before -running this script.* +To work with Dependabot packages on your local machine you will need Ruby and the package's specific language installed. -You can use the "dry-run" script to simulate a dependency update job, printing -the diff that would be generated to the terminal. It takes two positional -arguments: the package manager and the GitHub repo name (including the -account): - -```bash -$ cd omnibus && bundle install && cd - -$ bin/dry-run.rb go_modules rsc/quote -=> fetching dependency files -=> parsing dependency files -=> updating 2 dependencies -... -``` +For some languages there are additional steps required, please refer to the README file in each package. ## Debugging with Visual Studio Code and Docker There's built-in support for leveraging Visual Studio Code's [ability for -debugging](https://code.visualstudio.com/docs/remote/containers) inside a Docker container. -After installing the recommended [`Remote - Containers` extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers), +debugging][vsc-remote-containers] inside a Docker container. +After installing the recommended [`Remote - Containers` extension][vsc-remote-containers-ext], simply press `Ctrl+Shift+P` (`⇧⌘P` on macOS) and select `Remote-Containers: Reopen in Container`. You can also access the dropdown by clicking on the green button in the bottom-left corner of the editor. If the development Docker image isn't present on your machine, it will be built automatically. @@ -125,6 +222,14 @@ Once that's finished, start the `Debug Dry Run` configuration `(F5)` and you'll to select a package manager and a repository to perform a dry run on. Feel free to place breakpoints on the code. +There is also support to debug individual test runs by running the `Debug Tests` configuration `(F5)` +and you'll be prompted to select an ecosystem and provide an rspec path. + +⚠ī¸ The `Clone Repository ...` commands of the Remote Containers extension are currently +missing some functionality and are therefore not supported. You have to clone the +repository manually and use the `Reopen in Container` or `Open Folder in Container...` +command. + ## Releasing Triggering the jobs that will push the new gems is done by following the steps below. @@ -166,9 +271,7 @@ classes: The high-level flow looks like this: -

- Dependabot architecture -

+![Dependabot high-level architecture diagram](architecture.svg) ### `dependabot-omnibus` @@ -176,6 +279,14 @@ This is a "meta" gem, that simply depends on all the others. If you want to automatically include support for all languages, you can just include this gem and you'll get all you need. +## Profiling + +You can profile a dry-run by passing the `--profile` flag when running it, or +tag an rspec test with `:profile`. This will generate a +`stackprof-.dump` file in the `tmp/` folder, and you can generate a +flamegraph from this by running: +`stackprof --d3-flamegraph tmp/stackprof-.dump > tmp/flamegraph.html`. + ## Why is this public? As the name suggests, Dependabot Core is the core of Dependabot (the rest of the @@ -203,7 +314,7 @@ the following: arrangement. If you make a significant contribution to Dependabot Core then you will be asked -to transfer the IP of that contribution to Dependabot Ltd so that it can be +to transfer the IP of that contribution to GitHub Inc. so that it can be licensed in the same way as the above. ## History @@ -214,10 +325,15 @@ Dependabot and Dependabot Core started life as [Bump][bump] and GoCardless in helping make Dependabot possible - if you need to collect recurring payments from Europe, check them out. + [dependabot]: https://dependabot.com [dependabot-status]: https://api.dependabot.com/badges/status?host=github&identifier=93163073 [dependabot-script]: https://github.com/dependabot/dependabot-script -[api-docs]: https://github.com/dependabot/api-docs +[contributing]: https://github.com/dependabot/dependabot-core/blob/main/CONTRIBUTING.md [bump]: https://github.com/gocardless/bump [bump-core]: https://github.com/gocardless/bump-core [gocardless]: https://gocardless.com +[ghcr-core-dev]: https://github.com/dependabot/dependabot-core/pkgs/container/dependabot-core-development +[support]: https://support.github.com/ +[vsc-remote-containers]: https://code.visualstudio.com/docs/remote/containers +[vsc-remote-containers-ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers diff --git a/Rakefile b/Rakefile index d9c13c63396..60ad27e8b9d 100644 --- a/Rakefile +++ b/Rakefile @@ -9,6 +9,7 @@ require "shellwords" require "rubygems/package" require "bundler" require "./common/lib/dependabot/version" +require "yaml" GEMSPECS = %w( common/dependabot-common.gemspec @@ -23,11 +24,11 @@ GEMSPECS = %w( bundler/dependabot-bundler.gemspec elm/dependabot-elm.gemspec cargo/dependabot-cargo.gemspec - dep/dependabot-dep.gemspec npm_and_yarn/dependabot-npm_and_yarn.gemspec composer/dependabot-composer.gemspec hex/dependabot-hex.gemspec python/dependabot-python.gemspec + pub/dependabot-pub.gemspec omnibus/dependabot-omnibus.gemspec ).freeze @@ -36,24 +37,6 @@ def run_command(command) exit 1 unless system(command) end -namespace :ci do - task :rubocop do - packages = changed_packages - puts "Running rubocop on: #{packages.join(', ')}" - packages.each do |package| - run_command("cd #{package} && bundle exec rubocop -c ../.rubocop.yml") - end - end - - task :rspec do - packages = changed_packages - puts "Running rspec on: #{packages.join(', ')}" - packages.each do |package| - run_command("cd #{package} && bundle exec rspec spec") - end - end -end - # rubocop:disable Metrics/BlockLength namespace :gems do task build: :clean do @@ -104,6 +87,25 @@ namespace :gems do end end +class Hash + def sort_by_key(recursive = false, &block) + keys.sort(&block).each_with_object({}) do |key, seed| + seed[key] = self[key] + seed[key] = seed[key].sort_by_key(true, &block) if recursive && seed[key].is_a?(Hash) + seed + end + end +end + +namespace :rubocop do + task :sort do + File.write( + ".rubocop.yml", + YAML.load_file(".rubocop.yml").sort_by_key(true).to_yaml + ) + end +end + def guard_tag_match tag = "v#{Dependabot::VERSION}" tag_commit = `git rev-list -n 1 #{tag} 2> /dev/null`.strip @@ -131,7 +133,7 @@ def changed_packages select { |gs| gs.include?("/") }. map { |gs| "./" + gs.split("/").first } - compare_url = ENV["CIRCLE_COMPARE_URL"] + compare_url = ENV.fetch("CIRCLE_COMPARE_URL", nil) if compare_url.nil? warn "CIRCLE_COMPARE_URL not set, so changed packages can't be calculated" return all_packages diff --git a/SECURITY.md b/SECURITY.md index 02b968c9db7..d9ca9342c30 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1 +1,11 @@ -If you believe you have found a security vulnerability in Dependabot please submit the vulnerability to GitHub Security [Bug Bounty](https://bounty.github.com/) so that we can resolve the issue before it is disclosed publicly. +GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). + +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. + +If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly using [private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability). + +If the vulnerability you have found is [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) and you would like for your finding to be considered for a bounty reward, please submit the vulnerability to us through [HackerOne](https://hackerone.com/github) in order to be eligible to receive a bounty award. + +**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.** + +Thanks for helping make GitHub safe for everyone. diff --git a/architecture.svg b/architecture.svg new file mode 100644 index 00000000000..42c81cfa820 --- /dev/null +++ b/architecture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bin/bump-version.rb b/bin/bump-version.rb index 3adea279fec..6a2728f88b1 100755 --- a/bin/bump-version.rb +++ b/bin/bump-version.rb @@ -2,10 +2,55 @@ # frozen_string_literal: true unless %w(minor patch).include?(ARGV[0]) - puts "usage: bin/bump-version.rb minor|patch" + puts "usage: bin/bump-version.rb minor|patch [--dry-run]" exit 1 end component = ARGV[0].to_sym +dry_run = ARGV[1] == "--dry-run" + +# rubocop:disable Lint/LiteralAsCondition +unless `which gh` && $?.success? + puts "Please install the gh cli: brew install gh" + exit 1 +end + +unless `gh auth status -h github.com > /dev/null 2>&1` && $?.success? + puts "Please login to GitHub first: gh auth login" + exit 1 +end +# rubocop:enable Lint/LiteralAsCondition + +CHANGELOG_PATH = File.join(__dir__, "..", "CHANGELOG.md") +CHANGELOG_CONTENTS = File.read(CHANGELOG_PATH) + +def proposed_changes(version, _new_version) + dependabot_team = `gh api -X GET 'orgs/dependabot/teams/maintainers/members' --jq '.[].login'` + dependabot_team = dependabot_team.split("\n").map(&:strip) + ["dependabot"] + + commit_subjects = `git log --pretty="%s" v#{version}..HEAD`.lines + merge_subjects = commit_subjects.select do |s| + s.downcase.start_with?("merge pull request #") && !s.match?(/release[-_\s]notes/i) + end + pr_numbers = merge_subjects.map { |s| s.match(/#(\d+)/)[1].to_i } + puts "âŗ fetching pull request details" + pr_details = pr_numbers.map do |pr_number| + pr_details = `gh pr view #{pr_number} --json title,author --jq ".title,.author.login"` + title, author = pr_details.split("\n").map(&:strip) + { + title: title, + author: author, + number: pr_number, + link: "https://github.com/dependabot/dependabot-core/pull/#{pr_number}" + } + end + + pr_details.map do |details| + line = "- #{details[:title]}" + line += " (@#{details[:author]})" unless dependabot_team.include?(details[:author]) + line += " [##{details[:number]}](#{details[:link]})" + line + end +end # Update version file version_path = File.join(__dir__, "..", "common", "lib", "dependabot", @@ -23,33 +68,47 @@ end new_version_contents = version_contents.gsub(version, new_version) -File.open(version_path, "w") { |f| f.write(new_version_contents) } -puts "✓ common/lib/dependabot/version.rb updated" +if dry_run + puts "Would update version file:" + puts new_version_contents +else + File.write(version_path, new_version_contents) + puts "☑ī¸ common/lib/dependabot/version.rb updated" + +end + +proposed_changes = proposed_changes(version, new_version) # Update CHANGELOG +if dry_run + puts "Would update CHANGELOG:" + puts proposed_changes +else + new_changelog_contents = [ + "## v#{new_version}, #{Time.now.strftime('%e %B %Y').strip}\n", + proposed_changes.join("\n") + "\n", + CHANGELOG_CONTENTS + ].join("\n") -changelog_path = File.join(__dir__, "..", "CHANGELOG.md") -changelog_contents = File.read(changelog_path) - -commit_subjects = `git log --pretty="%s" v#{version}..HEAD`.lines -proposed_changes = commit_subjects.map { |line| "- #{line}" }.join("") - -new_changelog_contents = [ - "## v#{new_version}, #{Time.now.strftime('%e %B %Y').strip}\n", - proposed_changes, - changelog_contents -].join("\n") -File.open(changelog_path, "w") { |f| f.write(new_changelog_contents) } - -puts "✓ CHANGELOG.md updated" -puts -puts "Double check the changes (editing CHANGELOG.md where necessary), then" -puts "commit, tag, and push the release:" -puts -puts "git add CHANGELOG.md common/lib/dependabot/version.rb" -puts "git commit -m 'v#{new_version}'" -puts "git push origin main" -puts "git tag 'v#{new_version}'" -puts "git push --tags origin main" -puts + File.write(CHANGELOG_PATH, new_changelog_contents) + puts "☑ī¸ CHANGELOG.md updated" +end + +unless dry_run + puts + puts "Double check the changes (editing CHANGELOG.md where necessary), then" + puts "commit, tag, and push the release:" + puts + puts "git checkout -b v#{new_version}-release-notes" + puts "git add CHANGELOG.md common/lib/dependabot/version.rb" + puts "git commit -m 'v#{new_version}'" + puts "git push origin HEAD:v#{new_version}-release-notes" + puts "# ... create PR, verify, merge, for example:" + puts "gh pr create" + puts "# tag the approved release notes:" + puts "git fetch" + puts "git tag 'v#{new_version}' 'origin/v#{new_version}-release-notes'" + puts "git push origin v#{new_version}" + puts +end diff --git a/bin/ci-test b/bin/ci-test new file mode 100755 index 00000000000..5c1b3332db0 --- /dev/null +++ b/bin/ci-test @@ -0,0 +1,57 @@ +#!/bin/bash -e +#/ usage: ci-test SUITE +#/ simulate the process followed by ~/.github/workflows/ci.yml + +function print_usage() { + grep ^#/ "$0" | cut -c4- +} + +function handle_args() { + export SUITE=$1 + case $SUITE in + bundler1 | bundler2) + export MODULE=bundler + ;; + "") + print_usage + exit 1 + ;; + *) + export MODULE=$SUITE + esac + + if ! [ -d "$MODULE" ]; then + print_usage + echo "module not found, try:" + for m in */*.gemspec; do + [[ "$m" == "omnibus" ]] && continue + echo -n " "; dirname "$m" + done + exit 1 + fi +} + +function build() { + export DOCKER_BUILDKIT=1 + export DOCKER_SCAN_SUGGEST=false + export CORE=dependabot/dependabot-core + export CI=dependabot/dependabot-core-ci + + set -x + docker build -qt $CORE . + docker build -qt $CI -f Dockerfile.ci . + docker run --rm \ + -e "CI=true" \ + -e "SUITE_NAME=$SUITE" \ + -e "DEPENDABOT_TEST_ACCESS_TOKEN=${LOCAL_GITHUB_ACCESS_TOKEN}" \ + -it $CI \ + bash -c \ + "cd /home/dependabot/dependabot-core/$MODULE && ./script/ci-test" +} + +function main() { + handle_args "$@" + build +} + +main "$@" diff --git a/bin/docker-dev-shell b/bin/docker-dev-shell index c14dbb2092a..d5b5e391f79 100755 --- a/bin/docker-dev-shell +++ b/bin/docker-dev-shell @@ -3,11 +3,17 @@ set -e IMAGE_NAME="${IMAGE_NAME:=dependabot/dependabot-core-development}" +CONTAINER_NAME="${CONTAINER_NAME:=dependabot-core-development}" DOCKERFILE="Dockerfile.development" HELP=false REBUILD=false -OPTS=`getopt -o hr --long help,rebuild -n 'parse-options' -- "$@"` +# Enable docker buildkit with inline cache builds +export DOCKER_BUILDKIT=1 + +# shellcheck disable=SC2034 +OPTS=$(getopt -o hr --long help,rebuild -n 'parse-options' -- "$@") +# shellcheck disable=SC2181 if [ $? != 0 ]; then echo "failed parsing options" >&2 exit 1 @@ -28,10 +34,26 @@ if [ "$HELP" = "true" ]; then fi build_image() { + export BUILT_IMAGE=true echo "$(tput setaf 2)=> building image from Dockerfile$(tput sgr0)" - docker build -t dependabot/dependabot-core . + + local TARGETARCH; + case "$(uname -m)" + in + amd64 | x86_64) TARGETARCH=amd64 ;; + arm64 | aarch64) TARGETARCH=arm64 ;; + *) TARGETARCH=amd64 ;; + esac + + docker build \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --build-arg "TARGETARCH=${TARGETARCH}" \ + --build-arg "USER_UID=$(id -u)" \ + --build-arg "USER_GID=$(id -g)" \ + --cache-from "dependabot/dependabot-core:latest" \ + -t dependabot/dependabot-core . echo "$(tput setaf 2)=> building image from $DOCKERFILE$(tput sgr0)" - docker build --build-arg "USER_UID=$UID" --build-arg "USER_GID=$(id -g)" -t "$IMAGE_NAME" -f "$DOCKERFILE" . + docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t "$IMAGE_NAME" -f "$DOCKERFILE" . } IMAGE_ID=$(docker inspect --type=image -f '{{.Id}}' "$IMAGE_NAME" 2> /dev/null || true) @@ -45,14 +67,26 @@ else echo "$(tput setaf 4) > image $IMAGE_NAME already exists$(tput sgr0)" fi -DOCKER_OPTS=() -if [ -n "$HTTP_PROXY" ]; then - DOCKER_OPTS+=(-e "http_proxy=$HTTP_PROXY") - DOCKER_OPTS+=(-e "HTTP_PROXY=$HTTP_PROXY") +set +e +RUNNING=$(docker ps --format '{{.Names}}' | grep "$CONTAINER_NAME$") +set -e +echo "$RUNNING" +if [ -n "$RUNNING" ]; then + if [ -z "$BUILT_IMAGE" ]; then + # image was not rebuilt - can we reuse existing? + exec docker exec -ti "$CONTAINER_NAME" bash + else + # image was rebuilt - exit running container + docker stop "$CONTAINER_NAME" + fi fi -if [ -n "$HTTPS_PROXY" ]; then - DOCKER_OPTS+=(-e "https_proxy=$HTTPS_PROXY") - DOCKER_OPTS+=(-e "HTTPS_PROXY=$HTTPS_PROXY") + +DOCKER_OPTS=() +if [ -n "$DEPENDABOT_PROXY" ]; then + DOCKER_OPTS+=(-e "http_proxy=$DEPENDABOT_PROXY") + DOCKER_OPTS+=(-e "HTTP_PROXY=$DEPENDABOT_PROXY") + DOCKER_OPTS+=(-e "https_proxy=$DEPENDABOT_PROXY") + DOCKER_OPTS+=(-e "HTTPS_PROXY=$DEPENDABOT_PROXY") fi if [ -n "$DOCKER_NETWORK" ]; then @@ -71,82 +105,125 @@ docker run --rm -ti \ -v "$(pwd)/.core-bash_history:/home/dependabot/.bash_history" \ -v "$(pwd)/.rubocop.yml:$CODE_DIR/.rubocop.yml" \ -v "$(pwd)/bin:$CODE_DIR/bin" \ + -v "$(pwd)/dry-run:$CODE_DIR/dry-run" \ + -v "$(pwd)/common/.rubocop.yml:$CODE_DIR/common/.rubocop.yml" \ -v "$(pwd)/common/Gemfile:$CODE_DIR/common/Gemfile" \ -v "$(pwd)/common/dependabot-common.gemspec:$CODE_DIR/common/dependabot-common.gemspec" \ -v "$(pwd)/common/bin:$CODE_DIR/common/bin" \ -v "$(pwd)/common/lib:$CODE_DIR/common/lib" \ -v "$(pwd)/common/spec:$CODE_DIR/common/spec" \ + -v "$(pwd)/common/script:$CODE_DIR/common/script" \ + -v "$(pwd)/terraform/.rubocop.yml:$CODE_DIR/terraform/.rubocop.yml" \ -v "$(pwd)/terraform/Gemfile:$CODE_DIR/terraform/Gemfile" \ -v "$(pwd)/terraform/dependabot-terraform.gemspec:$CODE_DIR/terraform/dependabot-terraform.gemspec" \ + -v "$(pwd)/terraform/helpers:$CODE_DIR/terraform/helpers" \ -v "$(pwd)/terraform/lib:$CODE_DIR/terraform/lib" \ -v "$(pwd)/terraform/spec:$CODE_DIR/terraform/spec" \ + -v "$(pwd)/terraform/script:$CODE_DIR/terraform/script" \ + -v "$(pwd)/elm/.rubocop.yml:$CODE_DIR/elm/.rubocop.yml" \ -v "$(pwd)/elm/Gemfile:$CODE_DIR/elm/Gemfile" \ -v "$(pwd)/elm/dependabot-elm.gemspec:$CODE_DIR/elm/dependabot-elm.gemspec" \ -v "$(pwd)/elm/lib:$CODE_DIR/elm/lib" \ -v "$(pwd)/elm/spec:$CODE_DIR/elm/spec" \ + -v "$(pwd)/elm/script:$CODE_DIR/elm/script" \ + -v "$(pwd)/docker/.rubocop.yml:$CODE_DIR/docker/.rubocop.yml" \ -v "$(pwd)/docker/Gemfile:$CODE_DIR/docker/Gemfile" \ -v "$(pwd)/docker/dependabot-docker.gemspec:$CODE_DIR/docker/dependabot-docker.gemspec" \ -v "$(pwd)/docker/lib:$CODE_DIR/docker/lib" \ -v "$(pwd)/docker/spec:$CODE_DIR/docker/spec" \ + -v "$(pwd)/docker/script:$CODE_DIR/docker/script" \ + -v "$(pwd)/git_submodules/.rubocop.yml:$CODE_DIR/git_submodules/.rubocop.yml" \ -v "$(pwd)/git_submodules/Gemfile:$CODE_DIR/git_submodules/Gemfile" \ - -v "$(pwd)/git_submodules/dependabot-git_submodules.gemspec:$CODE_DIR/git_submodules/dependabot-core.gemspec" \ + -v "$(pwd)/git_submodules/dependabot-git_submodules.gemspec:$CODE_DIR/git_submodules/dependabot-git_submodules.gemspec" \ -v "$(pwd)/git_submodules/lib:$CODE_DIR/git_submodules/lib" \ -v "$(pwd)/git_submodules/spec:$CODE_DIR/git_submodules/spec" \ + -v "$(pwd)/git_submodules/script:$CODE_DIR/git_submodules/script" \ + -v "$(pwd)/github_actions/.rubocop.yml:$CODE_DIR/github_actions/.rubocop.yml" \ -v "$(pwd)/github_actions/Gemfile:$CODE_DIR/github_actions/Gemfile" \ - -v "$(pwd)/github_actions/dependabot-github_actions.gemspec:$CODE_DIR/github_actions/dependabot-core.gemspec" \ + -v "$(pwd)/github_actions/dependabot-github_actions.gemspec:$CODE_DIR/github_actions/dependabot-github_actions.gemspec" \ -v "$(pwd)/github_actions/lib:$CODE_DIR/github_actions/lib" \ -v "$(pwd)/github_actions/spec:$CODE_DIR/github_actions/spec" \ + -v "$(pwd)/github_actions/script:$CODE_DIR/github_actions/script" \ + -v "$(pwd)/python/.rubocop.yml:$CODE_DIR/python/.rubocop.yml" \ -v "$(pwd)/python/Gemfile:$CODE_DIR/python/Gemfile" \ -v "$(pwd)/python/dependabot-python.gemspec:$CODE_DIR/python/dependabot-python.gemspec" \ - -v "$(pwd)/python/helpers:/opt/python" \ - -v "$(pwd)/python/helpers:/opt/python/helpers" \ + -v "$(pwd)/python/helpers:$CODE_DIR/python/helpers" \ -v "$(pwd)/python/lib:$CODE_DIR/python/lib" \ -v "$(pwd)/python/spec:$CODE_DIR/python/spec" \ + -v "$(pwd)/python/script:$CODE_DIR/python/script" \ + -v "$(pwd)/pub/.rubocop.yml:$CODE_DIR/pub/.rubocop.yml" \ + -v "$(pwd)/pub/Gemfile:$CODE_DIR/pub/Gemfile" \ + -v "$(pwd)/pub/dependabot-pub.gemspec:$CODE_DIR/pub/dependabot-pub.gemspec" \ + -v "$(pwd)/pub/lib:$CODE_DIR/pub/lib" \ + -v "$(pwd)/pub/spec:$CODE_DIR/pub/spec" \ + -v "$(pwd)/pub/script:$CODE_DIR/pub/script" \ + -v "$(pwd)/nuget/.rubocop.yml:$CODE_DIR/nuget/.rubocop.yml" \ -v "$(pwd)/nuget/Gemfile:$CODE_DIR/nuget/Gemfile" \ - -v "$(pwd)/nuget/dependabot-nuget.gemspec:$CODE_DIR/nuget/dependabot-core.gemspec" \ + -v "$(pwd)/nuget/dependabot-nuget.gemspec:$CODE_DIR/nuget/dependabot-nuget.gemspec" \ -v "$(pwd)/nuget/lib:$CODE_DIR/nuget/lib" \ -v "$(pwd)/nuget/spec:$CODE_DIR/nuget/spec" \ + -v "$(pwd)/nuget/script:$CODE_DIR/nuget/script" \ + -v "$(pwd)/maven/.rubocop.yml:$CODE_DIR/maven/.rubocop.yml" \ -v "$(pwd)/maven/Gemfile:$CODE_DIR/maven/Gemfile" \ - -v "$(pwd)/maven/dependabot-maven.gemspec:$CODE_DIR/maven/dependabot-core.gemspec" \ + -v "$(pwd)/maven/dependabot-maven.gemspec:$CODE_DIR/maven/dependabot-maven.gemspec" \ -v "$(pwd)/maven/lib:$CODE_DIR/maven/lib" \ -v "$(pwd)/maven/spec:$CODE_DIR/maven/spec" \ + -v "$(pwd)/maven/script:$CODE_DIR/maven/script" \ + -v "$(pwd)/gradle/.rubocop.yml:$CODE_DIR/gradle/.rubocop.yml" \ -v "$(pwd)/gradle/Gemfile:$CODE_DIR/gradle/Gemfile" \ -v "$(pwd)/gradle/dependabot-gradle.gemspec:$CODE_DIR/gradle/dependabot-gradle.gemspec" \ -v "$(pwd)/gradle/lib:$CODE_DIR/gradle/lib" \ -v "$(pwd)/gradle/spec:$CODE_DIR/gradle/spec" \ + -v "$(pwd)/gradle/script:$CODE_DIR/gradle/script" \ + -v "$(pwd)/hex/.rubocop.yml:$CODE_DIR/hex/.rubocop.yml" \ -v "$(pwd)/hex/Gemfile:$CODE_DIR/hex/Gemfile" \ -v "$(pwd)/hex/dependabot-hex.gemspec:$CODE_DIR/hex/dependabot-hex.gemspec" \ + -v "$(pwd)/hex/helpers:$CODE_DIR/hex/helpers" \ -v "$(pwd)/hex/lib:$CODE_DIR/hex/lib" \ -v "$(pwd)/hex/spec:$CODE_DIR/hex/spec" \ + -v "$(pwd)/hex/script:$CODE_DIR/hex/script" \ + -v "$(pwd)/cargo/.rubocop.yml:$CODE_DIR/cargo/.rubocop.yml" \ -v "$(pwd)/cargo/Gemfile:$CODE_DIR/cargo/Gemfile" \ - -v "$(pwd)/cargo/dependabot-cargo.gemspec:$CODE_DIR/cargo/dependabot-core.gemspec" \ + -v "$(pwd)/cargo/dependabot-cargo.gemspec:$CODE_DIR/cargo/dependabot-cargo.gemspec" \ -v "$(pwd)/cargo/lib:$CODE_DIR/cargo/lib" \ -v "$(pwd)/cargo/spec:$CODE_DIR/cargo/spec" \ - -v "$(pwd)/dep/Gemfile:$CODE_DIR/dep/Gemfile" \ - -v "$(pwd)/dep/dependabot-dep.gemspec:$CODE_DIR/dep/dependabot-dep.gemspec" \ - -v "$(pwd)/dep/lib:$CODE_DIR/dep/lib" \ - -v "$(pwd)/dep/spec:$CODE_DIR/dep/spec" \ + -v "$(pwd)/cargo/script:$CODE_DIR/cargo/script" \ + -v "$(pwd)/go_modules/.rubocop.yml:$CODE_DIR/go_modules/.rubocop.yml" \ -v "$(pwd)/go_modules/Gemfile:$CODE_DIR/go_modules/Gemfile" \ -v "$(pwd)/go_modules/dependabot-go_modules.gemspec:$CODE_DIR/go_modules/dependabot-go_modules.gemspec" \ + -v "$(pwd)/go_modules/helpers:$CODE_DIR/go_modules/helpers" \ -v "$(pwd)/go_modules/lib:$CODE_DIR/go_modules/lib" \ -v "$(pwd)/go_modules/spec:$CODE_DIR/go_modules/spec" \ + -v "$(pwd)/go_modules/script:$CODE_DIR/go_modules/script" \ + -v "$(pwd)/npm_and_yarn/.rubocop.yml:$CODE_DIR/npm_and_yarn/.rubocop.yml" \ -v "$(pwd)/npm_and_yarn/Gemfile:$CODE_DIR/npm_and_yarn/Gemfile" \ -v "$(pwd)/npm_and_yarn/dependabot-npm_and_yarn.gemspec:$CODE_DIR/npm_and_yarn/dependabot-npm_and_yarn.gemspec" \ + -v "$(pwd)/npm_and_yarn/helpers:$CODE_DIR/npm_and_yarn/helpers" \ -v "$(pwd)/npm_and_yarn/lib:$CODE_DIR/npm_and_yarn/lib" \ -v "$(pwd)/npm_and_yarn/spec:$CODE_DIR/npm_and_yarn/spec" \ + -v "$(pwd)/npm_and_yarn/script:$CODE_DIR/npm_and_yarn/script" \ + -v "$(pwd)/composer/.rubocop.yml:$CODE_DIR/composer/.rubocop.yml" \ -v "$(pwd)/composer/Gemfile:$CODE_DIR/composer/Gemfile" \ -v "$(pwd)/composer/dependabot-composer.gemspec:$CODE_DIR/composer/dependabot-composer.gemspec" \ + -v "$(pwd)/composer/helpers:$CODE_DIR/composer/helpers" \ -v "$(pwd)/composer/lib:$CODE_DIR/composer/lib" \ -v "$(pwd)/composer/spec:$CODE_DIR/composer/spec" \ + -v "$(pwd)/composer/script:$CODE_DIR/composer/script" \ + -v "$(pwd)/bundler/.rubocop.yml:$CODE_DIR/bundler/.rubocop.yml" \ -v "$(pwd)/bundler/Gemfile:$CODE_DIR/bundler/Gemfile" \ -v "$(pwd)/bundler/dependabot-bundler.gemspec:$CODE_DIR/bundler/dependabot-bundler.gemspec" \ -v "$(pwd)/bundler/lib:$CODE_DIR/bundler/lib" \ + -v "$(pwd)/bundler/helpers:$CODE_DIR/bundler/helpers" \ -v "$(pwd)/bundler/spec:$CODE_DIR/bundler/spec" \ + -v "$(pwd)/bundler/script:$CODE_DIR/bundler/script" \ + -v "$(pwd)/omnibus/.rubocop.yml:$CODE_DIR/omnibus/.rubocop.yml" \ -v "$(pwd)/omnibus/Gemfile:$CODE_DIR/omnibus/Gemfile" \ -v "$(pwd)/omnibus/dependabot-omnibus.gemspec:$CODE_DIR/omnibus/dependabot-omnibus.gemspec" \ -v "$(pwd)/omnibus/lib:$CODE_DIR/omnibus/lib" \ - -v "$(pwd)/omnibus/spec:$CODE_DIR/omnibus/spec" \ - -v "$(pwd)/dry-run:$CODE_DIR/dry-run" \ + -v "$(pwd)/omnibus/script:$CODE_DIR/omnibus/script" \ + -v "$(pwd)/tmp:/$CODE_DIR/tmp" \ + --name "$CONTAINER_NAME" \ + --env "LOCAL_GITHUB_ACCESS_TOKEN=$LOCAL_GITHUB_ACCESS_TOKEN" \ "${DOCKER_OPTS[@]}" \ --cap-add=SYS_PTRACE \ "$IMAGE_NAME" "${CONTAINER_ARGS[@]}" diff --git a/bin/dry-run.rb b/bin/dry-run.rb index 300789543e9..1ac98d22fc4 100755 --- a/bin/dry-run.rb +++ b/bin/dry-run.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true -# This script is does a full update run for a given repo (optionally for a +# This script executes a full update run for a given repo (optionally for a # specific dependency only), and shows the proposed changes to any dependency # files without actually creating a pull request. # @@ -27,20 +27,29 @@ # - hex # - composer # - nuget -# - dep # - go_modules # - elm # - submodules # - docker # - terraform +# - pub # rubocop:disable Style/GlobalVars +require "etc" +unless Etc.getpwuid(Process.uid).name == "dependabot" || ENV["ALLOW_DRY_RUN_STANDALONE"] == "true" + puts <<~INFO + bin/dry-run.rb is only supported in a development container. + + Please use bin/docker-dev-shell first. + INFO + exit 1 +end + $LOAD_PATH << "./bundler/lib" $LOAD_PATH << "./cargo/lib" $LOAD_PATH << "./common/lib" $LOAD_PATH << "./composer/lib" -$LOAD_PATH << "./dep/lib" $LOAD_PATH << "./docker/lib" $LOAD_PATH << "./elm/lib" $LOAD_PATH << "./git_submodules/lib" @@ -52,6 +61,7 @@ $LOAD_PATH << "./npm_and_yarn/lib" $LOAD_PATH << "./nuget/lib" $LOAD_PATH << "./python/lib" +$LOAD_PATH << "./pub/lib" $LOAD_PATH << "./terraform/lib" require "bundler" @@ -60,18 +70,23 @@ require "optparse" require "json" -require "byebug" +require "debug" +require "logger" +require "dependabot/logger" +require "stackprof" + +Dependabot.logger = Logger.new($stdout) require "dependabot/file_fetchers" require "dependabot/file_parsers" require "dependabot/update_checkers" require "dependabot/file_updaters" require "dependabot/pull_request_creator" +require "dependabot/config/file_fetcher" require "dependabot/bundler" require "dependabot/cargo" require "dependabot/composer" -require "dependabot/dep" require "dependabot/docker" require "dependabot/elm" require "dependabot/git_submodules" @@ -83,6 +98,7 @@ require "dependabot/npm_and_yarn" require "dependabot/nuget" require "dependabot/python" +require "dependabot/pub" require "dependabot/terraform" # GitHub credentials with write permission to the repo you want to update @@ -91,14 +107,22 @@ $options = { credentials: [], + provider: "github", directory: "/", - dependency_name: nil, + dependency_names: nil, branch: nil, cache_steps: [], write: false, + clone: false, lockfile_only: false, + reject_external_code: false, requirements_update_strategy: nil, - commit: nil + commit: nil, + updater_options: {}, + security_advisories: [], + security_updates_only: false, + ignore_conditions: [], + pull_request: false } unless ENV["LOCAL_GITHUB_ACCESS_TOKEN"].to_s.strip.empty? @@ -106,7 +130,7 @@ "type" => "git_source", "host" => "github.com", "username" => "x-access-token", - "password" => ENV["LOCAL_GITHUB_ACCESS_TOKEN"] + "password" => ENV.fetch("LOCAL_GITHUB_ACCESS_TOKEN", nil) } end @@ -114,12 +138,32 @@ # For example: # "[{\"type\":\"npm_registry\",\"registry\":\ # "registry.npmjs.org\",\"token\":\"123\"}]" - $options[:credentials].concat(JSON.parse(ENV["LOCAL_CONFIG_VARIABLES"])) + $options[:credentials].concat(JSON.parse(ENV.fetch("LOCAL_CONFIG_VARIABLES", nil))) +end + +unless ENV["SECURITY_ADVISORIES"].to_s.strip.empty? + # For example: + # [{"dependency-name":"name", + # "patched-versions":[], + # "unaffected-versions":[], + # "affected-versions":["< 0.10.0"]}] + $options[:security_advisories].concat(JSON.parse(ENV.fetch("SECURITY_ADVISORIES", nil))) +end + +unless ENV["IGNORE_CONDITIONS"].to_s.strip.empty? + # For example: + # [{"dependency-name":"ruby","version-requirement":">= 3.a, < 4"}] + $options[:ignore_conditions] = JSON.parse(ENV.fetch("IGNORE_CONDITIONS", nil)) end +# rubocop:disable Metrics/BlockLength option_parse = OptionParser.new do |opts| opts.banner = "usage: ruby bin/dry-run.rb [OPTIONS] PACKAGE_MANAGER REPO" + opts.on("--provider PROVIDER", "SCM provider e.g. github, azure, bitbucket") do |value| + $options[:provider] = value + end + opts.on("--dir DIRECTORY", "Dependency file directory") do |value| $options[:directory] = value end @@ -128,8 +172,9 @@ $options[:branch] = value end - opts.on("--dep DEPENDENCY", "Dependency to update") do |value| - $options[:dependency_name] = value + opts.on("--dep DEPENDENCIES", + "Comma separated list of dependencies to update") do |value| + $options[:dependency_names] = value.split(",").map { |o| o.strip.downcase } end opts.on("--cache STEPS", "Cache e.g. files, dependencies") do |value| @@ -144,8 +189,12 @@ $options[:lockfile_only] = true end - opts_req_desc = "Options: auto, widen_ranges, bump_versions or "\ - "bump_versions_if_necessary" + opts.on("--reject-external-code", "Reject external code") do |_value| + $options[:reject_external_code] = true + end + + opts_req_desc = "Options: auto, widen_ranges, bump_versions or " \ + "bump_versions_if_necessary" opts.on("--requirements-update-strategy STRATEGY", opts_req_desc) do |value| value = nil if value == "auto" $options[:requirements_update_strategy] = value @@ -154,7 +203,49 @@ opts.on("--commit COMMIT", "Commit to fetch dependency files from") do |value| $options[:commit] = value end + + opts.on("--clone", "clone the repo") do |_value| + $options[:clone] = true + end + + opts_opt_desc = "Comma separated list of updater options, " \ + "available options depend on PACKAGE_MANAGER" + opts.on("--updater-options OPTIONS", opts_opt_desc) do |value| + $options[:updater_options] = value.split(",").to_h do |o| + if o.include?("=") # key/value pair, e.g. "goprivate=true" + o.split("=", 2).map.with_index do |v, i| + if i.zero? + v.strip.downcase.to_sym + else + v.strip + end + end + else # just a key, e.g. "vendor" + [o.strip.downcase.to_sym, true] + end + end + + $options[:updater_options].each do |name, val| + Dependabot::Experiments.register(name, val) + end + end + + opts.on("--security-updates-only", + "Only update vulnerable dependencies") do |_value| + $options[:security_updates_only] = true + end + + opts.on("--profile", + "Profile using Stackprof. Output in `tmp/stackprof-.dump`") do + $options[:profile] = true + end + + opts.on("--pull-request", + "Output pull request information: title, description") do + $options[:pull_request] = true + end end +# rubocop:enable Metrics/BlockLength option_parse.parse! @@ -167,6 +258,8 @@ $package_manager, $repo_name = ARGV def show_diff(original_file, updated_file) + return unless original_file + if original_file.content == updated_file.content puts " no change to #{original_file.name}" return @@ -184,7 +277,7 @@ def show_diff(original_file, updated_file) puts puts " Âą #{original_file.name}" puts " ~~~" - puts diff.lines.map { |line| " " + line }.join("") + puts diff.lines.map { |line| " " + line }.join puts " ~~~" end @@ -194,7 +287,7 @@ def cached_read(name) cache_path = File.join("tmp", $repo_name.split("/"), "cache", "#{name}.bin") cache_dir = File.dirname(cache_path) - FileUtils.mkdir_p(cache_dir) unless Dir.exist?(cache_dir) + FileUtils.mkdir_p(cache_dir) cached = File.read(cache_path) if File.exist?(cache_path) # rubocop:disable Security/MarshalLoad return Marshal.load(cached) if cached @@ -221,11 +314,9 @@ def cached_dependency_files_read cache_manifest_path = File.join( cache_dir, "cache-manifest-#{$package_manager}.json" ) - FileUtils.mkdir_p(cache_dir) unless Dir.exist?(cache_dir) + FileUtils.mkdir_p(cache_dir) - if File.exist?(cache_manifest_path) - cached_manifest = File.read(cache_manifest_path) - end + cached_manifest = File.read(cache_manifest_path) if File.exist?(cache_manifest_path) cached_dependency_files = JSON.parse(cached_manifest) if cached_manifest all_files_cached = cached_dependency_files&.all? do |file| @@ -233,7 +324,8 @@ def cached_dependency_files_read end if all_files_cached && $options[:cache_steps].include?("files") - puts "=> reading dependency files from cache: ./#{cache_dir}" + puts "=> reading dependency files from cache manifest: " \ + "./#{cache_manifest_path}" cached_dependency_files.map do |file| file_content = File.read(File.join(cache_dir, file["name"])) Dependabot::DependencyFile.new( @@ -247,7 +339,7 @@ def cached_dependency_files_read end else if $options[:cache_steps].include?("files") - puts "=> failed to read all dependency files from cache manifest: "\ + puts "=> failed to read all dependency files from cache manifest: " \ "./#{cache_manifest_path}" end puts "=> fetching dependency files" @@ -266,14 +358,12 @@ def cached_dependency_files_read data.map do |file| files_path = File.join(cache_dir, file.name) files_dir = File.dirname(files_path) - FileUtils.mkdir_p(files_dir) unless Dir.exist?(files_dir) + FileUtils.mkdir_p(files_dir) File.write(files_path, file.content) end # Initialize a git repo so that changed files can be diffed if $options[:write] - if File.exist?(".gitignore") - FileUtils.cp(".gitignore", File.join(cache_dir, ".gitignore")) - end + FileUtils.cp(".gitignore", File.join(cache_dir, ".gitignore")) if File.exist?(".gitignore") Dir.chdir(cache_dir) do system("git init . && git add . && git commit --allow-empty -m 'Init'") end @@ -286,34 +376,188 @@ def cached_dependency_files_read # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize -source = Dependabot::Source.new( - provider: "github", +# rubocop:disable Metrics/MethodLength +def handle_dependabot_error(error:, dependency:) + error_details = + case error + when Dependabot::DependencyFileNotResolvable + { + "error-type": "dependency_file_not_resolvable", + "error-detail": { message: error.message } + } + when Dependabot::DependencyFileNotEvaluatable + { + "error-type": "dependency_file_not_evaluatable", + "error-detail": { message: error.message } + } + when Dependabot::BranchNotFound + { + "error-type": "branch_not_found", + "error-detail": { "branch-name": error.branch_name } + } + when Dependabot::DependencyFileNotParseable + { + "error-type": "dependency_file_not_parseable", + "error-detail": { + message: error.message, + "file-path": error.file_path + } + } + when Dependabot::DependencyFileNotFound + { + "error-type": "dependency_file_not_found", + "error-detail": { "file-path": error.file_path } + } + when Dependabot::PathDependenciesNotReachable + { + "error-type": "path_dependencies_not_reachable", + "error-detail": { dependencies: error.dependencies } + } + when Dependabot::GitDependenciesNotReachable + { + "error-type": "git_dependencies_not_reachable", + "error-detail": { "dependency-urls": error.dependency_urls } + } + when Dependabot::GitDependencyReferenceNotFound + { + "error-type": "git_dependency_reference_not_found", + "error-detail": { dependency: error.dependency } + } + when Dependabot::PrivateSourceAuthenticationFailure + { + "error-type": "private_source_authentication_failure", + "error-detail": { source: error.source } + } + when Dependabot::PrivateSourceTimedOut + { + "error-type": "private_source_timed_out", + "error-detail": { source: error.source } + } + when Dependabot::PrivateSourceCertificateFailure + { + "error-type": "private_source_certificate_failure", + "error-detail": { source: error.source } + } + when Dependabot::MissingEnvironmentVariable + { + "error-type": "missing_environment_variable", + "error-detail": { + "environment-variable": error.environment_variable + } + } + when Dependabot::GoModulePathMismatch + { + "error-type": "go_module_path_mismatch", + "error-detail": { + "declared-path": error.declared_path, + "discovered-path": error.discovered_path, + "go-mod": error.go_mod + } + } + else + raise error + end + + puts " => handled error whilst updating #{dependency.name}: #{error_details.fetch(:"error-type")} " \ + "#{error_details.fetch(:"error-detail")}" +end +# rubocop:enable Metrics/MethodLength + +def log_conflicting_dependencies(conflicting_dependencies) + return unless conflicting_dependencies.any? + + puts " => The update is not possible because of the following conflicting " \ + "dependencies:" + + conflicting_dependencies.each do |conflicting_dep| + puts " #{conflicting_dep['explanation']}" + end +end + +StackProf.start(raw: true) if $options[:profile] + +$network_trace_count = 0 +ActiveSupport::Notifications.subscribe(/excon.request/) do |*args| + $network_trace_count += 1 + payload = args.last + puts "🌍 #{payload[:scheme]}://#{payload[:host]}#{payload[:path]}" +end + +$package_manager_version_log = [] +Dependabot.subscribe(Dependabot::Notifications::FILE_PARSER_PACKAGE_MANAGER_VERSION_PARSED) do |*args| + $package_manager_version_log << args.last +end + +$source = Dependabot::Source.new( + provider: $options[:provider], repo: $repo_name, directory: $options[:directory], branch: $options[:branch], commit: $options[:commit] ) -$files = cached_dependency_files_read do - fetcher = Dependabot::FileFetchers.for_package_manager($package_manager). - new(source: source, credentials: $options[:credentials]) - fetcher.files +always_clone = Dependabot::Utils. + always_clone_for_package_manager?($package_manager) +$repo_contents_path = File.expand_path(File.join("tmp", $repo_name.split("/"))) if $options[:clone] || always_clone + +fetcher_args = { + source: $source, + credentials: $options[:credentials], + repo_contents_path: $repo_contents_path, + options: $options[:updater_options] +} +$config_file = begin + cfg_file = Dependabot::Config::FileFetcher.new(**fetcher_args).config_file + Dependabot::Config::File.parse(cfg_file.content) +rescue Dependabot::RepoNotFound, Dependabot::DependencyFileNotFound + Dependabot::Config::File.new(updates: []) end +$update_config = $config_file.update_config( + $package_manager, + directory: $options[:directory], + target_branch: $options[:branch] +) + +fetcher = Dependabot::FileFetchers.for_package_manager($package_manager).new(**fetcher_args) +$files = if $repo_contents_path + if $options[:cache_steps].include?("files") && Dir.exist?($repo_contents_path) + puts "=> reading cloned repo from #{$repo_contents_path}" + else + puts "=> cloning into #{$repo_contents_path}" + FileUtils.rm_rf($repo_contents_path) + end + fetcher.clone_repo_contents + if $options[:commit] + Dir.chdir($repo_contents_path) do + puts "=> checking out commit #{$options[:commit]}" + Dependabot::SharedHelpers.run_shell_command("git checkout #{$options[:commit]}") + end + end + fetcher.files + else + cached_dependency_files_read do + fetcher.files + end + end # Parse the dependency files puts "=> parsing dependency files" parser = Dependabot::FileParsers.for_package_manager($package_manager).new( dependency_files: $files, - source: source, - credentials: $options[:credentials] + repo_contents_path: $repo_contents_path, + source: $source, + credentials: $options[:credentials], + reject_external_code: $options[:reject_external_code] ) dependencies = cached_read("dependencies") { parser.parse } -if $options[:dependency_name].nil? +if $options[:dependency_names].nil? dependencies.select!(&:top_level?) else - dependencies.select! { |d| d.name == $options[:dependency_name] } + dependencies.select! do |d| + $options[:dependency_names].include?(d.name.downcase) + end end def update_checker_for(dependency) @@ -321,35 +565,40 @@ def update_checker_for(dependency) dependency: dependency, dependency_files: $files, credentials: $options[:credentials], + repo_contents_path: $repo_contents_path, requirements_update_strategy: $options[:requirements_update_strategy], - ignored_versions: ignore_conditions_for(dependency), - security_advisories: security_advisories_for(dependency) + ignored_versions: ignored_versions_for(dependency), + security_advisories: security_advisories, + options: $options[:updater_options] ) end -# TODO: Parse from config file -def ignore_conditions_for(_) - # Array of version requirements, e.g. ["4.x", "5.x"] - [] +def ignored_versions_for(dep) + if $options[:ignore_conditions].any? + ignore_conditions = $options[:ignore_conditions].map do |ic| + Dependabot::Config::IgnoreCondition.new( + dependency_name: ic["dependency-name"], + versions: [ic["version-requirement"]].compact, + update_types: ic["update-types"] + ) + end + Dependabot::Config::UpdateConfig.new(ignore_conditions: ignore_conditions). + ignored_versions_for(dep, security_updates_only: $options[:security_updates_only]) + else + $update_config.ignored_versions_for(dep) + end end -# TODO: Parse from config file -def security_advisories_for(dependency) - # Array of version requirement ranges, e.g. affected_versions: ["< 3.5.1"] - advisories = [{ - dependency_name: dependency.name, - patched_versions: [], - unaffected_versions: [], - affected_versions: [] - }] - - advisories.map do |adv| - vulnerable_versions = adv[:affected_versions] || [] - safe_versions = (adv[:patched_versions] || []) + - (adv[:unaffected_versions] || []) +def security_advisories + $options[:security_advisories].map do |adv| + vulnerable_versions = adv["affected-versions"] || [] + safe_versions = (adv["patched-versions"] || []) + + (adv["unaffected-versions"] || []) + # Handle case mismatches between advisory name and parsed dependency name + dependency_name = adv["dependency-name"].downcase Dependabot::SecurityAdvisory.new( - dependency_name: dependency.name, + dependency_name: dependency_name, package_manager: $package_manager, vulnerable_versions: vulnerable_versions, safe_versions: safe_versions @@ -357,9 +606,15 @@ def security_advisories_for(dependency) end end -def peer_dependencies_can_update?(checker, reqs_to_unlock) - checker.updated_dependencies(requirements_to_unlock: reqs_to_unlock). - reject { |dep| dep.name == checker.dependency.name }. +# If a version update for a peer dependency is possible we should +# defer to the PR that will be created for it to avoid duplicate PRs. +def peer_dependency_should_update_instead?(dependency_name, updated_deps) + # This doesn't apply to security updates as we can't rely on the + # peer dependency getting updated. + return false if $options[:security_updates_only] + + updated_deps. + reject { |dep| dep.name == dependency_name }. any? do |dep| original_peer_dep = ::Dependabot::Dependency.new( name: dep.name, @@ -373,64 +628,105 @@ def peer_dependencies_can_update?(checker, reqs_to_unlock) end def file_updater_for(dependencies) - Dependabot::FileUpdaters.for_package_manager($package_manager).new( - dependencies: dependencies, - dependency_files: $files, - credentials: $options[:credentials] - ) -end - -def generate_dependency_files_for(updated_dependencies) - if updated_dependencies.count == 1 - updated_dependency = updated_dependencies.first + if dependencies.count == 1 + updated_dependency = dependencies.first prev_v = updated_dependency.previous_version prev_v_msg = prev_v ? "from #{prev_v} " : "" puts " => updating #{updated_dependency.name} #{prev_v_msg}to " \ "#{updated_dependency.version}" else - dependency_names = updated_dependencies.map(&:name) + dependency_names = dependencies.map(&:name) puts " => updating #{dependency_names.join(', ')}" end - updater = file_updater_for(updated_dependencies) - updater.updated_dependency_files + Dependabot::FileUpdaters.for_package_manager($package_manager).new( + dependencies: dependencies, + dependency_files: $files, + repo_contents_path: $repo_contents_path, + credentials: $options[:credentials], + options: $options[:updater_options] + ) end -puts "=> updating #{dependencies.count} dependencies" +def security_fix?(dependency) + security_advisories.any? do |advisory| + advisory.fixed_by?(dependency) + end +end + +puts "=> updating #{dependencies.count} dependencies: #{dependencies.map(&:name).join(', ')}" # rubocop:disable Metrics/BlockLength +checker_count = 0 dependencies.each do |dep| - puts "\n=== #{dep.name} (#{dep.version})" + checker_count += 1 checker = update_checker_for(dep) + name_version = "\n=== #{dep.name} (#{dep.version})" + vulnerable = checker.vulnerable? ? " (vulnerable 🚨)" : "" + puts name_version + vulnerable + + puts " => checking for updates #{checker_count}/#{dependencies.count}" + puts " => latest available version is #{checker.latest_version}" + + if $options[:security_updates_only] && !checker.vulnerable? + if checker.version_class.correct?(checker.dependency.version) + puts " (no security update needed as it's not vulnerable)" + else + puts " (can't update vulnerable dependencies for " \ + "projects without a lockfile as the currently " \ + "installed version isn't known 🚨)" + end + next + end - puts " => checking for updates" - puts " => latest version from registry is #{checker.latest_version}" - puts " => latest resolvable version is #{checker.latest_resolvable_version}" + if checker.vulnerable? + if checker.lowest_security_fix_version + puts " => earliest available non-vulnerable version is " \ + "#{checker.lowest_security_fix_version}" + else + puts " => there is no available non-vulnerable version" + end + end if checker.up_to_date? - puts " (no update needed)" + puts " (no update needed as it's already up-to-date)" next end + latest_allowed_version = if checker.vulnerable? + checker.lowest_resolvable_security_fix_version + else + checker.latest_resolvable_version + end + puts " => latest allowed version is #{latest_allowed_version || dep.version}" + requirements_to_unlock = if $options[:lockfile_only] || !checker.requirements_unlocked_or_can_be? if checker.can_update?(requirements_to_unlock: :none) then :none - else :update_not_possible + else + :update_not_possible end elsif checker.can_update?(requirements_to_unlock: :own) then :own elsif checker.can_update?(requirements_to_unlock: :all) then :all - else :update_not_possible + else + :update_not_possible end puts " => requirements to unlock: #{requirements_to_unlock}" if checker.respond_to?(:requirements_update_strategy) - puts " => requirements update strategy: "\ + puts " => requirements update strategy: " \ "#{checker.requirements_update_strategy}" end if requirements_to_unlock == :update_not_possible - puts " (no update possible)" + if checker.vulnerable? || $options[:security_updates_only] + puts " (no security update possible 🙅‍♀ī¸)" + else + puts " (no update possible 🙅‍♀ī¸)" + end + + log_conflicting_dependencies(checker.conflicting_dependencies) next end @@ -438,17 +734,27 @@ def generate_dependency_files_for(updated_dependencies) requirements_to_unlock: requirements_to_unlock ) - if peer_dependencies_can_update?(checker, requirements_to_unlock) + if peer_dependency_should_update_instead?(checker.dependency.name, updated_deps) puts " (no update possible, peer dependency can be updated)" next end - updated_files = generate_dependency_files_for(updated_deps) + if $options[:security_updates_only] && + updated_deps.none? { |d| security_fix?(d) } + puts " (updated version is still vulnerable 🚨)" + log_conflicting_dependencies(checker.conflicting_dependencies) + next + end - # Currently unused but used to create pull requests (from the updater) - updated_deps.reject do |d| + # Removal is only supported for transitive dependencies which are removed as a + # side effect of the parent update + deps_to_update = updated_deps.reject(&:removed?) + updater = file_updater_for(deps_to_update) + updated_files = updater.updated_dependency_files + + updated_deps = updated_deps.reject do |d| next false if d.name == checker.dependency.name - next true if d.requirements == d.previous_requirements + next true if d.top_level? && d.requirements == d.previous_requirements d.version == d.previous_version end @@ -457,15 +763,52 @@ def generate_dependency_files_for(updated_dependencies) updated_files.each do |updated_file| path = File.join(dependency_files_cache_dir, updated_file.name) puts " => writing updated file ./#{path}" - File.write(path, updated_file.content) + dirname = File.dirname(path) + FileUtils.mkdir_p(dirname) + if updated_file.operation == Dependabot::DependencyFile::Operation::DELETE + FileUtils.rm_f(path) + else + File.write(path, updated_file.decoded_content) + end end end updated_files.each do |updated_file| - original_file = $files.find { |f| f.name == updated_file.name } - show_diff(original_file, updated_file) + if updated_file.operation == Dependabot::DependencyFile::Operation::DELETE + puts "deleted #{updated_file.name}" + else + original_file = $files.find { |f| f.name == updated_file.name } + if original_file + show_diff(original_file, updated_file) + else + puts "added #{updated_file.name}" + end + end + end + + if $options[:pull_request] + msg = Dependabot::PullRequestCreator::MessageBuilder.new( + dependencies: updated_deps, + files: updated_files, + credentials: $options[:credentials], + source: $source, + commit_message_options: $update_config.commit_message_options.to_h, + github_redirection_service: Dependabot::PullRequestCreator::DEFAULT_GITHUB_REDIRECTION_SERVICE + ).message + puts "Pull Request Title: #{msg.pr_name}" + puts "--description--\n#{msg.pr_message}\n--/description--" + puts "--commit--\n#{msg.commit_message}\n--/commit--" end +rescue StandardError => e + handle_dependabot_error(error: e, dependency: dep) end + +StackProf.stop if $options[:profile] +StackProf.results("tmp/stackprof-#{Time.now.strftime('%Y-%m-%d-%H:%M')}.dump") if $options[:profile] + +puts "🌍 Total requests made: '#{$network_trace_count}'" +puts "🎈 Package manager version log: #{$package_manager_version_log.join('\n')}" if $package_manager_version_log.any? + # rubocop:enable Metrics/BlockLength # rubocop:enable Style/GlobalVars diff --git a/bin/lint b/bin/lint new file mode 100755 index 00000000000..f38d95b5b39 --- /dev/null +++ b/bin/lint @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +shellcheck \ + --source-path=SCRIPTDIR \ + ./bin/ci-test \ + ./bin/docker-dev-shell \ + ./bin/lint \ + ./*/helpers/*/build \ + ./*/helpers/build \ + ./*/script/* \ + "$@" diff --git a/bundler/.gitignore b/bundler/.gitignore index 06845bd78c0..24563d85bc8 100644 --- a/bundler/.gitignore +++ b/bundler/.gitignore @@ -3,3 +3,6 @@ /tmp /dependabot-*.gem Gemfile.lock +spec/fixtures/projects/*/.bundle/ +!spec/fixtures/projects/**/Gemfile.lock +!spec/fixtures/projects/**/vendor diff --git a/bundler/.rubocop.yml b/bundler/.rubocop.yml new file mode 100644 index 00000000000..fc2019d46a3 --- /dev/null +++ b/bundler/.rubocop.yml @@ -0,0 +1 @@ +inherit_from: ../.rubocop.yml diff --git a/bundler/README.md b/bundler/README.md index 6052ab63213..929bb5ab64c 100644 --- a/bundler/README.md +++ b/bundler/README.md @@ -4,7 +4,14 @@ Ruby (bundler) support for [`dependabot-core`][core-repo]. ### Running locally -1. Install Ruby dependencies +1. Install native helpers + ``` + $ export DEPENDABOT_NATIVE_HELPERS_PATH=$PWD/helpers/install-dir + $ helpers/v1/build + $ helpers/v2/build + ``` + +2. Install Ruby dependencies ``` $ bundle install ``` diff --git a/bundler/dependabot-bundler.gemspec b/bundler/dependabot-bundler.gemspec index 9d04fbdd78a..1d09c9b6139 100644 --- a/bundler/dependabot-bundler.gemspec +++ b/bundler/dependabot-bundler.gemspec @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "find" - Gem::Specification.new do |spec| common_gemspec = Bundler.load_gemspec_uncached("../common/dependabot-common.gemspec") @@ -25,21 +23,10 @@ Gem::Specification.new do |spec| spec.add_dependency "dependabot-common", Dependabot::VERSION common_gemspec.development_dependencies.each do |dep| - spec.add_development_dependency dep.name, dep.requirement.to_s + spec.add_development_dependency dep.name, *dep.requirement.as_list end next unless File.exist?("../.gitignore") - ignores = File.readlines("../.gitignore").grep(/\S+/).map(&:chomp) - - next unless File.directory?("lib") - - prefix = "/" + File.basename(File.expand_path(__dir__)) + "/" - Find.find("lib") do |path| - if ignores.any? { |i| File.fnmatch(i, prefix + path, File::FNM_DOTMATCH) } - Find.prune - else - spec.files << path unless File.directory?(path) - end - end + spec.files += `git -C #{__dir__} ls-files lib helpers -z`.split("\x0") end diff --git a/bundler/helpers/v1/.gitignore b/bundler/helpers/v1/.gitignore new file mode 100644 index 00000000000..c88c5c24353 --- /dev/null +++ b/bundler/helpers/v1/.gitignore @@ -0,0 +1,8 @@ +/.bundle +/.env +/tmp +/dependabot-*.gem +Gemfile.lock +spec/fixtures/projects/*/.bundle/ +!spec/fixtures/projects/**/Gemfile.lock +!spec/fixtures/projects/**/vendor diff --git a/bundler/helpers/v1/Gemfile b/bundler/helpers/v1/Gemfile new file mode 100644 index 00000000000..23a9d87c7b3 --- /dev/null +++ b/bundler/helpers/v1/Gemfile @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# NOTE: Used to run native helper specs +group :test do + gem "rspec", "~> 3.8" + gem "rspec-its", "~> 1.2" + gem "vcr", "6.1.0" + gem "webmock", "~> 3.4" +end diff --git a/bundler/helpers/v1/build b/bundler/helpers/v1/build new file mode 100755 index 00000000000..3301b6b70a3 --- /dev/null +++ b/bundler/helpers/v1/build @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +helpers_dir=$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +if [ -z "$DEPENDABOT_NATIVE_HELPERS_PATH" ]; then + install_dir="$helpers_dir" +else + install_dir="$DEPENDABOT_NATIVE_HELPERS_PATH/bundler/v1" + mkdir -p "$install_dir" + + cp -r \ + "$helpers_dir/lib" \ + "$helpers_dir/monkey_patches" \ + "$helpers_dir/run.rb" \ + "$helpers_dir/Gemfile" \ + "$install_dir" +fi + +cd "$install_dir" + +export GEM_HOME=$install_dir/.bundle + +gem install bundler -v 1.17.3 --no-document + +BUNDLER_VERSION=1.17.3 bundle config --local path.system true + +if [ -n "$DEPENDABOT_NATIVE_HELPERS_PATH" ]; then + BUNDLER_VERSION=1.17.3 bundle config --local without "test" +fi + +# NOTE: Sets `BUNDLED WITH` to match the installed v1 version in Gemfile.lock +# forcing native helpers to run with the same version +BUNDLER_VERSION=1.17.3 bundle install diff --git a/bundler/helpers/v1/lib/functions.rb b/bundler/helpers/v1/lib/functions.rb new file mode 100644 index 00000000000..c6c37f04387 --- /dev/null +++ b/bundler/helpers/v1/lib/functions.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +require "functions/file_parser" +require "functions/force_updater" +require "functions/lockfile_updater" +require "functions/dependency_source" +require "functions/version_resolver" +require "functions/conflicting_dependency_resolver" + +module Functions + def self.parsed_gemfile(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + FileParser.new(lockfile_name: args.fetch(:lockfile_name)). + parsed_gemfile(gemfile_name: args.fetch(:gemfile_name)) + end + + def self.parsed_gemspec(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + FileParser.new(lockfile_name: args.fetch(:lockfile_name)). + parsed_gemspec(gemspec_name: args.fetch(:gemspec_name)) + end + + def self.vendor_cache_dir(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + Bundler.settings.app_cache_path + end + + def self.update_lockfile(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + LockfileUpdater.new( + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name), + dependencies: args.fetch(:dependencies) + ).run + end + + def self.force_update(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + ForceUpdater.new( + dependency_name: args.fetch(:dependency_name), + target_version: args.fetch(:target_version), + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name), + update_multiple_dependencies: args.fetch(:update_multiple_dependencies) + ).run + end + + def self.dependency_source_type(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).type + end + + def self.depencency_source_latest_git_version(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).latest_git_version( + dependency_source_url: args.fetch(:dependency_source_url), + dependency_source_branch: args.fetch(:dependency_source_branch) + ) + end + + def self.private_registry_versions(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).private_registry_versions + end + + def self.resolve_version(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + VersionResolver.new( + dependency_name: args.fetch(:dependency_name), + dependency_requirements: args.fetch(:dependency_requirements), + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name) + ).version_details + end + + def self.jfrog_source(**args) + # Set flags and credentials + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + Bundler::Definition.build(args.fetch(:gemfile_name), nil, {}). + send(:sources). + rubygems_remotes. + find { |uri| uri.host.include?("jfrog") }&. + host + end + + def self.git_specs(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + git_specs = Bundler::Definition.build(args.fetch(:gemfile_name), nil, {}).dependencies. + select do |spec| + spec.source.is_a?(Bundler::Source::Git) + end + git_specs.map do |spec| + # Piggy-back off some private Bundler methods to configure the + # URI with auth details in the same way Bundler does. + git_proxy = spec.source.send(:git_proxy) + auth_uri = spec.source.uri.gsub("git://", "https://") + auth_uri = git_proxy.send(:configured_uri_for, auth_uri) + auth_uri += ".git" unless auth_uri.end_with?(".git") + auth_uri += "/info/refs?service=git-upload-pack" + { + uri: spec.source.uri, + auth_uri: auth_uri + } + end + end + + def self.conflicting_dependencies(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + ConflictingDependencyResolver.new( + dependency_name: args.fetch(:dependency_name), + target_version: args.fetch(:target_version), + lockfile_name: args.fetch(:lockfile_name) + ).conflicting_dependencies + end + + def self.set_bundler_flags_and_credentials(dir:, credentials:) + dir = dir ? Pathname.new(dir) : dir + Bundler.instance_variable_set(:@root, dir) + + # Remove installed gems from the default Rubygems index + Gem::Specification.all = + Gem::Specification.send(:default_stubs, "*.gemspec") + + # Set auth details + relevant_credentials(credentials).each do |cred| + token = cred["token"] || + "#{cred['username']}:#{cred['password']}" + + Bundler.settings.set_command_option( + cred.fetch("host"), + token.gsub("@", "%40F").gsub("?", "%3F") + ) + end + + # Use HTTPS for GitHub if lockfile + Bundler.settings.set_command_option("github.https", "true") + end + + def self.relevant_credentials(credentials) + [ + *git_source_credentials(credentials), + *private_registry_credentials(credentials) + ].select { |cred| cred["password"] || cred["token"] } + end + + def self.private_registry_credentials(credentials) + credentials. + select { |cred| cred["type"] == "rubygems_server" } + end + + def self.git_source_credentials(credentials) + credentials. + select { |cred| cred["type"] == "git_source" } + end +end diff --git a/bundler/helpers/v1/lib/functions/conflicting_dependency_resolver.rb b/bundler/helpers/v1/lib/functions/conflicting_dependency_resolver.rb new file mode 100644 index 00000000000..b6576d461c3 --- /dev/null +++ b/bundler/helpers/v1/lib/functions/conflicting_dependency_resolver.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Functions + class ConflictingDependencyResolver + def initialize(dependency_name:, target_version:, lockfile_name:) + @dependency_name = dependency_name + @target_version = target_version + @lockfile_name = lockfile_name + end + + # Finds any dependencies in the lockfile that have a subdependency on the + # given dependency that does not satisfly the target_version. + # @return [Array String}] + # * explanation [String] a sentence explaining the conflict + # * name [String] the blocking dependencies name + # * version [String] the version of the blocking dependency + # * requirement [String] the requirement on the target_dependency + def conflicting_dependencies + Bundler.settings.set_command_option("only_update_to_newer_versions", true) + + parent_specs.flat_map do |parent_spec| + top_level_specs_for(parent_spec).map do |top_level| + dependency = parent_spec.dependencies.find { |bd| bd.name == dependency_name } + { + "explanation" => explanation(parent_spec, dependency, top_level), + "name" => parent_spec.name, + "version" => parent_spec.version.to_s, + "requirement" => dependency.requirement.to_s + } + end + end + end + + private + + attr_reader :dependency_name, :target_version, :lockfile_name + + def parent_specs + version = Gem::Version.new(target_version) + parsed_lockfile.specs.filter do |spec| + spec.dependencies.any? do |dep| + dep.name == dependency_name && + !dep.requirement.satisfied_by?(version) + end + end + end + + def top_level_specs_for(parent_spec) + return [parent_spec] if top_level?(parent_spec) + + parsed_lockfile.specs.filter do |spec| + spec.dependencies.any? do |dep| + dep.name == parent_spec.name && top_level?(spec) + end + end + end + + def top_level?(spec) + parsed_lockfile.dependencies.key?(spec.name) + end + + def explanation(spec, dependency, top_level) + if spec.name == top_level.name + "#{spec.name} (#{spec.version}) requires #{dependency_name} (#{dependency.requirement})" + else + "#{top_level.name} (#{top_level.version}) requires #{dependency_name} " \ + "(#{dependency.requirement}) via #{spec.name} (#{spec.version})" + end + end + + def parsed_lockfile + @parsed_lockfile ||= Bundler::LockfileParser.new(lockfile) + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + end +end diff --git a/bundler/helpers/v1/lib/functions/dependency_source.rb b/bundler/helpers/v1/lib/functions/dependency_source.rb new file mode 100644 index 00000000000..abe82412a5e --- /dev/null +++ b/bundler/helpers/v1/lib/functions/dependency_source.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Functions + class DependencySource + attr_reader :gemfile_name, :dependency_name + + RUBYGEMS = "rubygems" + PRIVATE_REGISTRY = "private" + GIT = "git" + OTHER = "other" + + def initialize(gemfile_name:, dependency_name:) + @gemfile_name = gemfile_name + @dependency_name = dependency_name + end + + def type + bundler_source = specified_source || default_source + type_of(bundler_source) + end + + def latest_git_version(dependency_source_url:, dependency_source_branch:) + source = Bundler::Source::Git.new( + "uri" => dependency_source_url, + "branch" => dependency_source_branch, + "name" => dependency_name, + "submodules" => true + ) + + # Tell Bundler we're fine with fetching the source remotely + source.instance_variable_set(:@allow_remote, true) + + spec = source.specs.first + { version: spec.version, commit_sha: spec.source.revision } + end + + def private_registry_versions + bundler_source = specified_source || default_source + + bundler_source. + fetchers.flat_map do |fetcher| + fetcher. + specs_with_retry([dependency_name], bundler_source). + search_all(dependency_name) + end. + map(&:version) + end + + private + + def type_of(bundler_source) + case bundler_source + when Bundler::Source::Rubygems + remote = bundler_source.remotes.first + if remote.nil? || remote.to_s == "https://rubygems.org/" + RUBYGEMS + else + PRIVATE_REGISTRY + end + when Bundler::Source::Git + GIT + else + OTHER + end + end + + def specified_source + return @specified_source if defined? @specified_source + + @specified_source = definition.dependencies. + find { |dep| dep.name == dependency_name }&.source + end + + def default_source + definition.send(:sources).default_source + end + + def definition + @definition ||= Bundler::Definition.build(gemfile_name, nil, {}) + end + + def serialize_bundler_source(source) + { + type: source.class.to_s + } + end + end +end diff --git a/bundler/helpers/v1/lib/functions/file_parser.rb b/bundler/helpers/v1/lib/functions/file_parser.rb new file mode 100644 index 00000000000..05532fd865f --- /dev/null +++ b/bundler/helpers/v1/lib/functions/file_parser.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +require "uri" + +module Functions + class FileParser + def initialize(lockfile_name:) + @lockfile_name = lockfile_name + end + + attr_reader :lockfile_name + + def parsed_gemfile(gemfile_name:) + Bundler::Definition.build(gemfile_name, nil, {}). + dependencies.select(&:current_platform?). + reject { |dep| dep.source.is_a?(Bundler::Source::Gemspec) }. + map { |dep| serialize_bundler_dependency(dep) } + end + + def parsed_gemspec(gemspec_name:) + Bundler.load_gemspec_uncached(gemspec_name). + dependencies. + map { |dep| serialize_bundler_dependency(dep) } + end + + private + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def parsed_lockfile + return unless lockfile + + @parsed_lockfile ||= Bundler::LockfileParser.new(lockfile) + end + + def source_from_lockfile(dependency_name) + parsed_lockfile&.specs&.find { |s| s.name == dependency_name }&.source + end + + def source_for(dependency) + source = dependency.source + if lockfile && default_rubygems?(source) + # If there's a lockfile and the Gemfile doesn't have anything + # interesting to say about the source, check that. + source = source_from_lockfile(dependency.name) + end + raise "Bad source: #{source}" unless sources.include?(source.class) + + return nil if default_rubygems?(source) + + details = { type: source.class.name.split("::").last.downcase } + details.merge!(git_source_details(source)) if source.is_a?(Bundler::Source::Git) + details[:url] = source.remotes.first.to_s if source.is_a?(Bundler::Source::Rubygems) + details + end + + def git_source_details(source) + { + url: source.uri, + branch: source.branch, + ref: source.ref + } + end + + RUBYGEMS_HOSTS = [ + "rubygems.org", + "www.rubygems.org" + ].freeze + + def default_rubygems?(source) + return true if source.nil? + return false unless source.is_a?(Bundler::Source::Rubygems) + + source.remotes.any? do |r| + RUBYGEMS_HOSTS.include?(URI(r.to_s).host) + end + end + + def serialize_bundler_dependency(dependency) + { + name: dependency.name, + requirement: dependency.requirement, + groups: dependency.groups, + source: source_for(dependency), + type: dependency.type + } + end + + # Can't be a constant because some of these don't exist in bundler + # 1.15, which used to cause issues on Heroku (causing exception on boot). + # TODO: Check if this will be an issue with multiple bundler versions + def sources + [ + NilClass, + Bundler::Source::Rubygems, + Bundler::Source::Git, + Bundler::Source::Path, + Bundler::Source::Gemspec, + Bundler::Source::Metadata + ] + end + end +end diff --git a/bundler/helpers/v1/lib/functions/force_updater.rb b/bundler/helpers/v1/lib/functions/force_updater.rb new file mode 100644 index 00000000000..a35e0ccaa25 --- /dev/null +++ b/bundler/helpers/v1/lib/functions/force_updater.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true + +module Functions + class ForceUpdater + class TransitiveDependencyError < StandardError; end + + def initialize(dependency_name:, target_version:, gemfile_name:, + lockfile_name:, update_multiple_dependencies:) + @dependency_name = dependency_name + @target_version = target_version + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + @update_multiple_dependencies = update_multiple_dependencies + end + + def run + # Only allow upgrades. Otherwise it's unlikely that this + # resolution will be found by the FileUpdater + Bundler.settings.set_command_option( + "only_update_to_newer_versions", + true + ) + + dependencies_to_unlock = [] + + begin + definition = build_definition(dependencies_to_unlock: dependencies_to_unlock) + definition.resolve_remotely! + specs = definition.resolve + updates = [{ name: dependency_name }] + + dependencies_to_unlock.map { |dep| { name: dep.name } } + specs = specs.map do |dep| + { + name: dep.name, + version: dep.version + } + end + [updates, specs] + rescue Bundler::VersionConflict => e + raise unless update_multiple_dependencies? + + # TODO: Not sure this won't unlock way too many things... + new_dependencies_to_unlock = + new_dependencies_to_unlock_from( + error: e, + already_unlocked: dependencies_to_unlock + ) + + raise if new_dependencies_to_unlock.none? + + dependencies_to_unlock += new_dependencies_to_unlock + retry + end + end + + private + + attr_reader :dependency_name, :target_version, :gemfile_name, + :lockfile_name, :credentials, + :update_multiple_dependencies + alias update_multiple_dependencies? update_multiple_dependencies + + def new_dependencies_to_unlock_from(error:, already_unlocked:) + potentials_deps = + relevant_conflicts(error, already_unlocked). + flat_map(&:requirement_trees). + reject do |tree| + # If the final requirement wasn't specific, it can't be binding + next true if tree.last.requirement == Gem::Requirement.new(">= 0") + + # If the conflict wasn't for the dependency we're updating then + # we don't have enough info to reject it + next false unless tree.last.name == dependency_name + + # If the final requirement *was* for the dependency we're updating + # then we can ignore the tree if it permits the target version + tree.last.requirement.satisfied_by?( + Gem::Version.new(target_version) + ) + end.map(&:first) + + potentials_deps. + reject { |dep| already_unlocked.map(&:name).include?(dep.name) }. + reject { |dep| [dependency_name, "ruby\0"].include?(dep.name) }. + uniq + end + + def relevant_conflicts(error, dependencies_being_unlocked) + names = [*dependencies_being_unlocked.map(&:name), dependency_name] + + # For a conflict to be relevant to the updates we're making it must be + # 1) caused by a new requirement introduced by our unlocking, or + # 2) caused by an old requirement that prohibits the update. + # Hence, we look at the beginning and end of the requirement trees + error.cause.conflicts.values. + select do |conflict| + conflict.requirement_trees.any? do |t| + names.include?(t.last.name) || names.include?(t.first.name) + end + end + end + + def build_definition(dependencies_to_unlock:) + gems_to_unlock = dependencies_to_unlock.map(&:name) + [dependency_name] + definition = Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: gems_to_unlock + subdependencies, + lock_shared_dependencies: true + ) + + # Remove the Gemfile / gemspec requirements on the gems we're + # unlocking (i.e., completely unlock them) + gems_to_unlock.each do |gem_name| + unlock_gem(definition: definition, gem_name: gem_name) + end + + dep = definition.dependencies. + find { |d| d.name == dependency_name } + + # If the dependency is not found in the Gemfile it means this is a + # transitive dependency that we can't force update. + raise TransitiveDependencyError unless dep + + # Set the requirement for the gem we're forcing an update of + new_req = Gem::Requirement.create("= #{target_version}") + dep.instance_variable_set(:@requirement, new_req) + dep.source = nil if dep.source.is_a?(Bundler::Source::Git) + + definition + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def subdependencies + # If there's no lockfile we don't need to worry about + # subdependencies + return [] unless lockfile + + all_deps = Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s) + top_level = Bundler::Definition. + build(gemfile_name, lockfile_name, {}). + dependencies.map(&:name).map(&:to_s) + + all_deps - top_level + end + + def unlock_gem(definition:, gem_name:) + dep = definition.dependencies.find { |d| d.name == gem_name } + version = definition.locked_gems.specs. + find { |d| d.name == gem_name }.version + + dep&.instance_variable_set( + :@requirement, + Gem::Requirement.create(">= #{version}") + ) + end + end +end diff --git a/bundler/helpers/v1/lib/functions/lockfile_updater.rb b/bundler/helpers/v1/lib/functions/lockfile_updater.rb new file mode 100644 index 00000000000..0079bf2c743 --- /dev/null +++ b/bundler/helpers/v1/lib/functions/lockfile_updater.rb @@ -0,0 +1,226 @@ +# frozen_string_literal: true + +require "fileutils" + +module Functions + class LockfileUpdater + RETRYABLE_ERRORS = [Bundler::HTTPError].freeze + GEM_NOT_FOUND_ERROR_REGEX = + / + locked\sto\s(?[^\s]+)\s\(| + not\sfind\s(?[^\s]+)-\d| + has\s(?[^\s]+)\slocked\sat + /x + + def initialize(gemfile_name:, lockfile_name:, dependencies:) + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + @dependencies = dependencies + end + + def run + generate_lockfile + end + + private + + attr_reader :gemfile_name, :lockfile_name, :dependencies + + def generate_lockfile # rubocop:disable Metrics/PerceivedComplexity + dependencies_to_unlock = dependencies.map { |d| d.fetch("name") } + + begin + definition = build_definition(dependencies_to_unlock) + + old_reqs = lock_deps_being_updated_to_exact_versions(definition) + + definition.resolve_remotely! + + old_reqs.each do |dep_name, old_req| + d_dep = definition.dependencies.find { |d| d.name == dep_name } + if old_req == :none then definition.dependencies.delete(d_dep) + else + d_dep.instance_variable_set(:@requirement, old_req) + end + end + + cache_vendored_gems(definition) if Bundler.app_cache.exist? + + definition.to_lock + rescue Bundler::GemNotFound => e + unlock_yanked_gem(dependencies_to_unlock, e) && retry + rescue Bundler::VersionConflict => e + unlock_blocking_subdeps(dependencies_to_unlock, e) && retry + rescue *RETRYABLE_ERRORS + raise if @retrying + + @retrying = true + sleep(rand(1.0..5.0)) + retry + end + end + + def cache_vendored_gems(definition) + # Dependencies that have been unlocked for the update (including + # sub-dependencies) + unlocked_gems = definition.instance_variable_get(:@unlock). + fetch(:gems).reject { |gem| __keep_on_prune?(gem) } + bundler_opts = { + cache_all: true, + cache_all_platforms: true, + no_prune: true + } + + Bundler.settings.temporary(**bundler_opts) do + # Fetch and cache gems on all platforms without pruning + Bundler::Runtime.new(nil, definition).cache + + # Only prune unlocked gems (the original implementation is in + # Bundler::Runtime) + cache_path = Bundler.app_cache + resolve = definition.resolve + prune_gem_cache(resolve, cache_path, unlocked_gems) + prune_git_and_path_cache(resolve, cache_path) + end + end + + # This is not officially supported and may be removed without notice. + def __keep_on_prune?(spec_name) + unless (specs = Bundler.settings[:persistent_gems_after_clean]) + return false + end + + specs.include?(spec_name) + end + + # Copied from Bundler::Runtime: Modified to only prune gems that have + # been unlocked + def prune_gem_cache(resolve, cache_path, unlocked_gems) + cached_gems = Dir["#{cache_path}/*.gem"] + + outdated_gems = cached_gems.reject do |path| + spec = Bundler.rubygems.spec_from_gem path + + !unlocked_gems.include?(spec.name) || resolve.any? do |s| + s.name == spec.name && s.version == spec.version && + !s.source.is_a?(Bundler::Source::Git) + end + end + + return unless outdated_gems.any? + + outdated_gems.each do |path| + File.delete(path) + end + end + + # Copied from Bundler::Runtime + def prune_git_and_path_cache(resolve, cache_path) + cached_git_and_path = Dir["#{cache_path}/*/.bundlecache"] + + outdated_git_and_path = cached_git_and_path.reject do |path| + name = File.basename(File.dirname(path)) + + resolve.any? do |s| + s.source.respond_to?(:app_cache_dirname) && + s.source.app_cache_dirname == name + end + end + + return unless outdated_git_and_path.any? + + outdated_git_and_path.each do |path| + path = File.dirname(path) + FileUtils.rm_rf(path) + end + end + + def unlock_yanked_gem(dependencies_to_unlock, error) + raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) + + gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). + named_captures["name"] + raise if dependencies_to_unlock.include?(gem_name) + + dependencies_to_unlock << gem_name + end + + # rubocop:disable Metrics/PerceivedComplexity + def unlock_blocking_subdeps(dependencies_to_unlock, error) + all_deps = Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s) + top_level = build_definition([]).dependencies. + map(&:name).map(&:to_s) + allowed_new_unlocks = all_deps - top_level - dependencies_to_unlock + + raise if allowed_new_unlocks.none? + + # Unlock any sub-dependencies that Bundler reports caused the + # conflict + potentials_deps = + error.cause.conflicts.values. + flat_map(&:requirement_trees). + filter_map do |tree| + tree.find { |req| allowed_new_unlocks.include?(req.name) } + end.map(&:name) + + # If there are specific dependencies we can unlock, unlock them + return dependencies_to_unlock.append(*potentials_deps) if potentials_deps.any? + + # Fall back to unlocking *all* sub-dependencies. This is required + # because Bundler's VersionConflict objects don't include enough + # information to chart the full path through all conflicts unwound + dependencies_to_unlock.append(*allowed_new_unlocks) + end + # rubocop:enable Metrics/PerceivedComplexity + + def build_definition(dependencies_to_unlock) + defn = Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: dependencies_to_unlock + ) + + # Bundler unlocks the sub-dependencies of gems it is passed even + # if those sub-deps are top-level dependencies. We only want true + # subdeps unlocked, like they were in the UpdateChecker, so we + # mutate the unlocked gems array. + unlocked = defn.instance_variable_get(:@unlock).fetch(:gems) + must_not_unlock = defn.dependencies.map(&:name).map(&:to_s) - + dependencies_to_unlock + unlocked.reject! { |n| must_not_unlock.include?(n) } + + defn + end + + def lock_deps_being_updated_to_exact_versions(definition) + dependencies.each_with_object({}) do |dep, old_reqs| + defn_dep = definition.dependencies.find do |d| + d.name == dep.fetch("name") + end + + if defn_dep.nil? + definition.dependencies << + Bundler::Dependency.new(dep.fetch("name"), dep.fetch("version")) + old_reqs[dep.fetch("name")] = :none + elsif git_dependency?(dep) && + defn_dep.source.is_a?(Bundler::Source::Git) + defn_dep.source.unlock! + elsif Gem::Version.correct?(dep.fetch("version")) + new_req = Gem::Requirement.create("= #{dep.fetch('version')}") + old_reqs[dep.fetch("name")] = defn_dep.requirement + defn_dep.instance_variable_set(:@requirement, new_req) + end + end + end + + def git_dependency?(dep) + sources = dep.fetch("requirements").map { |r| r.fetch("source") } + sources.all? { |s| s&.fetch("type", nil) == "git" } + end + + def lockfile + @lockfile ||= File.read(lockfile_name) + end + end +end diff --git a/bundler/helpers/v1/lib/functions/version_resolver.rb b/bundler/helpers/v1/lib/functions/version_resolver.rb new file mode 100644 index 00000000000..01afb47f2cf --- /dev/null +++ b/bundler/helpers/v1/lib/functions/version_resolver.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Functions + class VersionResolver + GEM_NOT_FOUND_ERROR_REGEX = /locked to (?[^\s]+) \(/ + + attr_reader :dependency_name, :dependency_requirements, + :gemfile_name, :lockfile_name + + def initialize(dependency_name:, dependency_requirements:, + gemfile_name:, lockfile_name:) + @dependency_name = dependency_name + @dependency_requirements = dependency_requirements + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + end + + def version_details + dep = dependency_from_definition + + # If the dependency wasn't found in the definition, but *is* + # included in a gemspec, it's because the Gemfile didn't import + # the gemspec. This is unusual, but the correct behaviour if/when + # it happens is to behave as if the repo was gemspec-only. + return "latest" if dep.nil? && dependency_requirements.any? + + # Otherwise, if the dependency wasn't found it's because it is a + # subdependency that was removed when attempting to update it. + return nil if dep.nil? + + # If the dependency is Bundler itself then we can't trust the + # version that has been returned (it's the version Dependabot is + # running on, rather than the true latest resolvable version). + return nil if dep.name == "bundler" + + details = { + version: dep.version, + ruby_version: ruby_version, + fetcher: fetcher_class(dep) + } + details[:commit_sha] = dep.source.revision if dep.source.instance_of?(::Bundler::Source::Git) + details + end + + private + + # rubocop:disable Metrics/PerceivedComplexity + def dependency_from_definition(unlock_subdependencies: true) + dependencies_to_unlock = [dependency_name] + dependencies_to_unlock += subdependencies if unlock_subdependencies + begin + definition = build_definition(dependencies_to_unlock) + definition.resolve_remotely! + rescue ::Bundler::GemNotFound => e + unlock_yanked_gem(dependencies_to_unlock, e) && retry + rescue ::Bundler::HTTPError => e + # Retry network errors + # Note: in_a_native_bundler_context will also retry `Bundler::HTTPError` errors + # up to three times meaning we'll end up retrying this error up to six times + # TODO: Could we get rid of this retry logic and only rely on + # SharedBundlerHelpers.in_a_native_bundler_context + attempt ||= 1 + attempt += 1 + raise if attempt > 3 || !e.message.include?("Network error") + + retry + end + + dep = definition.resolve.find { |d| d.name == dependency_name } + return dep if dep + return if dependency_requirements.any? || !unlock_subdependencies + + # If no definition was found and we're updating a sub-dependency, + # try again but without unlocking any other sub-dependencies + dependency_from_definition(unlock_subdependencies: false) + end + # rubocop:enable Metrics/PerceivedComplexity + + def subdependencies + # If there's no lockfile we don't need to worry about + # subdependencies + return [] unless lockfile + + all_deps = ::Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s).uniq + top_level = build_definition([]).dependencies. + map(&:name).map(&:to_s) + + all_deps - top_level + end + + def build_definition(dependencies_to_unlock) + # NOTE: we lock shared dependencies to avoid any top-level + # dependencies getting unlocked (which would happen if they were + # also subdependencies of the dependency being unlocked) + ::Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: dependencies_to_unlock, + lock_shared_dependencies: true + ) + end + + def unlock_yanked_gem(dependencies_to_unlock, error) + raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) + + gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). + named_captures["name"] + raise if dependencies_to_unlock.include?(gem_name) + + dependencies_to_unlock << gem_name + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name + return unless File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def fetcher_class(dep) + return unless dep.source.is_a?(::Bundler::Source::Rubygems) + + dep.source.fetchers.first.fetchers.first.class.to_s + end + + def ruby_version + return nil unless gemfile_name + + @ruby_version ||= build_definition([]).ruby_version&.gem_version + end + end +end diff --git a/bundler/helpers/v1/monkey_patches/definition_bundler_version_patch.rb b/bundler/helpers/v1/monkey_patches/definition_bundler_version_patch.rb new file mode 100644 index 00000000000..6734d4c8e12 --- /dev/null +++ b/bundler/helpers/v1/monkey_patches/definition_bundler_version_patch.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "bundler/definition" + +# Ignore the Bundler version specified in the Gemfile (since the only Bundler +# version available to us is the one we're using). +module BundlerDefinitionBundlerVersionPatch + def expanded_dependencies + @expanded_dependencies ||= + expand_dependencies(dependencies + metadata_dependencies, @remote). + reject { |d| d.name == "bundler" } + end +end + +Bundler::Definition.prepend(BundlerDefinitionBundlerVersionPatch) diff --git a/bundler/helpers/v1/monkey_patches/definition_ruby_version_patch.rb b/bundler/helpers/v1/monkey_patches/definition_ruby_version_patch.rb new file mode 100644 index 00000000000..a00dc55696b --- /dev/null +++ b/bundler/helpers/v1/monkey_patches/definition_ruby_version_patch.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require "bundler/definition" + +module BundlerDefinitionRubyVersionPatch + def index + @index ||= super.tap do + if ruby_version + requested_version = ruby_version.to_gem_version_with_patchlevel + sources.metadata_source.specs << + Gem::Specification.new("ruby\0", requested_version) + end + + %w(2.5.3p105 2.6.10p210 2.7.6p219 3.0.4p208).each do |version| + sources.metadata_source.specs << Gem::Specification.new("ruby\0", version) + end + end + end +end + +Bundler::Definition.prepend(BundlerDefinitionRubyVersionPatch) diff --git a/bundler/helpers/v1/monkey_patches/fileutils_keyword_splat_patch.rb b/bundler/helpers/v1/monkey_patches/fileutils_keyword_splat_patch.rb new file mode 100644 index 00000000000..0bc75505bf4 --- /dev/null +++ b/bundler/helpers/v1/monkey_patches/fileutils_keyword_splat_patch.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require "bundler/vendor/fileutils/lib/fileutils" + +# Port +# https://github.com/ruby/fileutils/commit/a5eca84a4240e29bb7886c3ef7085d464a972dd0 +# to fix keyword argument errors on Ruby 3.1 + +module BundlerFileUtilsKeywordSplatPatch + def entries + opts = {} + opts[:encoding] = ::Encoding::UTF_8 if fu_windows? + Dir.entries(path, **opts). + reject { |n| n == "." || n == ".." }. + map { |n| self.class.new(prefix, join(rel, n.untaint)) } + end +end + +Bundler::FileUtils::Entry_.prepend(BundlerFileUtilsKeywordSplatPatch) diff --git a/bundler/helpers/v1/monkey_patches/git_source_patch.rb b/bundler/helpers/v1/monkey_patches/git_source_patch.rb new file mode 100644 index 00000000000..a5132beb3ed --- /dev/null +++ b/bundler/helpers/v1/monkey_patches/git_source_patch.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require "bundler/source" + +module Bundler + class Source + class Git + class GitProxy + private + + # Bundler allows ssh authentication when talking to GitHub but there's + # no way for Dependabot to do so (it doesn't have any ssh keys). + # Instead, we convert all `git@github.com:` URLs to use HTTPS. + def configured_uri_for(uri) + uri = uri.gsub(%r{git@(.*?):/?}, 'https://\1/') + if uri.match?(/https?:/) + remote = URI(uri) + config_auth = + Bundler.settings[remote.to_s] || Bundler.settings[remote.host] + remote.userinfo ||= config_auth + remote.to_s + else + uri + end + end + end + end + end +end + +module Bundler + class Source + class Git < Path + private + + def serialize_gemspecs_in(destination) + original_load_paths = $LOAD_PATH.dup + reduced_load_paths = original_load_paths. + reject { |p| p.include?("/gems/") } + + $LOAD_PATH.shift until $LOAD_PATH.empty? + reduced_load_paths.each { |p| $LOAD_PATH << p } + + destination = destination.expand_path(Bundler.root) if destination.relative? + Dir["#{destination}/#{@glob}"].each do |spec_path| + # Evaluate gemspecs and cache the result. Gemspecs + # in git might require git or other dependencies. + # The gemspecs we cache should already be evaluated. + spec = Bundler.load_gemspec(spec_path) + next unless spec + + Bundler.rubygems.set_installed_by_version(spec) + Bundler.rubygems.validate(spec) + File.binwrite(spec_path, spec.to_ruby) + end + $LOAD_PATH.shift until $LOAD_PATH.empty? + original_load_paths.each { |p| $LOAD_PATH << p } + end + end + end +end diff --git a/bundler/helpers/v1/monkey_patches/resolver_spec_group_sane_eql.rb b/bundler/helpers/v1/monkey_patches/resolver_spec_group_sane_eql.rb new file mode 100644 index 00000000000..3fbb29a4ae1 --- /dev/null +++ b/bundler/helpers/v1/monkey_patches/resolver_spec_group_sane_eql.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "bundler/resolver/spec_group" + +# Port +# https://github.com/rubygems/bundler/commit/30a690edbdf5ee64ea54afc7d0c91d910ff2b80e +# to fix flaky failures on Bundler 1 + +module BundlerResolverSpecGroupSaneEql + def eql?(other) + return unless other.is_a?(self.class) + + super(other) + end +end + +Bundler::Resolver::SpecGroup.prepend(BundlerResolverSpecGroupSaneEql) diff --git a/bundler/helpers/v1/run.rb b/bundler/helpers/v1/run.rb new file mode 100644 index 00000000000..099d722f248 --- /dev/null +++ b/bundler/helpers/v1/run.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +gem "bundler", "~> 1.17" +require "bundler/setup" +require "json" + +$LOAD_PATH.unshift(File.expand_path("./lib", __dir__)) +$LOAD_PATH.unshift(File.expand_path("./monkey_patches", __dir__)) + +trap "HUP" do + puts JSON.generate(error: "timeout", error_class: "Timeout::Error", trace: []) + exit 2 +end + +# Bundler monkey patches +require "definition_ruby_version_patch" +require "definition_bundler_version_patch" +require "fileutils_keyword_splat_patch" +require "git_source_patch" +require "resolver_spec_group_sane_eql" + +require "functions" + +MAX_BUNDLER_VERSION = "2.0.0" + +def validate_bundler_version! + return true if correct_bundler_version? + + raise StandardError, "Called with Bundler '#{Bundler::VERSION}', expected < '#{MAX_BUNDLER_VERSION}'" +end + +def correct_bundler_version? + Gem::Version.new(Bundler::VERSION) < Gem::Version.new(MAX_BUNDLER_VERSION) +end + +def output(obj) + print JSON.dump(obj) +end + +begin + validate_bundler_version! + + request = JSON.parse($stdin.read) + + function = request["function"] + args = request["args"].transform_keys(&:to_sym) + + output({ result: Functions.send(function, **args) }) +rescue StandardError => e + output( + { error: e.message, error_class: e.class, trace: e.backtrace } + ) + exit(1) +end diff --git a/bundler/helpers/v1/spec/functions/conflicting_dependency_resolver_spec.rb b/bundler/helpers/v1/spec/functions/conflicting_dependency_resolver_spec.rb new file mode 100644 index 00000000000..3fa9794e905 --- /dev/null +++ b/bundler/helpers/v1/spec/functions/conflicting_dependency_resolver_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::ConflictingDependencyResolver do + include_context "in a temporary bundler directory" + + let(:conflicting_dependency_resolver) do + described_class.new( + dependency_name: dependency_name, + target_version: target_version, + lockfile_name: "Gemfile.lock" + ) + end + + let(:dependency_name) { "dummy-pkg-a" } + let(:target_version) { "2.0.0" } + + let(:project_name) { "blocked_by_subdep" } + + describe "#conflicting_dependencies" do + subject(:conflicting_dependencies) do + in_tmp_folder { conflicting_dependency_resolver.conflicting_dependencies } + end + + it "returns a list of dependencies that block the update" do + expect(conflicting_dependencies).to eq( + [{ + "explanation" => "dummy-pkg-b (1.0.0) requires dummy-pkg-a (< 2.0.0)", + "name" => "dummy-pkg-b", + "version" => "1.0.0", + "requirement" => "< 2.0.0" + }] + ) + end + + context "for nested transitive dependencies" do + let(:project_name) { "transitive_blocking" } + let(:dependency_name) { "activesupport" } + let(:target_version) { "6.0.0" } + + it "returns a list of dependencies that block the update" do + expect(conflicting_dependencies).to match_array( + [ + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0)", + "name" => "rails", + "requirement" => "= 5.2.0", + "version" => "5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via actionpack (5.2.0)", + "name" => "actionpack", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via actionview (5.2.0)", + "name" => "actionview", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activejob (5.2.0)", + "name" => "activejob", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activemodel (5.2.0)", + "name" => "activemodel", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activerecord (5.2.0)", + "name" => "activerecord", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via railties (5.2.0)", + "name" => "railties", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + } + ] + ) + end + end + + context "with multiple blocking dependencies" do + let(:dependency_name) { "activesupport" } + let(:current_version) { "5.0.0" } + let(:target_version) { "6.0.0" } + let(:project_name) { "multiple_blocking" } + + it "returns all of the blocking dependencies" do + expect(conflicting_dependencies).to match_array( + [ + { + "explanation" => "actionmailer (5.0.0) requires activesupport (= 5.0.0) via actionpack (5.0.0)", + "name" => "actionpack", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + }, + { + "explanation" => "actionview (5.0.0) requires activesupport (= 5.0.0)", + "name" => "actionview", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + }, + { + "explanation" => "actionmailer (5.0.0) requires activesupport (= 5.0.0) via activejob (5.0.0)", + "name" => "activejob", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + } + ] + ) + end + end + + context "without any blocking dependencies" do + let(:target_version) { "1.0.0" } + + it "returns an empty list" do + expect(conflicting_dependencies).to eq([]) + end + end + end +end diff --git a/bundler/helpers/v1/spec/functions/dependency_source_spec.rb b/bundler/helpers/v1/spec/functions/dependency_source_spec.rb new file mode 100644 index 00000000000..d1f9b2fa3f2 --- /dev/null +++ b/bundler/helpers/v1/spec/functions/dependency_source_spec.rb @@ -0,0 +1,187 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::DependencySource do + include_context "in a temporary bundler directory" + + let(:dependency_source) do + described_class.new( + gemfile_name: "Gemfile", + dependency_name: dependency_name + ) + end + + let(:dependency_name) { "business" } + + let(:project_name) { "specified_source_no_lockfile" } + let(:registry_url) { "https://repo.fury.io/greysteil/" } + let(:gemfury_business_url) do + "https://repo.fury.io/greysteil/api/v1/dependencies?gems=business" + end + + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 404) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 200) + stub_request(:get, gemfury_business_url). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + end + + describe "#private_registry_versions" do + subject(:private_registry_versions) do + in_tmp_folder { dependency_source.private_registry_versions } + end + + it "returns all versions from the private source" do + is_expected.to eq([ + Gem::Version.new("1.5.0"), + Gem::Version.new("1.9.0"), + Gem::Version.new("1.10.0.beta") + ]) + end + + context "specified as the default source" do + let(:project_name) { "specified_default_source_no_lockfile" } + + it "returns all versions from the private source" do + is_expected.to eq([ + Gem::Version.new("1.5.0"), + Gem::Version.new("1.9.0"), + Gem::Version.new("1.10.0.beta") + ]) + end + end + + context "that we don't have authentication details for" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + end + + it "blows up with a useful error" do + error_class = Bundler::Fetcher::AuthenticationRequiredError + error_message = "Authentication is required for repo.fury.io" + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(error_class) + expect(error.message).to include(error_message) + end + end + end + + context "that we have bad authentication details for" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + end + + it "blows up with a useful error" do + error_class = Bundler::Fetcher::BadAuthenticationError + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(error_class) + expect(error.message). + to include("Bad username or password for") + end + end + end + + context "that bad-requested, but was a private repo" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + end + + it "blows up with a useful error" do + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(Bundler::HTTPError) + expect(error.message). + to include("Could not fetch specs from") + end + end + end + + context "that doesn't have details of the gem" do + before do + stub_request(:get, gemfury_business_url). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 404) + + # Stub indexes to return details of other gems (but not this one) + stub_request(:get, registry_url + "specs.4.8.gz"). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_response") + ) + stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_prerelease_response") + ) + end + + it { is_expected.to be_empty } + end + + context "that only implements the old Bundler index format..." do + let(:project_name) { "sidekiq_pro" } + let(:dependency_name) { "sidekiq-pro" } + let(:registry_url) { "https://gems.contribsys.com/" } + + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: %w(username password)). + to_return(status: 404) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: %w(username password)). + to_return(status: 404) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: %w(username password)). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_response") + ) + stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). + with(basic_auth: %w(username password)). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_prerelease_response") + ) + end + + it "returns all versions from the private source" do + expect(private_registry_versions.length).to eql(70) + expect(private_registry_versions.min).to eql(Gem::Version.new("1.0.0")) + expect(private_registry_versions.max).to eql(Gem::Version.new("3.5.2")) + end + end + end +end diff --git a/bundler/helpers/v1/spec/functions/file_parser_spec.rb b/bundler/helpers/v1/spec/functions/file_parser_spec.rb new file mode 100644 index 00000000000..edd47436f4d --- /dev/null +++ b/bundler/helpers/v1/spec/functions/file_parser_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::FileParser do + include_context "in a temporary bundler directory" + + let(:dependency_source) do + described_class.new( + lockfile_name: "Gemfile.lock" + ) + end + + describe "#parsed_gemfile" do + let(:project_name) { "gemfile" } + + subject(:parsed_gemfile) do + in_tmp_folder do + dependency_source.parsed_gemfile(gemfile_name: "Gemfile") + end + end + + it "parses gemfile" do + parsed_gemfile = [ + { + groups: [:default], + name: "business", + requirement: Gem::Requirement.new("~> 1.4.0"), + source: nil, + type: :runtime + }, + { + groups: [:default], + name: "statesman", + requirement: Gem::Requirement.new("~> 1.2.0"), + source: nil, + type: :runtime + } + ] + is_expected.to eq(parsed_gemfile) + end + end + + describe "#parsed_gemspec" do + let(:project_name) { "gemfile_exact" } + + subject(:parsed_gemspec) do + in_tmp_folder do |_tmp_path| + dependency_source.parsed_gemspec(gemspec_name: "example.gemspec") + end + end + + it "parses gemspec" do + parsed_gemspec = [ + { + groups: nil, + name: "business", + requirement: Gem::Requirement.new("= 1.0.0"), + source: nil, + type: :runtime + }, + { + groups: nil, + name: "statesman", + requirement: Gem::Requirement.new("= 1.0.0"), + source: nil, + type: :runtime + } + ] + is_expected.to eq(parsed_gemspec) + end + end +end diff --git a/bundler/helpers/v1/spec/functions/force_updater_spec.rb b/bundler/helpers/v1/spec/functions/force_updater_spec.rb new file mode 100644 index 00000000000..2e78980ba65 --- /dev/null +++ b/bundler/helpers/v1/spec/functions/force_updater_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::ForceUpdater do + include_context "in a temporary bundler directory" + include_context "stub rubygems compact index" + + let(:force_updater) do + described_class.new( + dependency_name: dependency_name, + target_version: target_version, + gemfile_name: gemfile_name, + lockfile_name: lockfile_name, + update_multiple_dependencies: update_multiple_dependencies + ) + end + let(:gemfile_name) { "Gemfile" } + let(:lockfile_name) { "Gemfile.lock" } + let(:update_multiple_dependencies) { true } + + describe "#run" do + subject(:force_update) do + in_tmp_folder { force_updater.run } + end + + context "with a version conflict" do + let(:target_version) { "3.6.0" } + let(:dependency_name) { "rspec-support" } + let(:project_name) { "version_conflict" } + + it "updates the conflicting dependencies" do + updated_deps, _specs = force_update + expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }]) + end + + context "when updating a single dependency" do + let(:update_multiple_dependencies) { false } + + it { expect { force_update }.to raise_error(Bundler::VersionConflict) } + end + end + + context "with a version conflict in gems rb" do + let(:target_version) { "3.6.0" } + let(:dependency_name) { "rspec-support" } + let(:project_name) { "version_conflict_gems_rb" } + let(:gemfile_name) { "gems.rb" } + let(:lockfile_name) { "gems.locked" } + + it "updates the conflicting dependencies" do + updated_deps, _specs = force_update + expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }]) + end + end + end +end diff --git a/bundler/helpers/v1/spec/functions/version_resolver_spec.rb b/bundler/helpers/v1/spec/functions/version_resolver_spec.rb new file mode 100644 index 00000000000..6ce1cda32b3 --- /dev/null +++ b/bundler/helpers/v1/spec/functions/version_resolver_spec.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::VersionResolver do + include_context "in a temporary bundler directory" + include_context "stub rubygems compact index" + + let(:version_resolver) do + described_class.new( + dependency_name: dependency_name, + dependency_requirements: dependency_requirements, + gemfile_name: "Gemfile", + lockfile_name: "Gemfile.lock" + ) + end + + let(:dependency_name) { "business" } + let(:dependency_requirements) do + [{ + file: "Gemfile", + requirement: requirement_string, + groups: [], + source: source + }] + end + let(:source) { nil } + + let(:rubygems_url) { "https://index.rubygems.org/api/v1/" } + let(:old_index_url) { rubygems_url + "dependencies" } + + describe "#version_details" do + subject do + in_tmp_folder { version_resolver.version_details } + end + + let(:project_name) { "gemfile" } + let(:requirement_string) { " >= 0" } + + its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::CompactIndex") } + + context "with a private gemserver source" do + include_context "stub rubygems compact index" + + let(:project_name) { "specified_source" } + let(:requirement_string) { ">= 0" } + + before do + gemfury_url = "https://repo.fury.io/greysteil/" + gemfury_deps_url = gemfury_url + "api/v1/dependencies" + + stub_request(:get, gemfury_url + "versions"). + to_return(status: 200, body: fixture("ruby", "gemfury-index")) + stub_request(:get, gemfury_url + "info/business").to_return(status: 404) + stub_request(:get, gemfury_deps_url).to_return(status: 200) + stub_request(:get, gemfury_deps_url + "?gems=business,statesman"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + stub_request(:get, gemfury_deps_url + "?gems=business"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + stub_request(:get, gemfury_deps_url + "?gems=statesman"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + end + + its([:version]) { is_expected.to eq(Gem::Version.new("1.9.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") } + end + + context "with a git source" do + let(:project_name) { "git_source" } + + its([:version]) { is_expected.to eq(Gem::Version.new("1.6.0")) } + its([:fetcher]) { is_expected.to be_nil } + end + + context "when Bundler's compact index is down" do + before do + stub_request(:get, "https://index.rubygems.org/versions"). + to_return(status: 500, body: "We'll be back soon") + stub_request(:get, "https://index.rubygems.org/info/public_suffix"). + to_return(status: 500, body: "We'll be back soon") + stub_request(:get, old_index_url).to_return(status: 200) + stub_request(:get, old_index_url + "?gems=business,statesman"). + to_return( + status: 200, + body: fixture("rubygems_responses", + "dependencies-default-gemfile") + ) + end + + its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") } + end + + context "with no update possible due to a version conflict" do + let(:project_name) { "version_conflict_with_listed_subdep" } + let(:dependency_name) { "rspec-mocks" } + let(:requirement_string) { ">= 0" } + + its([:version]) { is_expected.to eq(Gem::Version.new("3.6.0")) } + end + end +end diff --git a/bundler/helpers/v1/spec/native_spec_helper.rb b/bundler/helpers/v1/spec/native_spec_helper.rb new file mode 100644 index 00000000000..414047798da --- /dev/null +++ b/bundler/helpers/v1/spec/native_spec_helper.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require "rspec/its" +require "webmock/rspec" +require "tmpdir" + +$LOAD_PATH.unshift(File.expand_path("../lib", __dir__)) +$LOAD_PATH.unshift(File.expand_path("../monkey_patches", __dir__)) + +# Bundler monkey patches +require "definition_ruby_version_patch" +require "definition_bundler_version_patch" +require "fileutils_keyword_splat_patch" +require "git_source_patch" +require "resolver_spec_group_sane_eql" + +require "functions" + +RSpec.configure do |config| + config.color = true + config.order = :rand + config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true } + config.raise_errors_for_deprecations! +end + +# Duplicated in lib/dependabot/bundler/file_updater/lockfile_updater.rb +# TODO: Stop sanitizing the lockfile once we have bundler 2 installed +LOCKFILE_ENDING = /(?\s*(?:RUBY VERSION|BUNDLED WITH).*)/m + +def project_dependency_files(project) + project_path = File.expand_path(File.join("../../spec/fixtures/projects/bundler1", project)) + + raise "Fixture does not exist for project: '#{project}'" unless Dir.exist?(project_path) + + Dir.chdir(project_path) do + # NOTE: Include dotfiles (e.g. .npmrc) + files = Dir.glob("**/*", File::FNM_DOTMATCH) + files = files.select { |f| File.file?(f) } + files.map do |filename| + content = File.read(filename) + content = content.gsub(LOCKFILE_ENDING, "") if filename == "Gemfile.lock" + { + name: filename, + content: content + } + end + end +end + +def fixture(*name) + File.read(File.join("../../spec/fixtures", File.join(*name))) +end diff --git a/bundler/helpers/v1/spec/shared_contexts.rb b/bundler/helpers/v1/spec/shared_contexts.rb new file mode 100644 index 00000000000..344a620fbfc --- /dev/null +++ b/bundler/helpers/v1/spec/shared_contexts.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "bundler/compact_index_client" +require "bundler/compact_index_client/updater" + +TMP_DIR_PATH = File.expand_path("../tmp", __dir__) + +RSpec.shared_context "in a temporary bundler directory" do + let(:project_name) { "gemfile" } + + let(:tmp_path) do + FileUtils.mkdir_p(TMP_DIR_PATH) + dir = Dir.mktmpdir("native_helper_spec_", TMP_DIR_PATH) + Pathname.new(dir).expand_path + end + + before do + project_dependency_files(project_name).each do |file| + File.write(File.join(tmp_path, file[:name]), file[:content]) + end + end + + def in_tmp_folder(&block) + Dir.chdir(tmp_path, &block) + end +end + +RSpec.shared_context "without caching rubygems" do + before do + # Stub Bundler to stop it using a cached versions of Rubygems + allow_any_instance_of(Bundler::CompactIndexClient::Updater). + to receive(:etag_for).and_return("") + end +end + +RSpec.shared_context "stub rubygems compact index" do + include_context "without caching rubygems" + + before do + # Stub the Rubygems index + stub_request(:get, "https://index.rubygems.org/versions"). + to_return( + status: 200, + body: fixture("rubygems_responses", "index") + ) + + # Stub the Rubygems response for each dependency we have a fixture for + fixtures = + Dir[File.join("../../spec", "fixtures", "rubygems_responses", "info-*")] + fixtures.each do |path| + dep_name = path.split("/").last.gsub("info-", "") + stub_request(:get, "https://index.rubygems.org/info/#{dep_name}"). + to_return( + status: 200, + body: fixture("rubygems_responses", "info-#{dep_name}") + ) + end + end +end diff --git a/bundler/helpers/v2/.gitignore b/bundler/helpers/v2/.gitignore new file mode 100644 index 00000000000..c88c5c24353 --- /dev/null +++ b/bundler/helpers/v2/.gitignore @@ -0,0 +1,8 @@ +/.bundle +/.env +/tmp +/dependabot-*.gem +Gemfile.lock +spec/fixtures/projects/*/.bundle/ +!spec/fixtures/projects/**/Gemfile.lock +!spec/fixtures/projects/**/vendor diff --git a/bundler/helpers/v2/Gemfile b/bundler/helpers/v2/Gemfile new file mode 100644 index 00000000000..37e8704dd81 --- /dev/null +++ b/bundler/helpers/v2/Gemfile @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# NOTE: Used to run native helper specs +group :test do + gem "debug", ">= 1.0.0" + gem "rspec", "~> 3.8" + gem "rspec-its", "~> 1.2" + gem "vcr", "6.1.0" + gem "webmock", "~> 3.4" +end diff --git a/bundler/helpers/v2/build b/bundler/helpers/v2/build new file mode 100755 index 00000000000..3a42f12ebd7 --- /dev/null +++ b/bundler/helpers/v2/build @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +helpers_dir=$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +if [ -z "$DEPENDABOT_NATIVE_HELPERS_PATH" ]; then + install_dir="$helpers_dir" +else + install_dir="$DEPENDABOT_NATIVE_HELPERS_PATH/bundler/v2" + mkdir -p "$install_dir" + + cp -r \ + "$helpers_dir/lib" \ + "$helpers_dir/monkey_patches" \ + "$helpers_dir/run.rb" \ + "$helpers_dir/Gemfile" \ + "$install_dir" +fi + +cd "$install_dir" + +default_version=$(ruby -rbundler -e'print Bundler::VERSION') + +export GEM_HOME=$install_dir/.bundle + +gem install bundler -v "$default_version" --no-document + +bundle config --local path.system true + +if [ -n "$DEPENDABOT_NATIVE_HELPERS_PATH" ]; then + bundle config --local without "test" +fi + +bundle install diff --git a/bundler/helpers/v2/lib/functions.rb b/bundler/helpers/v2/lib/functions.rb new file mode 100644 index 00000000000..58b2b00513b --- /dev/null +++ b/bundler/helpers/v2/lib/functions.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true + +require "functions/conflicting_dependency_resolver" +require "functions/dependency_source" +require "functions/file_parser" +require "functions/force_updater" +require "functions/lockfile_updater" +require "functions/version_resolver" + +module Functions + class NotImplementedError < StandardError; end + + def self.parsed_gemfile(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + FileParser.new(lockfile_name: args.fetch(:lockfile_name)). + parsed_gemfile(gemfile_name: args.fetch(:gemfile_name)) + end + + def self.parsed_gemspec(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + FileParser.new(lockfile_name: args.fetch(:lockfile_name)). + parsed_gemspec(gemspec_name: args.fetch(:gemspec_name)) + end + + def self.vendor_cache_dir(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: []) + Bundler.settings.app_cache_path + end + + def self.update_lockfile(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + LockfileUpdater.new( + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name), + dependencies: args.fetch(:dependencies) + ).run + end + + def self.force_update(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + ForceUpdater.new( + dependency_name: args.fetch(:dependency_name), + target_version: args.fetch(:target_version), + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name), + update_multiple_dependencies: args.fetch(:update_multiple_dependencies) + ).run + end + + def self.dependency_source_type(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).type + end + + def self.depencency_source_latest_git_version(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).latest_git_version( + dependency_source_url: args.fetch(:dependency_source_url), + dependency_source_branch: args.fetch(:dependency_source_branch) + ) + end + + def self.private_registry_versions(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + DependencySource.new( + gemfile_name: args.fetch(:gemfile_name), + dependency_name: args.fetch(:dependency_name) + ).private_registry_versions + end + + def self.resolve_version(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + VersionResolver.new( + dependency_name: args.fetch(:dependency_name), + dependency_requirements: args.fetch(:dependency_requirements), + gemfile_name: args.fetch(:gemfile_name), + lockfile_name: args.fetch(:lockfile_name) + ).version_details + end + + def self.jfrog_source(**args) + # Set flags and credentials + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + Bundler::Definition.build(args.fetch(:gemfile_name), nil, {}). + send(:sources). + rubygems_remotes. + find { |uri| uri.host.include?("jfrog") }&. + host + end + + def self.git_specs(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + + git_specs = Bundler::Definition.build(args.fetch(:gemfile_name), nil, {}).dependencies. + select do |spec| + spec.source.is_a?(Bundler::Source::Git) + end + git_specs.map do |spec| + # Piggy-back off some private Bundler methods to configure the + # URI with auth details in the same way Bundler does. + git_proxy = spec.source.send(:git_proxy) + auth_uri = spec.source.uri.gsub("git://", "https://") + auth_uri = git_proxy.send(:configured_uri_for, auth_uri) + auth_uri += ".git" unless auth_uri.end_with?(".git") + auth_uri += "/info/refs?service=git-upload-pack" + { + uri: spec.source.uri, + auth_uri: auth_uri + } + end + end + + def self.conflicting_dependencies(**args) + set_bundler_flags_and_credentials(dir: args.fetch(:dir), credentials: args.fetch(:credentials)) + ConflictingDependencyResolver.new( + dependency_name: args.fetch(:dependency_name), + target_version: args.fetch(:target_version), + lockfile_name: args.fetch(:lockfile_name) + ).conflicting_dependencies + end + + def self.set_bundler_flags_and_credentials(dir:, credentials:) + dir = dir ? Pathname.new(dir) : dir + Bundler.instance_variable_set(:@root, dir) + + # Remove installed gems from the default Rubygems index + Gem::Specification.all = + Gem::Specification.send(:default_stubs, "*.gemspec") + + # Set auth details + relevant_credentials(credentials).each do |cred| + token = cred["token"] || + "#{cred['username']}:#{cred['password']}" + + Bundler.settings.set_command_option( + cred.fetch("host"), + token.gsub("@", "%40").gsub("?", "%3F") + ) + end + + # NOTE: Prevent bundler from printing resolution information + Bundler.ui = Bundler::UI::Silent.new + + Bundler.settings.set_command_option("forget_cli_options", "true") + end + + def self.relevant_credentials(credentials) + [ + *git_source_credentials(credentials), + *private_registry_credentials(credentials) + ].select { |cred| cred["password"] || cred["token"] } + end + + def self.private_registry_credentials(credentials) + credentials. + select { |cred| cred["type"] == "rubygems_server" } + end + + def self.git_source_credentials(credentials) + credentials. + select { |cred| cred["type"] == "git_source" } + end +end diff --git a/bundler/helpers/v2/lib/functions/conflicting_dependency_resolver.rb b/bundler/helpers/v2/lib/functions/conflicting_dependency_resolver.rb new file mode 100644 index 00000000000..b6576d461c3 --- /dev/null +++ b/bundler/helpers/v2/lib/functions/conflicting_dependency_resolver.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Functions + class ConflictingDependencyResolver + def initialize(dependency_name:, target_version:, lockfile_name:) + @dependency_name = dependency_name + @target_version = target_version + @lockfile_name = lockfile_name + end + + # Finds any dependencies in the lockfile that have a subdependency on the + # given dependency that does not satisfly the target_version. + # @return [Array String}] + # * explanation [String] a sentence explaining the conflict + # * name [String] the blocking dependencies name + # * version [String] the version of the blocking dependency + # * requirement [String] the requirement on the target_dependency + def conflicting_dependencies + Bundler.settings.set_command_option("only_update_to_newer_versions", true) + + parent_specs.flat_map do |parent_spec| + top_level_specs_for(parent_spec).map do |top_level| + dependency = parent_spec.dependencies.find { |bd| bd.name == dependency_name } + { + "explanation" => explanation(parent_spec, dependency, top_level), + "name" => parent_spec.name, + "version" => parent_spec.version.to_s, + "requirement" => dependency.requirement.to_s + } + end + end + end + + private + + attr_reader :dependency_name, :target_version, :lockfile_name + + def parent_specs + version = Gem::Version.new(target_version) + parsed_lockfile.specs.filter do |spec| + spec.dependencies.any? do |dep| + dep.name == dependency_name && + !dep.requirement.satisfied_by?(version) + end + end + end + + def top_level_specs_for(parent_spec) + return [parent_spec] if top_level?(parent_spec) + + parsed_lockfile.specs.filter do |spec| + spec.dependencies.any? do |dep| + dep.name == parent_spec.name && top_level?(spec) + end + end + end + + def top_level?(spec) + parsed_lockfile.dependencies.key?(spec.name) + end + + def explanation(spec, dependency, top_level) + if spec.name == top_level.name + "#{spec.name} (#{spec.version}) requires #{dependency_name} (#{dependency.requirement})" + else + "#{top_level.name} (#{top_level.version}) requires #{dependency_name} " \ + "(#{dependency.requirement}) via #{spec.name} (#{spec.version})" + end + end + + def parsed_lockfile + @parsed_lockfile ||= Bundler::LockfileParser.new(lockfile) + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + end +end diff --git a/bundler/helpers/v2/lib/functions/dependency_source.rb b/bundler/helpers/v2/lib/functions/dependency_source.rb new file mode 100644 index 00000000000..2ad359ee195 --- /dev/null +++ b/bundler/helpers/v2/lib/functions/dependency_source.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Functions + class DependencySource + attr_reader :gemfile_name, :dependency_name + + RUBYGEMS = "rubygems" + PRIVATE_REGISTRY = "private" + GIT = "git" + OTHER = "other" + + def initialize(gemfile_name:, dependency_name:) + @gemfile_name = gemfile_name + @dependency_name = dependency_name + end + + def type + bundler_source = specified_source || default_source + type_of(bundler_source) + end + + def latest_git_version(dependency_source_url:, dependency_source_branch:) + source = Bundler::Source::Git.new( + "uri" => dependency_source_url, + "branch" => dependency_source_branch, + "name" => dependency_name, + "submodules" => true + ) + + # Tell Bundler we're fine with fetching the source remotely + source.instance_variable_set(:@allow_remote, true) + + spec = source.specs.first + { version: spec.version, commit_sha: spec.source.revision } + end + + def private_registry_versions + bundler_source = specified_source || default_source + + bundler_source. + fetchers.flat_map do |fetcher| + fetcher. + specs([dependency_name], bundler_source). + search_all(dependency_name) + end. + map(&:version) + end + + private + + def type_of(bundler_source) + case bundler_source + when Bundler::Source::Rubygems + remote = bundler_source.remotes.first + if remote.nil? || remote.to_s == "https://rubygems.org/" + RUBYGEMS + else + PRIVATE_REGISTRY + end + when Bundler::Source::Git + GIT + else + OTHER + end + end + + def specified_source + return @specified_source if defined? @specified_source + + @specified_source = definition.dependencies. + find { |dep| dep.name == dependency_name }&.source + end + + def default_source + definition.send(:sources).default_source + end + + def definition + @definition ||= Bundler::Definition.build(gemfile_name, nil, {}) + end + + def serialize_bundler_source(source) + { + type: source.class.to_s + } + end + end +end diff --git a/bundler/helpers/v2/lib/functions/file_parser.rb b/bundler/helpers/v2/lib/functions/file_parser.rb new file mode 100644 index 00000000000..05532fd865f --- /dev/null +++ b/bundler/helpers/v2/lib/functions/file_parser.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +require "uri" + +module Functions + class FileParser + def initialize(lockfile_name:) + @lockfile_name = lockfile_name + end + + attr_reader :lockfile_name + + def parsed_gemfile(gemfile_name:) + Bundler::Definition.build(gemfile_name, nil, {}). + dependencies.select(&:current_platform?). + reject { |dep| dep.source.is_a?(Bundler::Source::Gemspec) }. + map { |dep| serialize_bundler_dependency(dep) } + end + + def parsed_gemspec(gemspec_name:) + Bundler.load_gemspec_uncached(gemspec_name). + dependencies. + map { |dep| serialize_bundler_dependency(dep) } + end + + private + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def parsed_lockfile + return unless lockfile + + @parsed_lockfile ||= Bundler::LockfileParser.new(lockfile) + end + + def source_from_lockfile(dependency_name) + parsed_lockfile&.specs&.find { |s| s.name == dependency_name }&.source + end + + def source_for(dependency) + source = dependency.source + if lockfile && default_rubygems?(source) + # If there's a lockfile and the Gemfile doesn't have anything + # interesting to say about the source, check that. + source = source_from_lockfile(dependency.name) + end + raise "Bad source: #{source}" unless sources.include?(source.class) + + return nil if default_rubygems?(source) + + details = { type: source.class.name.split("::").last.downcase } + details.merge!(git_source_details(source)) if source.is_a?(Bundler::Source::Git) + details[:url] = source.remotes.first.to_s if source.is_a?(Bundler::Source::Rubygems) + details + end + + def git_source_details(source) + { + url: source.uri, + branch: source.branch, + ref: source.ref + } + end + + RUBYGEMS_HOSTS = [ + "rubygems.org", + "www.rubygems.org" + ].freeze + + def default_rubygems?(source) + return true if source.nil? + return false unless source.is_a?(Bundler::Source::Rubygems) + + source.remotes.any? do |r| + RUBYGEMS_HOSTS.include?(URI(r.to_s).host) + end + end + + def serialize_bundler_dependency(dependency) + { + name: dependency.name, + requirement: dependency.requirement, + groups: dependency.groups, + source: source_for(dependency), + type: dependency.type + } + end + + # Can't be a constant because some of these don't exist in bundler + # 1.15, which used to cause issues on Heroku (causing exception on boot). + # TODO: Check if this will be an issue with multiple bundler versions + def sources + [ + NilClass, + Bundler::Source::Rubygems, + Bundler::Source::Git, + Bundler::Source::Path, + Bundler::Source::Gemspec, + Bundler::Source::Metadata + ] + end + end +end diff --git a/bundler/helpers/v2/lib/functions/force_updater.rb b/bundler/helpers/v2/lib/functions/force_updater.rb new file mode 100644 index 00000000000..49d88b2e30b --- /dev/null +++ b/bundler/helpers/v2/lib/functions/force_updater.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true + +module Functions + class ForceUpdater + class TransitiveDependencyError < StandardError; end + + def initialize(dependency_name:, target_version:, gemfile_name:, + lockfile_name:, update_multiple_dependencies:) + @dependency_name = dependency_name + @target_version = target_version + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + @update_multiple_dependencies = update_multiple_dependencies + end + + def run + # Only allow upgrades. Otherwise it's unlikely that this + # resolution will be found by the FileUpdater + Bundler.settings.set_command_option( + "only_update_to_newer_versions", + true + ) + + dependencies_to_unlock = [] + + begin + definition = build_definition(dependencies_to_unlock: dependencies_to_unlock) + definition.resolve_remotely! + specs = definition.resolve + updates = [{ name: dependency_name }] + + dependencies_to_unlock.map { |dep| { name: dep.name } } + specs = specs.map do |dep| + { + name: dep.name, + version: dep.version + } + end + [updates, specs] + rescue Bundler::VersionConflict => e + raise unless update_multiple_dependencies? + + # TODO: Not sure this won't unlock way too many things... + new_dependencies_to_unlock = + new_dependencies_to_unlock_from( + error: e, + already_unlocked: dependencies_to_unlock + ) + + raise if new_dependencies_to_unlock.none? + + dependencies_to_unlock += new_dependencies_to_unlock + retry + end + end + + private + + attr_reader :dependency_name, :target_version, :gemfile_name, + :lockfile_name, :credentials, + :update_multiple_dependencies + alias update_multiple_dependencies? update_multiple_dependencies + + def new_dependencies_to_unlock_from(error:, already_unlocked:) + potentials_deps = + relevant_conflicts(error, already_unlocked). + flat_map(&:requirement_trees). + reject do |tree| + # If the final requirement wasn't specific, it can't be binding + next true if tree.last.requirement == Gem::Requirement.new(">= 0") + + # If the conflict wasn't for the dependency we're updating then + # we don't have enough info to reject it + next false unless tree.last.name == dependency_name + + # If the final requirement *was* for the dependency we're updating + # then we can ignore the tree if it permits the target version + tree.last.requirement.satisfied_by?( + Gem::Version.new(target_version) + ) + end.map(&:first) + + potentials_deps. + reject { |dep| already_unlocked.map(&:name).include?(dep.name) }. + reject { |dep| [dependency_name, "ruby\0"].include?(dep.name) }. + uniq + end + + def relevant_conflicts(error, dependencies_being_unlocked) + names = [*dependencies_being_unlocked.map(&:name), dependency_name] + + # For a conflict to be relevant to the updates we're making it must be + # 1) caused by a new requirement introduced by our unlocking, or + # 2) caused by an old requirement that prohibits the update. + # Hence, we look at the beginning and end of the requirement trees + error.cause.conflicts.values. + select do |conflict| + conflict.requirement_trees.any? do |t| + names.include?(t.last.name) || names.include?(t.first.name) + end + end + end + + def build_definition(dependencies_to_unlock:) + gems_to_unlock = dependencies_to_unlock.map(&:name) + [dependency_name] + definition = Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: gems_to_unlock + subdependencies, + conservative: true + ) + + # Remove the Gemfile / gemspec requirements on the gems we're + # unlocking (i.e., completely unlock them) + gems_to_unlock.each do |gem_name| + unlock_gem(definition: definition, gem_name: gem_name) + end + + dep = definition.dependencies. + find { |d| d.name == dependency_name } + + # If the dependency is not found in the Gemfile it means this is a + # transitive dependency that we can't force update. + raise TransitiveDependencyError unless dep + + # Set the requirement for the gem we're forcing an update of + new_req = Gem::Requirement.create("= #{target_version}") + dep.instance_variable_set(:@requirement, new_req) + dep.source = nil if dep.source.is_a?(Bundler::Source::Git) + + definition + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name && File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def subdependencies + # If there's no lockfile we don't need to worry about + # subdependencies + return [] unless lockfile + + all_deps = Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s) + top_level = Bundler::Definition. + build(gemfile_name, lockfile_name, {}). + dependencies.map(&:name).map(&:to_s) + + all_deps - top_level + end + + def unlock_gem(definition:, gem_name:) + dep = definition.dependencies.find { |d| d.name == gem_name } + version = definition.locked_gems.specs. + find { |d| d.name == gem_name }.version + + dep&.instance_variable_set( + :@requirement, + Gem::Requirement.create(">= #{version}") + ) + end + end +end diff --git a/bundler/helpers/v2/lib/functions/lockfile_updater.rb b/bundler/helpers/v2/lib/functions/lockfile_updater.rb new file mode 100644 index 00000000000..43ef79bf0a7 --- /dev/null +++ b/bundler/helpers/v2/lib/functions/lockfile_updater.rb @@ -0,0 +1,227 @@ +# frozen_string_literal: true + +require "fileutils" + +module Functions + class LockfileUpdater + RETRYABLE_ERRORS = [Bundler::HTTPError].freeze + GEM_NOT_FOUND_ERROR_REGEX = + / + locked\sto\s(?[^\s]+)\s\(| + not\sfind\s(?[^\s]+)-\d| + has\s(?[^\s]+)\slocked\sat + /x + DEPENDENCY_DROPPED = "_dependency_dropped_" + + def initialize(gemfile_name:, lockfile_name:, dependencies:) + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + @dependencies = dependencies + end + + def run + generate_lockfile + end + + private + + attr_reader :gemfile_name, :lockfile_name, :dependencies + + def generate_lockfile # rubocop:disable Metrics/PerceivedComplexity + dependencies_to_unlock = dependencies.map { |d| d.fetch("name") } + + begin + definition = build_definition(dependencies_to_unlock) + + old_reqs = lock_deps_being_updated_to_exact_versions(definition) + + definition.resolve_remotely! + + old_reqs.each do |dep_name, old_req| + d_dep = definition.dependencies.find { |d| d.name == dep_name } + if old_req.to_s == DEPENDENCY_DROPPED then definition.dependencies.delete(d_dep) + else + d_dep.instance_variable_set(:@requirement, old_req) + end + end + + cache_vendored_gems(definition) if Bundler.app_cache.exist? + + definition.to_lock + rescue Bundler::GemNotFound => e + unlock_yanked_gem(dependencies_to_unlock, e) && retry + rescue Bundler::VersionConflict => e + unlock_blocking_subdeps(dependencies_to_unlock, e) && retry + rescue *RETRYABLE_ERRORS + raise if @retrying + + @retrying = true + sleep(rand(1.0..5.0)) + retry + end + end + + def cache_vendored_gems(definition) + # Dependencies that have been unlocked for the update (including + # sub-dependencies) + unlocked_gems = definition.instance_variable_get(:@unlock). + fetch(:gems).reject { |gem| __keep_on_prune?(gem) } + bundler_opts = { + cache_all: true, + cache_all_platforms: true, + no_prune: true + } + + Bundler.settings.temporary(**bundler_opts) do + # Fetch and cache gems on all platforms without pruning + Bundler::Runtime.new(nil, definition).cache + + # Only prune unlocked gems (the original implementation is in + # Bundler::Runtime) + cache_path = Bundler.app_cache + resolve = definition.resolve + prune_gem_cache(resolve, cache_path, unlocked_gems) + prune_git_and_path_cache(resolve, cache_path) + end + end + + # This is not officially supported and may be removed without notice. + def __keep_on_prune?(spec_name) + unless (specs = Bundler.settings[:persistent_gems_after_clean]) + return false + end + + specs.include?(spec_name) + end + + # Copied from Bundler::Runtime: Modified to only prune gems that have + # been unlocked + def prune_gem_cache(resolve, cache_path, unlocked_gems) + cached_gems = Dir["#{cache_path}/*.gem"] + + outdated_gems = cached_gems.reject do |path| + spec = Bundler.rubygems.spec_from_gem path + + !unlocked_gems.include?(spec.name) || resolve.any? do |s| + s.name == spec.name && s.version == spec.version && + !s.source.is_a?(Bundler::Source::Git) + end + end + + return unless outdated_gems.any? + + outdated_gems.each do |path| + File.delete(path) + end + end + + # Copied from Bundler::Runtime + def prune_git_and_path_cache(resolve, cache_path) + cached_git_and_path = Dir["#{cache_path}/*/.bundlecache"] + + outdated_git_and_path = cached_git_and_path.reject do |path| + name = File.basename(File.dirname(path)) + + resolve.any? do |s| + s.source.respond_to?(:app_cache_dirname) && + s.source.app_cache_dirname == name + end + end + + return unless outdated_git_and_path.any? + + outdated_git_and_path.each do |path| + path = File.dirname(path) + FileUtils.rm_rf(path) + end + end + + def unlock_yanked_gem(dependencies_to_unlock, error) + raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) + + gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). + named_captures["name"] + raise if dependencies_to_unlock.include?(gem_name) + + dependencies_to_unlock << gem_name + end + + # rubocop:disable Metrics/PerceivedComplexity + def unlock_blocking_subdeps(dependencies_to_unlock, error) + all_deps = Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s) + top_level = build_definition([]).dependencies. + map(&:name).map(&:to_s) + allowed_new_unlocks = all_deps - top_level - dependencies_to_unlock + + raise if allowed_new_unlocks.none? + + # Unlock any sub-dependencies that Bundler reports caused the + # conflict + potentials_deps = + error.cause.conflicts.values. + flat_map(&:requirement_trees). + filter_map do |tree| + tree.find { |req| allowed_new_unlocks.include?(req.name) } + end.map(&:name) + + # If there are specific dependencies we can unlock, unlock them + return dependencies_to_unlock.append(*potentials_deps) if potentials_deps.any? + + # Fall back to unlocking *all* sub-dependencies. This is required + # because Bundler's VersionConflict objects don't include enough + # information to chart the full path through all conflicts unwound + dependencies_to_unlock.append(*allowed_new_unlocks) + end + # rubocop:enable Metrics/PerceivedComplexity + + def build_definition(dependencies_to_unlock) + defn = Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: dependencies_to_unlock + ) + + # Bundler unlocks the sub-dependencies of gems it is passed even + # if those sub-deps are top-level dependencies. We only want true + # subdeps unlocked, like they were in the UpdateChecker, so we + # mutate the unlocked gems array. + unlocked = defn.instance_variable_get(:@unlock).fetch(:gems) + must_not_unlock = defn.dependencies.map(&:name).map(&:to_s) - + dependencies_to_unlock + unlocked.reject! { |n| must_not_unlock.include?(n) } + + defn + end + + def lock_deps_being_updated_to_exact_versions(definition) + dependencies.each_with_object({}) do |dep, old_reqs| + defn_dep = definition.dependencies.find do |d| + d.name == dep.fetch("name") + end + + if defn_dep.nil? + definition.dependencies << + Bundler::Dependency.new(dep.fetch("name"), dep.fetch("version")) + old_reqs[dep.fetch("name")] = DEPENDENCY_DROPPED + elsif git_dependency?(dep) && + defn_dep.source.is_a?(Bundler::Source::Git) + defn_dep.source.unlock! + elsif Gem::Version.correct?(dep.fetch("version")) + new_req = Gem::Requirement.create("= #{dep.fetch('version')}") + old_reqs[dep.fetch("name")] = defn_dep.requirement + defn_dep.instance_variable_set(:@requirement, new_req) + end + end + end + + def git_dependency?(dep) + sources = dep.fetch("requirements").map { |r| r.fetch("source") } + sources.all? { |s| s&.fetch("type", nil) == "git" } + end + + def lockfile + @lockfile ||= File.read(lockfile_name) + end + end +end diff --git a/bundler/helpers/v2/lib/functions/version_resolver.rb b/bundler/helpers/v2/lib/functions/version_resolver.rb new file mode 100644 index 00000000000..e41a8ed4d24 --- /dev/null +++ b/bundler/helpers/v2/lib/functions/version_resolver.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Functions + class VersionResolver + GEM_NOT_FOUND_ERROR_REGEX = /locked to (?[^\s]+) \(/ + + attr_reader :dependency_name, :dependency_requirements, + :gemfile_name, :lockfile_name + + def initialize(dependency_name:, dependency_requirements:, + gemfile_name:, lockfile_name:) + @dependency_name = dependency_name + @dependency_requirements = dependency_requirements + @gemfile_name = gemfile_name + @lockfile_name = lockfile_name + end + + def version_details + # If the dependency is Bundler itself then we can't trust the + # version that has been returned (it's the version Dependabot is + # running on, rather than the true latest resolvable version). + return nil if dependency_name == "bundler" + + dep = dependency_from_definition + + # If the dependency wasn't found in the definition, but *is* + # included in a gemspec, it's because the Gemfile didn't import + # the gemspec. This is unusual, but the correct behaviour if/when + # it happens is to behave as if the repo was gemspec-only. + return "latest" if dep.nil? && dependency_requirements.any? + + # Otherwise, if the dependency wasn't found it's because it is a + # subdependency that was removed when attempting to update it. + return nil if dep.nil? + + details = { + version: dep.version, + ruby_version: ruby_version, + fetcher: fetcher_class(dep) + } + details[:commit_sha] = dep.source.revision if dep.source.instance_of?(::Bundler::Source::Git) + details + end + + private + + # rubocop:disable Metrics/PerceivedComplexity + def dependency_from_definition(unlock_subdependencies: true) + dependencies_to_unlock = [dependency_name] + dependencies_to_unlock += subdependencies if unlock_subdependencies + begin + definition = build_definition(dependencies_to_unlock) + definition.resolve_remotely! + rescue ::Bundler::GemNotFound => e + unlock_yanked_gem(dependencies_to_unlock, e) && retry + rescue ::Bundler::HTTPError => e + # Retry network errors + # Note: in_a_native_bundler_context will also retry `Bundler::HTTPError` errors + # up to three times meaning we'll end up retrying this error up to six times + # TODO: Could we get rid of this retry logic and only rely on + # SharedBundlerHelpers.in_a_native_bundler_context + attempt ||= 1 + attempt += 1 + raise if attempt > 3 || !e.message.include?("Network error") + + retry + end + + dep = definition.resolve.find { |d| d.name == dependency_name } + return dep if dep + return if dependency_requirements.any? || !unlock_subdependencies + + # If no definition was found and we're updating a sub-dependency, + # try again but without unlocking any other sub-dependencies + dependency_from_definition(unlock_subdependencies: false) + end + # rubocop:enable Metrics/PerceivedComplexity + + def subdependencies + # If there's no lockfile we don't need to worry about + # subdependencies + return [] unless lockfile + + all_deps = ::Bundler::LockfileParser.new(lockfile). + specs.map(&:name).map(&:to_s).uniq + top_level = build_definition([]).dependencies. + map(&:name).map(&:to_s) + + all_deps - top_level + end + + def build_definition(dependencies_to_unlock) + # NOTE: we lock shared dependencies to avoid any top-level + # dependencies getting unlocked (which would happen if they were + # also subdependencies of the dependency being unlocked) + ::Bundler::Definition.build( + gemfile_name, + lockfile_name, + gems: dependencies_to_unlock, + conservative: true + ) + end + + def unlock_yanked_gem(dependencies_to_unlock, error) + raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) + + gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). + named_captures["name"] + raise if dependencies_to_unlock.include?(gem_name) + + dependencies_to_unlock << gem_name + end + + def lockfile + return @lockfile if defined?(@lockfile) + + @lockfile = + begin + return unless lockfile_name + return unless File.exist?(lockfile_name) + + File.read(lockfile_name) + end + end + + def fetcher_class(dep) + return unless dep.source.is_a?(::Bundler::Source::Rubygems) + + dep.source.fetchers.first.fetchers.first.class.to_s + end + + def ruby_version + return nil unless gemfile_name + + @ruby_version ||= build_definition([]).ruby_version&.gem_version + end + end +end diff --git a/bundler/helpers/v2/monkey_patches/definition_bundler_version_patch.rb b/bundler/helpers/v2/monkey_patches/definition_bundler_version_patch.rb new file mode 100644 index 00000000000..1ddd4780cef --- /dev/null +++ b/bundler/helpers/v2/monkey_patches/definition_bundler_version_patch.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "bundler/definition" + +# Ignore the Bundler version specified in the Gemfile (since the only Bundler +# version available to us is the one we're using). +module BundlerDefinitionBundlerVersionPatch + def expanded_dependencies + @expanded_dependencies ||= (dependencies + metadata_dependencies).reject { |d| d.name == "bundler" } + end +end + +Bundler::Definition.prepend(BundlerDefinitionBundlerVersionPatch) diff --git a/bundler/helpers/v2/monkey_patches/definition_ruby_version_patch.rb b/bundler/helpers/v2/monkey_patches/definition_ruby_version_patch.rb new file mode 100644 index 00000000000..14c7bdd6afe --- /dev/null +++ b/bundler/helpers/v2/monkey_patches/definition_ruby_version_patch.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "bundler/definition" + +module BundlerDefinitionRubyVersionPatch + def source_requirements + if ruby_version + requested_version = ruby_version.gem_version + sources.metadata_source.specs << + Gem::Specification.new("Ruby\0", requested_version) + end + + %w(2.5.3 2.6.10 2.7.6 3.0.4).each do |version| + sources.metadata_source.specs << Gem::Specification.new("Ruby\0", version) + end + + super + end + + def metadata_dependencies + @metadata_dependencies ||= + [ + Bundler::Dependency.new("Ruby\0", ruby_version_requirements), + Bundler::Dependency.new("RubyGems\0", Gem::VERSION) + ] + end + + def ruby_version_requirements + return [] unless ruby_version + + ruby_version.versions.map do |version| + Gem::Requirement.new(version) + end + end +end + +Bundler::Definition.prepend(BundlerDefinitionRubyVersionPatch) diff --git a/bundler/helpers/v2/monkey_patches/git_source_patch.rb b/bundler/helpers/v2/monkey_patches/git_source_patch.rb new file mode 100644 index 00000000000..1b8c5df7179 --- /dev/null +++ b/bundler/helpers/v2/monkey_patches/git_source_patch.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "bundler/source" + +module Bundler + class Source + class Git + class GitProxy + private + + # Bundler allows ssh authentication when talking to GitHub but there's + # no way for Dependabot to do so (it doesn't have any ssh keys). + # Instead, we convert all `git@github.com:` URLs to use HTTPS. + def configured_uri_for(uri) + uri = uri.gsub(%r{git@(.*?):/?}, 'https://\1/') + if /https?:/.match?(uri) + remote = Bundler::URI(uri) + config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host] + remote.userinfo ||= config_auth + remote.to_s + else + uri + end + end + end + end + end +end + +module Bundler + class Source + class Git < Path + private + + def serialize_gemspecs_in(destination) + original_load_paths = $LOAD_PATH.dup + reduced_load_paths = original_load_paths. + reject { |p| p.include?("/gems/") } + + $LOAD_PATH.shift until $LOAD_PATH.empty? + reduced_load_paths.each { |p| $LOAD_PATH << p } + + destination = destination.expand_path(Bundler.root) if destination.relative? + Dir["#{destination}/#{@glob}"].each do |spec_path| + # Evaluate gemspecs and cache the result. Gemspecs + # in git might require git or other dependencies. + # The gemspecs we cache should already be evaluated. + spec = Bundler.load_gemspec(spec_path) + next unless spec + + Bundler.rubygems.set_installed_by_version(spec) + Bundler.rubygems.validate(spec) + File.binwrite(spec_path, spec.to_ruby) + end + $LOAD_PATH.shift until $LOAD_PATH.empty? + original_load_paths.each { |p| $LOAD_PATH << p } + end + end + end +end diff --git a/bundler/helpers/v2/run.rb b/bundler/helpers/v2/run.rb new file mode 100644 index 00000000000..1e33c3a695f --- /dev/null +++ b/bundler/helpers/v2/run.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +gem "bundler", "~> 2.3" +require "bundler/setup" +require "json" + +$LOAD_PATH.unshift(File.expand_path("./lib", __dir__)) +$LOAD_PATH.unshift(File.expand_path("./monkey_patches", __dir__)) + +trap "HUP" do + puts JSON.generate(error: "timeout", error_class: "Timeout::Error", trace: []) + exit 2 +end + +# Bundler monkey patches +require "definition_ruby_version_patch" +require "definition_bundler_version_patch" +require "git_source_patch" + +require "functions" + +MIN_BUNDLER_VERSION = "2.1.0" + +def validate_bundler_version! + return true if correct_bundler_version? + + raise StandardError, "Called with Bundler '#{Bundler::VERSION}', expected >= '#{MIN_BUNDLER_VERSION}'" +end + +def correct_bundler_version? + Gem::Version.new(Bundler::VERSION) >= Gem::Version.new(MIN_BUNDLER_VERSION) +end + +def output(obj) + print JSON.dump(obj) +end + +begin + validate_bundler_version! + + request = JSON.parse($stdin.read) + + function = request["function"] + args = request["args"].transform_keys(&:to_sym) + + output({ result: Functions.send(function, **args) }) +rescue StandardError => e + output( + { error: e.message, error_class: e.class, trace: e.backtrace } + ) + exit(1) +end diff --git a/bundler/helpers/v2/spec/functions/conflicting_dependency_resolver_spec.rb b/bundler/helpers/v2/spec/functions/conflicting_dependency_resolver_spec.rb new file mode 100644 index 00000000000..3fa9794e905 --- /dev/null +++ b/bundler/helpers/v2/spec/functions/conflicting_dependency_resolver_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::ConflictingDependencyResolver do + include_context "in a temporary bundler directory" + + let(:conflicting_dependency_resolver) do + described_class.new( + dependency_name: dependency_name, + target_version: target_version, + lockfile_name: "Gemfile.lock" + ) + end + + let(:dependency_name) { "dummy-pkg-a" } + let(:target_version) { "2.0.0" } + + let(:project_name) { "blocked_by_subdep" } + + describe "#conflicting_dependencies" do + subject(:conflicting_dependencies) do + in_tmp_folder { conflicting_dependency_resolver.conflicting_dependencies } + end + + it "returns a list of dependencies that block the update" do + expect(conflicting_dependencies).to eq( + [{ + "explanation" => "dummy-pkg-b (1.0.0) requires dummy-pkg-a (< 2.0.0)", + "name" => "dummy-pkg-b", + "version" => "1.0.0", + "requirement" => "< 2.0.0" + }] + ) + end + + context "for nested transitive dependencies" do + let(:project_name) { "transitive_blocking" } + let(:dependency_name) { "activesupport" } + let(:target_version) { "6.0.0" } + + it "returns a list of dependencies that block the update" do + expect(conflicting_dependencies).to match_array( + [ + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0)", + "name" => "rails", + "requirement" => "= 5.2.0", + "version" => "5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via actionpack (5.2.0)", + "name" => "actionpack", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via actionview (5.2.0)", + "name" => "actionview", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activejob (5.2.0)", + "name" => "activejob", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activemodel (5.2.0)", + "name" => "activemodel", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via activerecord (5.2.0)", + "name" => "activerecord", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + }, + { + "explanation" => "rails (5.2.0) requires activesupport (= 5.2.0) via railties (5.2.0)", + "name" => "railties", + "version" => "5.2.0", + "requirement" => "= 5.2.0" + } + ] + ) + end + end + + context "with multiple blocking dependencies" do + let(:dependency_name) { "activesupport" } + let(:current_version) { "5.0.0" } + let(:target_version) { "6.0.0" } + let(:project_name) { "multiple_blocking" } + + it "returns all of the blocking dependencies" do + expect(conflicting_dependencies).to match_array( + [ + { + "explanation" => "actionmailer (5.0.0) requires activesupport (= 5.0.0) via actionpack (5.0.0)", + "name" => "actionpack", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + }, + { + "explanation" => "actionview (5.0.0) requires activesupport (= 5.0.0)", + "name" => "actionview", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + }, + { + "explanation" => "actionmailer (5.0.0) requires activesupport (= 5.0.0) via activejob (5.0.0)", + "name" => "activejob", + "version" => "5.0.0", + "requirement" => "= 5.0.0" + } + ] + ) + end + end + + context "without any blocking dependencies" do + let(:target_version) { "1.0.0" } + + it "returns an empty list" do + expect(conflicting_dependencies).to eq([]) + end + end + end +end diff --git a/bundler/helpers/v2/spec/functions/dependency_source_spec.rb b/bundler/helpers/v2/spec/functions/dependency_source_spec.rb new file mode 100644 index 00000000000..95e4b1d52cd --- /dev/null +++ b/bundler/helpers/v2/spec/functions/dependency_source_spec.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::DependencySource do + include_context "in a temporary bundler directory" + + let(:dependency_source) do + described_class.new( + gemfile_name: "Gemfile", + dependency_name: dependency_name + ) + end + + let(:dependency_name) { "business" } + + let(:project_name) { "specified_source_no_lockfile" } + let(:registry_url) { "https://repo.fury.io/greysteil/" } + let(:gemfury_business_url) do + "https://repo.fury.io/greysteil/api/v1/dependencies?gems=business" + end + + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 404) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 200) + stub_request(:get, gemfury_business_url). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + end + + describe "#private_registry_versions" do + subject(:private_registry_versions) do + in_tmp_folder { dependency_source.private_registry_versions } + end + + it "returns all versions from the private source" do + is_expected.to eq([ + Gem::Version.new("1.5.0"), + Gem::Version.new("1.9.0"), + Gem::Version.new("1.10.0.beta") + ]) + end + + context "specified as the default source" do + let(:project_name) { "specified_default_source_no_lockfile" } + + it "returns all versions from the private source" do + is_expected.to eq([ + Gem::Version.new("1.5.0"), + Gem::Version.new("1.9.0"), + Gem::Version.new("1.10.0.beta") + ]) + end + end + + context "that we don't have authentication details for" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 401) + end + + it "blows up with a useful error" do + error_class = Bundler::Fetcher::BadAuthenticationError + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(error_class) + expect(error.message).to include("Bad username or password for") + end + end + end + + context "that we have bad authentication details for" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 403) + end + + it "blows up with a useful error" do + error_class = Bundler::Fetcher::BadAuthenticationError + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(error_class) + expect(error.message).to include("Bad username or password for") + end + end + end + + context "that bad-requested, but was a private repo" do + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + stub_request(:get, registry_url + "info/business"). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 400) + end + + it "blows up with a useful error" do + expect { private_registry_versions }. + to raise_error do |error| + expect(error).to be_a(Bundler::HTTPError) + expect(error.message). + to include("Could not fetch specs from") + end + end + end + + context "that doesn't have details of the gem" do + before do + stub_request(:get, gemfury_business_url). + with(basic_auth: ["SECRET_CODES", ""]). + to_return(status: 404) + + # Stub indexes to return details of other gems (but not this one) + stub_request(:get, registry_url + "specs.4.8.gz"). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_response") + ) + stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_prerelease_response") + ) + end + + it { is_expected.to be_empty } + end + + context "that only implements the old Bundler index format..." do + let(:project_name) { "sidekiq_pro" } + let(:dependency_name) { "sidekiq-pro" } + let(:registry_url) { "https://gems.contribsys.com/" } + + before do + stub_request(:get, registry_url + "versions"). + with(basic_auth: %w(username password)). + to_return(status: 404) + stub_request(:get, registry_url + "api/v1/dependencies"). + with(basic_auth: %w(username password)). + to_return(status: 404) + stub_request(:get, registry_url + "specs.4.8.gz"). + with(basic_auth: %w(username password)). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_response") + ) + stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). + with(basic_auth: %w(username password)). + to_return( + status: 200, + body: fixture("ruby", "contribsys_old_index_prerelease_response") + ) + end + + it "returns all versions from the private source" do + expect(private_registry_versions.length).to eql(70) + expect(private_registry_versions.min).to eql(Gem::Version.new("1.0.0")) + expect(private_registry_versions.max).to eql(Gem::Version.new("3.5.2")) + end + end + end +end diff --git a/bundler/helpers/v2/spec/functions/file_parser_spec.rb b/bundler/helpers/v2/spec/functions/file_parser_spec.rb new file mode 100644 index 00000000000..0e5e880d859 --- /dev/null +++ b/bundler/helpers/v2/spec/functions/file_parser_spec.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::FileParser do + include_context "in a temporary bundler directory" + + let(:dependency_source) do + described_class.new( + lockfile_name: "Gemfile.lock" + ) + end + + describe "#parsed_gemfile" do + let(:project_name) { "gemfile" } + + subject(:parsed_gemfile) do + in_tmp_folder do + dependency_source.parsed_gemfile(gemfile_name: "Gemfile") + end + end + + it "parses gemfile" do + parsed_gemfile = [ + { + groups: [:default], + name: "business", + requirement: Gem::Requirement.new("~> 1.4.0"), + source: nil, + type: :runtime + }, + { + groups: [:default], + name: "statesman", + requirement: Gem::Requirement.new("~> 1.2.0"), + source: nil, + type: :runtime + } + ] + is_expected.to eq(parsed_gemfile) + end + + context "with a git source" do + let(:project_name) { "git_source" } + + it "parses gemfile" do + parsed_gemfile = [ + { + groups: [:default], + name: "business", + requirement: Gem::Requirement.new("~> 1.6.0"), + source: { + branch: nil, + ref: "a1b78a9", + type: "git", + url: "git@github.com:dependabot-fixtures/business" + }, + type: :runtime + }, + { + groups: [:default], + name: "statesman", + requirement: Gem::Requirement.new("~> 1.2.0"), + source: nil, + type: :runtime + }, + { + groups: [:default], + name: "prius", + requirement: Gem::Requirement.new(">= 0"), + source: { + branch: nil, + ref: nil, + type: "git", + url: "https://github.com/dependabot-fixtures/prius" + }, + type: :runtime + }, + { + groups: [:default], + name: "que", + requirement: Gem::Requirement.new(">= 0"), + source: { + branch: nil, + ref: "v0.11.6", + type: "git", + url: "git@github.com:dependabot-fixtures/que" + }, + type: :runtime + }, + { + groups: [:default], + name: "uk_phone_numbers", + requirement: Gem::Requirement.new(">= 0"), + source: { + branch: nil, + ref: nil, + type: "git", + url: "http://github.com/dependabot-fixtures/uk_phone_numbers" + }, + type: :runtime + } + ] + is_expected.to eq(parsed_gemfile) + end + end + end + + describe "#parsed_gemspec" do + let(:project_name) { "gemfile_exact" } + + subject(:parsed_gemspec) do + in_tmp_folder do |_tmp_path| + dependency_source.parsed_gemspec(gemspec_name: "example.gemspec") + end + end + + it "parses gemspec" do + parsed_gemspec = [ + { + groups: nil, + name: "business", + requirement: Gem::Requirement.new("= 1.0.0"), + source: nil, + type: :runtime + }, + { + groups: nil, + name: "statesman", + requirement: Gem::Requirement.new("= 1.0.0"), + source: nil, + type: :runtime + } + ] + is_expected.to eq(parsed_gemspec) + end + end +end diff --git a/bundler/helpers/v2/spec/functions/force_updater_spec.rb b/bundler/helpers/v2/spec/functions/force_updater_spec.rb new file mode 100644 index 00000000000..2e78980ba65 --- /dev/null +++ b/bundler/helpers/v2/spec/functions/force_updater_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::ForceUpdater do + include_context "in a temporary bundler directory" + include_context "stub rubygems compact index" + + let(:force_updater) do + described_class.new( + dependency_name: dependency_name, + target_version: target_version, + gemfile_name: gemfile_name, + lockfile_name: lockfile_name, + update_multiple_dependencies: update_multiple_dependencies + ) + end + let(:gemfile_name) { "Gemfile" } + let(:lockfile_name) { "Gemfile.lock" } + let(:update_multiple_dependencies) { true } + + describe "#run" do + subject(:force_update) do + in_tmp_folder { force_updater.run } + end + + context "with a version conflict" do + let(:target_version) { "3.6.0" } + let(:dependency_name) { "rspec-support" } + let(:project_name) { "version_conflict" } + + it "updates the conflicting dependencies" do + updated_deps, _specs = force_update + expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }]) + end + + context "when updating a single dependency" do + let(:update_multiple_dependencies) { false } + + it { expect { force_update }.to raise_error(Bundler::VersionConflict) } + end + end + + context "with a version conflict in gems rb" do + let(:target_version) { "3.6.0" } + let(:dependency_name) { "rspec-support" } + let(:project_name) { "version_conflict_gems_rb" } + let(:gemfile_name) { "gems.rb" } + let(:lockfile_name) { "gems.locked" } + + it "updates the conflicting dependencies" do + updated_deps, _specs = force_update + expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }]) + end + end + end +end diff --git a/bundler/helpers/v2/spec/functions/version_resolver_spec.rb b/bundler/helpers/v2/spec/functions/version_resolver_spec.rb new file mode 100644 index 00000000000..460401bb04f --- /dev/null +++ b/bundler/helpers/v2/spec/functions/version_resolver_spec.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions::VersionResolver do + include_context "in a temporary bundler directory" + include_context "stub rubygems compact index" + + let(:version_resolver) do + described_class.new( + dependency_name: dependency_name, + dependency_requirements: dependency_requirements, + gemfile_name: "Gemfile", + lockfile_name: "Gemfile.lock" + ) + end + + let(:dependency_name) { "business" } + let(:dependency_requirements) do + [{ + file: "Gemfile", + requirement: requirement_string, + groups: [], + source: source + }] + end + let(:source) { nil } + + let(:rubygems_url) { "https://index.rubygems.org/api/v1/" } + let(:old_index_url) { rubygems_url + "dependencies" } + let(:gemfury_url) { "https://repo.fury.io/greysteil/" } + + before do + stub_request(:get, "https://rubygems.org/quick/Marshal.4.8/statesman-1.2.1.gemspec.rz"). + to_return(status: 200, body: fixture("rubygems_responses", "statesman-1.2.1.gemspec.rz")) + + stub_request(:get, %r{quick/Marshal.4.8/business-.*.gemspec.rz}). + to_return(status: 200, body: fixture("rubygems_responses", "business-1.0.0.gemspec.rz")) + end + + describe "#version_details" do + subject do + in_tmp_folder { version_resolver.version_details } + end + + let(:project_name) { "gemfile" } + let(:requirement_string) { " >= 0" } + + its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::CompactIndex") } + + context "with a private gemserver source" do + include_context "stub rubygems compact index" + + let(:project_name) { "specified_source" } + let(:requirement_string) { ">= 0" } + + before do + gemfury_deps_url = gemfury_url + "api/v1/dependencies" + + stub_request(:get, gemfury_url + "versions"). + to_return(status: 200, body: fixture("ruby", "gemfury-index")) + stub_request(:get, gemfury_url + "info/business").to_return(status: 404) + stub_request(:get, gemfury_deps_url).to_return(status: 200) + stub_request(:get, gemfury_deps_url + "?gems=business,statesman"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + stub_request(:get, gemfury_deps_url + "?gems=business"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + stub_request(:get, gemfury_deps_url + "?gems=statesman"). + to_return(status: 200, body: fixture("ruby", "gemfury_response")) + end + + its([:version]) { is_expected.to eq(Gem::Version.new("1.9.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") } + end + + context "with a git source" do + let(:project_name) { "git_source" } + + its([:version]) { is_expected.to eq(Gem::Version.new("1.6.0")) } + its([:fetcher]) { is_expected.to be_nil } + end + + context "when Bundler's compact index is down" do + before do + stub_request(:get, "https://index.rubygems.org/versions"). + to_return(status: 500, body: "We'll be back soon") + stub_request(:get, "https://index.rubygems.org/info/public_suffix"). + to_return(status: 500, body: "We'll be back soon") + stub_request(:get, old_index_url).to_return(status: 200) + stub_request(:get, old_index_url + "?gems=business,statesman"). + to_return( + status: 200, + body: fixture("rubygems_responses", + "dependencies-default-gemfile") + ) + end + + its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } + its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") } + end + + context "with no update possible due to a version conflict" do + let(:project_name) { "version_conflict_with_listed_subdep" } + let(:dependency_name) { "rspec-mocks" } + let(:requirement_string) { ">= 0" } + + its([:version]) { is_expected.to eq(Gem::Version.new("3.6.0")) } + end + end +end diff --git a/bundler/helpers/v2/spec/functions_spec.rb b/bundler/helpers/v2/spec/functions_spec.rb new file mode 100644 index 00000000000..0b01398b8ef --- /dev/null +++ b/bundler/helpers/v2/spec/functions_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require "native_spec_helper" +require "shared_contexts" + +RSpec.describe Functions do + include_context "in a temporary bundler directory" + + describe "#jfrog_source" do + let(:project_name) { "jfrog_source" } + + it "returns the jfrog source" do + in_tmp_folder do + jfrog_source = Functions.jfrog_source( + dir: tmp_path, + gemfile_name: "Gemfile", + credentials: {} + ) + + expect(jfrog_source).to eq("test.jfrog.io") + end + end + end + + describe "#git_specs" do + let(:project_name) { "git_source" } + subject(:git_specs) do + in_tmp_folder do + Functions.git_specs( + dir: tmp_path, + gemfile_name: "Gemfile", + credentials: {} + ) + end + end + + def expect_specs(count) + expect(git_specs.size).to eq(count) + git_specs.each do |gs| + uri = URI.parse(gs[:auth_uri]) + expect(uri.scheme).to(satisfy { |s| s.match?(/https?/o) }) + end + end + + it "returns git specs" do + expect_specs(4) + end + + context "with github shorthand" do + let(:project_name) { "github_source" } + + it "returns git specs" do + expect_specs(1) + end + end + end +end diff --git a/bundler/helpers/v2/spec/native_spec_helper.rb b/bundler/helpers/v2/spec/native_spec_helper.rb new file mode 100644 index 00000000000..a5304dba944 --- /dev/null +++ b/bundler/helpers/v2/spec/native_spec_helper.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "rspec/its" +require "webmock/rspec" +require "debug" + +$LOAD_PATH.unshift(File.expand_path("../lib", __dir__)) +$LOAD_PATH.unshift(File.expand_path("../monkey_patches", __dir__)) + +# Bundler monkey patches +require "definition_ruby_version_patch" +require "definition_bundler_version_patch" +require "git_source_patch" + +require "functions" + +RSpec.configure do |config| + config.color = true + config.order = :rand + config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true } + config.raise_errors_for_deprecations! +end + +def project_dependency_files(project) + project_path = File.expand_path(File.join("../../spec/fixtures/projects/bundler2", project)) + + raise "Fixture does not exist for project: '#{project}'" unless Dir.exist?(project_path) + + Dir.chdir(project_path) do + # NOTE: Include dotfiles (e.g. .npmrc) + files = Dir.glob("**/*", File::FNM_DOTMATCH) + files = files.select { |f| File.file?(f) } + files.map do |filename| + content = File.read(filename) + { + name: filename, + content: content + } + end + end +end + +def fixture(*name) + File.read(File.join("../../spec/fixtures", File.join(*name))) +end diff --git a/bundler/helpers/v2/spec/shared_contexts.rb b/bundler/helpers/v2/spec/shared_contexts.rb new file mode 100644 index 00000000000..b1e5cfcf15b --- /dev/null +++ b/bundler/helpers/v2/spec/shared_contexts.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "tmpdir" +require "bundler/compact_index_client" +require "bundler/compact_index_client/updater" + +TMP_DIR_PATH = File.expand_path("../tmp", __dir__) + +RSpec.shared_context "in a temporary bundler directory" do + let(:project_name) { "gemfile" } + + let(:tmp_path) do + FileUtils.mkdir_p(TMP_DIR_PATH) + dir = Dir.mktmpdir("native_helper_spec_", TMP_DIR_PATH) + Pathname.new(dir).expand_path + end + + before do + project_dependency_files(project_name).each do |file| + File.write(File.join(tmp_path, file[:name]), file[:content]) + end + end + + def in_tmp_folder(&block) + Dir.chdir(tmp_path, &block) + end +end + +RSpec.shared_context "without caching rubygems" do + before do + # Stub Bundler to stop it using a cached versions of Rubygems + allow_any_instance_of(Bundler::CompactIndexClient::Updater). + to receive(:etag_for).and_return("") + end +end + +RSpec.shared_context "stub rubygems compact index" do + include_context "without caching rubygems" + + before do + # Stub the Rubygems index + stub_request(:get, "https://index.rubygems.org/versions"). + to_return( + status: 200, + body: fixture("rubygems_responses", "index") + ) + + # Stub the Rubygems response for each dependency we have a fixture for + fixtures = + Dir[File.join("../../spec", "fixtures", "rubygems_responses", "info-*")] + fixtures.each do |path| + dep_name = path.split("/").last.gsub("info-", "") + stub_request(:get, "https://index.rubygems.org/info/#{dep_name}"). + to_return( + status: 200, + body: fixture("rubygems_responses", "info-#{dep_name}") + ) + end + end +end diff --git a/bundler/lib/dependabot/bundler/file_fetcher.rb b/bundler/lib/dependabot/bundler/file_fetcher.rb index fa4c542d92e..bf6b43efb90 100644 --- a/bundler/lib/dependabot/bundler/file_fetcher.rb +++ b/bundler/lib/dependabot/bundler/file_fetcher.rb @@ -14,9 +14,7 @@ class FileFetcher < Dependabot::FileFetchers::Base require "dependabot/bundler/file_fetcher/require_relative_finder" def self.required_files_in?(filenames) - if filenames.any? { |name| name.match?(%r{^[^/]*\.gemspec$}) } - return true - end + return true if filenames.any? { |name| name.match?(%r{^[^/]*\.gemspec$}) } filenames.include?("Gemfile") || filenames.include?("gems.rb") end @@ -133,9 +131,7 @@ def path_gemspecs unfetchable_gems << path.basename.to_s end - if unfetchable_gems.any? - raise Dependabot::PathDependenciesNotReachable, unfetchable_gems - end + raise Dependabot::PathDependenciesNotReachable, unfetchable_gems if unfetchable_gems.any? gemspec_files.tap { |ar| ar.each { |f| f.support_file = true } } end @@ -192,6 +188,7 @@ def child_gemfiles fetch_child_gemfiles(file: gemfile, previously_fetched_files: []) end + # TODO: Stop sanitizing the lockfile once we have bundler 2 installed def sanitized_lockfile_content regex = FileUpdater::LockfileUpdater::LOCKFILE_ENDING lockfile.content.gsub(regex, "") diff --git a/bundler/lib/dependabot/bundler/file_fetcher/child_gemfile_finder.rb b/bundler/lib/dependabot/bundler/file_fetcher/child_gemfile_finder.rb index 44340d39f12..e7956569536 100644 --- a/bundler/lib/dependabot/bundler/file_fetcher/child_gemfile_finder.rb +++ b/bundler/lib/dependabot/bundler/file_fetcher/child_gemfile_finder.rb @@ -33,8 +33,8 @@ def find_child_gemfile_paths(node) path_node = node.children[2] unless path_node.type == :str path = gemfile.path - msg = "Dependabot only supports uninterpolated string arguments "\ - "to eval_gemfile. Got "\ + msg = "Dependabot only supports uninterpolated string arguments " \ + "to eval_gemfile. Got " \ "`#{path_node.loc.expression.source}`" raise Dependabot::DependencyFileNotParseable.new(path, msg) end diff --git a/bundler/lib/dependabot/bundler/file_fetcher/gemspec_finder.rb b/bundler/lib/dependabot/bundler/file_fetcher/gemspec_finder.rb index ae68bb9af12..85320b23b4e 100644 --- a/bundler/lib/dependabot/bundler/file_fetcher/gemspec_finder.rb +++ b/bundler/lib/dependabot/bundler/file_fetcher/gemspec_finder.rb @@ -35,8 +35,8 @@ def find_gemspec_paths(node) unless path_node.type == :str path = gemfile.path - msg = "Dependabot only supports uninterpolated string arguments "\ - "to gemspec. Got "\ + msg = "Dependabot only supports uninterpolated string arguments " \ + "to gemspec. Got " \ "`#{path_node.loc.expression.source}`" raise Dependabot::DependencyFileNotParseable.new(path, msg) end diff --git a/bundler/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb b/bundler/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb index e295a5854c8..494c75e14b9 100644 --- a/bundler/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb +++ b/bundler/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb @@ -34,8 +34,8 @@ def find_path_gemspec_paths(node) unless path_node.type == :str path = gemfile.path - msg = "Dependabot only supports uninterpolated string arguments "\ - "for path dependencies. Got "\ + msg = "Dependabot only supports uninterpolated string arguments " \ + "for path dependencies. Got " \ "`#{path_node.loc.expression.source}`" raise Dependabot::DependencyFileNotParseable.new(path, msg) end diff --git a/bundler/lib/dependabot/bundler/file_parser.rb b/bundler/lib/dependabot/bundler/file_parser.rb index cbdcc43d9ae..407879f941c 100644 --- a/bundler/lib/dependabot/bundler/file_parser.rb +++ b/bundler/lib/dependabot/bundler/file_parser.rb @@ -4,6 +4,8 @@ require "dependabot/file_parsers" require "dependabot/file_parsers/base" require "dependabot/bundler/file_updater/lockfile_updater" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" require "dependabot/bundler/version" require "dependabot/shared_helpers" require "dependabot/errors" @@ -14,28 +16,43 @@ class FileParser < Dependabot::FileParsers::Base require "dependabot/file_parsers/base/dependency_set" require "dependabot/bundler/file_parser/file_preparer" require "dependabot/bundler/file_parser/gemfile_declaration_finder" + require "dependabot/bundler/file_parser/gemspec_declaration_finder" def parse dependency_set = DependencySet.new dependency_set += gemfile_dependencies dependency_set += gemspec_dependencies dependency_set += lockfile_dependencies + check_external_code(dependency_set.dependencies) + instrument_package_manager_version dependency_set.dependencies end private - # Can't be a constant because some of these don't exist in bundler - # 1.15, which Heroku uses, which causes an exception on boot. - def sources - [ - NilClass, - ::Bundler::Source::Rubygems, - ::Bundler::Source::Git, - ::Bundler::Source::Path, - ::Bundler::Source::Gemspec, - ::Bundler::Source::Metadata - ] + def check_external_code(dependencies) + return unless @reject_external_code + return unless git_source?(dependencies) + + # A git source dependency might contain a .gemspec that is evaluated + raise ::Dependabot::UnexpectedExternalCode + end + + def git_source?(dependencies) + dependencies.any? do |dep| + dep.requirements.any? { |req| req.fetch(:source)&.fetch(:type) == "git" } + end + end + + def instrument_package_manager_version + version = Helpers.detected_bundler_version(lockfile) + Dependabot.instrument( + Notifications::FILE_PARSER_PACKAGE_MANAGER_VERSION_PARSED, + ecosystem: "bundler", + package_managers: { + "bundler" => version + } + ) end def gemfile_dependencies @@ -44,19 +61,19 @@ def gemfile_dependencies return dependencies unless gemfile [gemfile, *evaled_gemfiles].each do |file| + gemfile_declaration_finder = GemfileDeclarationFinder.new(gemfile: file) + parsed_gemfile.each do |dep| - gemfile_declaration_finder = - GemfileDeclarationFinder.new(dependency: dep, gemfile: file) - next unless gemfile_declaration_finder.gemfile_includes_dependency? + next unless gemfile_declaration_finder.gemfile_includes_dependency?(dep) dependencies << Dependency.new( - name: dep.name, - version: dependency_version(dep.name)&.to_s, + name: dep.fetch("name"), + version: dependency_version(dep.fetch("name"))&.to_s, requirements: [{ - requirement: gemfile_declaration_finder.enhanced_req_string, - groups: dep.groups, - source: source_for(dep), + requirement: gemfile_declaration_finder.enhanced_req_string(dep), + groups: dep.fetch("groups").map(&:to_sym), + source: dep.fetch("source")&.transform_keys(&:to_sym), file: file.name }], package_manager: "bundler" @@ -71,15 +88,23 @@ def gemspec_dependencies dependencies = DependencySet.new gemspecs.each do |gemspec| - parsed_gemspec(gemspec).dependencies.each do |dependency| + gemspec_declaration_finder = GemspecDeclarationFinder.new(gemspec: gemspec) + + parsed_gemspec(gemspec).each do |dependency| + next unless gemspec_declaration_finder.gemspec_includes_dependency?(dependency) + dependencies << Dependency.new( - name: dependency.name, - version: dependency_version(dependency.name)&.to_s, + name: dependency.fetch("name"), + version: dependency_version(dependency.fetch("name"))&.to_s, requirements: [{ - requirement: dependency.requirement.to_s, - groups: dependency.runtime? ? ["runtime"] : ["development"], - source: source_for(dependency), + requirement: dependency.fetch("requirement").to_s, + groups: if dependency.fetch("type") == "runtime" + ["runtime"] + else + ["development"] + end, + source: dependency.fetch("source")&.transform_keys(&:to_sym), file: gemspec.name }], package_manager: "bundler" @@ -118,31 +143,30 @@ def lockfile_dependencies def parsed_gemfile @parsed_gemfile ||= - SharedHelpers.in_a_temporary_directory(base_directory) do + SharedHelpers.in_a_temporary_repo_directory(base_directory, + repo_contents_path) do write_temporary_dependency_files - SharedHelpers.in_a_forked_process do - ::Bundler.instance_variable_set(:@root, Pathname.new(Dir.pwd)) - - ::Bundler::Definition.build(gemfile.name, nil, {}). - dependencies. - select(&:current_platform?). - # We can't dump gemspec sources, and we wouldn't bump them - # anyway, so we filter them out. - reject { |dep| dep.source.is_a?(::Bundler::Source::Gemspec) } - end + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "parsed_gemfile", + options: options, + args: { + gemfile_name: gemfile.name, + lockfile_name: lockfile&.name, + dir: Dir.pwd + } + ) end - rescue SharedHelpers::ChildProcessFailed, ArgumentError => e - handle_marshall_error(e) if e.is_a?(ArgumentError) + rescue SharedHelpers::HelperSubprocessFailed => e + handle_eval_error(e) if e.error_class == "JSON::ParserError" msg = e.error_class + " with message: " + - e.error_message.force_encoding("UTF-8").encode + e.message.force_encoding("UTF-8").encode raise Dependabot::DependencyFileNotEvaluatable, msg end - def handle_marshall_error(err) - raise err unless err.message == "marshal data too short" - + def handle_eval_error(err) msg = "Error evaluating your dependency files: #{err.message}" raise Dependabot::DependencyFileNotEvaluatable, msg end @@ -150,20 +174,23 @@ def handle_marshall_error(err) def parsed_gemspec(file) @parsed_gemspecs ||= {} @parsed_gemspecs[file.name] ||= - SharedHelpers.in_a_temporary_directory(base_directory) do - [file, *imported_ruby_files].each do |f| - path = f.name - FileUtils.mkdir_p(Pathname.new(path).dirname) - File.write(path, f.content) - end - - SharedHelpers.in_a_forked_process do - ::Bundler.instance_variable_set(:@root, Pathname.new(Dir.pwd)) - ::Bundler.load_gemspec_uncached(file.name) - end + SharedHelpers.in_a_temporary_repo_directory(base_directory, + repo_contents_path) do + write_temporary_dependency_files + + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "parsed_gemspec", + options: options, + args: { + gemspec_name: file.name, + lockfile_name: lockfile&.name, + dir: Dir.pwd + } + ) end - rescue SharedHelpers::ChildProcessFailed => e - msg = e.error_class + " with message: " + e.error_message + rescue SharedHelpers::HelperSubprocessFailed => e + msg = e.error_class + " with message: " + e.message raise Dependabot::DependencyFileNotEvaluatable, msg end @@ -183,6 +210,8 @@ def write_temporary_dependency_files FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, file.content) end + + File.write(lockfile.name, sanitized_lockfile_content) if lockfile end def check_required_files @@ -197,42 +226,6 @@ def check_required_files raise "A gemspec or Gemfile must be provided!" end - def source_for(dependency) - source = dependency.source - if lockfile && default_rubygems?(source) - # If there's a lockfile and the Gemfile doesn't have anything - # interesting to say about the source, check that. - source = source_from_lockfile(dependency.name) - end - raise "Bad source: #{source}" unless sources.include?(source.class) - - return nil if default_rubygems?(source) - - details = { type: source.class.name.split("::").last.downcase } - if source.is_a?(::Bundler::Source::Git) - details.merge!(git_source_details(source)) - end - if source.is_a?(::Bundler::Source::Rubygems) - details[:url] = source.remotes.first.to_s - end - details - end - - def git_source_details(source) - { - url: source.uri, - branch: source.branch || "master", - ref: source.ref - } - end - - def default_rubygems?(source) - return true if source.nil? - return false unless source.is_a?(::Bundler::Source::Rubygems) - - source.remotes.any? { |r| r.to_s.include?("rubygems.org") } - end - def dependency_version(dependency_name) return unless lockfile @@ -246,17 +239,11 @@ def dependency_version(dependency_name) # If the source is Git we're better off knowing the SHA-1 than the # version. - if spec.source.instance_of?(::Bundler::Source::Git) - return spec.source.revision - end + return spec.source.revision if spec.source.instance_of?(::Bundler::Source::Git) spec.version end - def source_from_lockfile(dependency_name) - parsed_lockfile.specs.find { |s| s.name == dependency_name }&.source - end - def gemfile @gemfile ||= get_original_file("Gemfile") || get_original_file("gems.rb") @@ -313,6 +300,7 @@ def production?(dependency) groups.any? { |g| g.include?("prod") } end + # TODO: Stop sanitizing the lockfile once we have bundler 2 installed def sanitized_lockfile_content regex = FileUpdater::LockfileUpdater::LOCKFILE_ENDING lockfile.content.gsub(regex, "") @@ -330,6 +318,10 @@ def imported_ruby_files select { |f| f.name.end_with?(".rb") }. reject { |f| f.name == "gems.rb" } end + + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) + end end end end diff --git a/bundler/lib/dependabot/bundler/file_parser/gemfile_declaration_finder.rb b/bundler/lib/dependabot/bundler/file_parser/gemfile_declaration_finder.rb index 249c26d2954..ebed8281f82 100644 --- a/bundler/lib/dependabot/bundler/file_parser/gemfile_declaration_finder.rb +++ b/bundler/lib/dependabot/bundler/file_parser/gemfile_declaration_finder.rb @@ -8,27 +8,29 @@ module Bundler class FileParser # Checks whether a dependency is declared in a Gemfile class GemfileDeclarationFinder - def initialize(dependency:, gemfile:) - @dependency = dependency + def initialize(gemfile:) @gemfile = gemfile + @declaration_nodes = {} end - def gemfile_includes_dependency? - !declaration_node.nil? + def gemfile_includes_dependency?(dependency) + !declaration_node(dependency).nil? end - def enhanced_req_string - return unless gemfile_includes_dependency? + def enhanced_req_string(dependency) + return unless gemfile_includes_dependency?(dependency) - fallback_string = dependency.requirement.to_s - req_nodes = declaration_node.children[3..-1] + fallback_string = dependency.fetch("requirement") + req_nodes = declaration_node(dependency).children[3..-1] req_nodes = req_nodes.reject { |child| child.type == :hash } return fallback_string if req_nodes.none? return fallback_string unless req_nodes.all? { |n| n.type == :str } original_req_string = req_nodes.map { |n| n.children.last } - if dependency.requirement == Gem::Requirement.new(original_req_string) + fallback_requirement = + Gem::Requirement.new(fallback_string.split(", ")) + if fallback_requirement == Gem::Requirement.new(original_req_string) original_req_string.join(", ") else fallback_string @@ -37,35 +39,39 @@ def enhanced_req_string private - attr_reader :dependency, :gemfile + attr_reader :gemfile - def declaration_node - return @declaration_node if defined?(@declaration_node) - return unless Parser::CurrentRuby.parse(gemfile.content) + def parsed_gemfile + @parsed_gemfile ||= Parser::CurrentRuby.parse(gemfile.content) + end + + def declaration_node(dependency) + return @declaration_nodes[dependency] if @declaration_nodes.key?(dependency) + return unless parsed_gemfile - @declaration_node = nil - Parser::CurrentRuby.parse(gemfile.content).children.any? do |node| - @declaration_node = deep_search_for_gem(node) + @declaration_nodes[dependency] = nil + parsed_gemfile.children.any? do |node| + @declaration_nodes[dependency] = deep_search_for_gem(node, dependency) end - @declaration_node + @declaration_nodes[dependency] end - def deep_search_for_gem(node) - return node if declares_targeted_gem?(node) + def deep_search_for_gem(node, dependency) + return node if declares_targeted_gem?(node, dependency) return unless node.is_a?(Parser::AST::Node) declaration_node = nil node.children.find do |child_node| - declaration_node = deep_search_for_gem(child_node) + declaration_node = deep_search_for_gem(child_node, dependency) end declaration_node end - def declares_targeted_gem?(node) + def declares_targeted_gem?(node, dependency) return false unless node.is_a?(Parser::AST::Node) return false unless node.children[1] == :gem - node.children[2].children.first == dependency.name + node.children[2].children.first == dependency.fetch("name") end end end diff --git a/bundler/lib/dependabot/bundler/file_parser/gemspec_declaration_finder.rb b/bundler/lib/dependabot/bundler/file_parser/gemspec_declaration_finder.rb new file mode 100644 index 00000000000..715570e039b --- /dev/null +++ b/bundler/lib/dependabot/bundler/file_parser/gemspec_declaration_finder.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require "parser/current" + +module Dependabot + module Bundler + class FileParser + # Checks whether a dependency is declared in a gemspec file + class GemspecDeclarationFinder + def initialize(gemspec:) + @gemspec = gemspec + @declaration_nodes = {} + end + + def gemspec_includes_dependency?(dependency) + !declaration_node(dependency).nil? + end + + private + + attr_reader :gemspec + + def parsed_gemspec + @parsed_gemspec ||= Parser::CurrentRuby.parse(gemspec.content) + end + + def declaration_node(dependency) + return @declaration_nodes[dependency] if @declaration_nodes.key?(dependency) + return unless parsed_gemspec + + @declaration_nodes[dependency] = nil + parsed_gemspec.children.any? do |node| + @declaration_nodes[dependency] = deep_search_for_gem(node, dependency) + end + @declaration_nodes[dependency] + end + + def deep_search_for_gem(node, dependency) + return node if declares_targeted_gem?(node, dependency) + return unless node.is_a?(Parser::AST::Node) + + declaration_node = nil + node.children.find do |child_node| + declaration_node = deep_search_for_gem(child_node, dependency) + end + declaration_node + end + + def declares_targeted_gem?(node, dependency) + return false unless node.is_a?(Parser::AST::Node) + + second_child = node.children[1] + allowed_declarations = %i(add_dependency add_runtime_dependency add_development_dependency) + return false unless allowed_declarations.include?(second_child) + + node.children[2].children.first == dependency.fetch("name") + end + end + end + end +end diff --git a/bundler/lib/dependabot/bundler/file_updater.rb b/bundler/lib/dependabot/bundler/file_updater.rb index 2404d1f4a97..c13cdba36e4 100644 --- a/bundler/lib/dependabot/bundler/file_updater.rb +++ b/bundler/lib/dependabot/bundler/file_updater.rb @@ -2,6 +2,9 @@ require "dependabot/file_updaters" require "dependabot/file_updaters/base" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" +require "dependabot/file_updaters/vendor_updater" module Dependabot module Bundler @@ -20,6 +23,8 @@ def self.updated_files_regex ] end + # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize def updated_dependency_files updated_files = [] @@ -51,17 +56,47 @@ def updated_dependency_files end check_updated_files(updated_files) + + base_dir = updated_files.first.directory + vendor_updater. + updated_vendor_cache_files(base_directory: base_dir). + each do |file| + updated_files << file + end + updated_files end + # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/AbcSize private + # Dynamically fetch the vendor cache folder from bundler + def vendor_cache_dir + return @vendor_cache_dir if defined?(@vendor_cache_dir) + + @vendor_cache_dir = + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "vendor_cache_dir", + options: options, + args: { + dir: repo_contents_path + } + ) + end + + def vendor_updater + Dependabot::FileUpdaters::VendorUpdater.new( + repo_contents_path: repo_contents_path, + vendor_dir: vendor_cache_dir + ) + end + def check_required_files file_names = dependency_files.map(&:name) - if lockfile && !gemfile - raise "A Gemfile must be provided if a lockfile is!" - end + raise "A Gemfile must be provided if a lockfile is!" if lockfile && !gemfile return if file_names.any? { |name| name.match?(%r{^[^/]*\.gemspec$}) } return if gemfile @@ -116,7 +151,9 @@ def updated_lockfile_content LockfileUpdater.new( dependencies: dependencies, dependency_files: dependency_files, - credentials: credentials + repo_contents_path: repo_contents_path, + credentials: credentials, + options: options ).updated_lockfile_content end @@ -125,6 +162,10 @@ def top_level_gemspecs select { |file| file.name.end_with?(".gemspec") }. reject(&:support_file?) end + + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) + end end end end diff --git a/bundler/lib/dependabot/bundler/file_updater/gemfile_updater.rb b/bundler/lib/dependabot/bundler/file_updater/gemfile_updater.rb index 77c8aaabbd8..2a65922807b 100644 --- a/bundler/lib/dependabot/bundler/file_updater/gemfile_updater.rb +++ b/bundler/lib/dependabot/bundler/file_updater/gemfile_updater.rb @@ -6,6 +6,8 @@ module Dependabot module Bundler class FileUpdater class GemfileUpdater + GEMFILE_FILENAMES = %w(Gemfile gems.rb).freeze + require_relative "git_pin_replacer" require_relative "git_source_remover" require_relative "requirement_replacer" @@ -25,13 +27,9 @@ def updated_gemfile_content content ) - if remove_git_source?(dependency) - content = remove_gemfile_git_source(dependency, content) - end + content = remove_gemfile_git_source(dependency, content) if remove_git_source?(dependency) - if update_git_pin?(dependency) - content = update_gemfile_git_pin(dependency, gemfile, content) - end + content = update_gemfile_git_pin(dependency, gemfile, content) if update_git_pin?(dependency, gemfile) end content @@ -72,21 +70,21 @@ def requirement_changed?(file, dependency) def remove_git_source?(dependency) old_gemfile_req = dependency.previous_requirements. - find { |f| %w(Gemfile gems.rb).include?(f[:file]) } + find { |f| GEMFILE_FILENAMES.include?(f[:file]) } return false unless old_gemfile_req&.dig(:source, :type) == "git" new_gemfile_req = dependency.requirements. - find { |f| %w(Gemfile gems.rb).include?(f[:file]) } + find { |f| GEMFILE_FILENAMES.include?(f[:file]) } new_gemfile_req[:source].nil? end - def update_git_pin?(dependency) + def update_git_pin?(dependency, file) new_gemfile_req = dependency.requirements. - find { |f| %w(Gemfile gems.rb).include?(f[:file]) } + find { |f| f[:file] == file.name } return false unless new_gemfile_req&.dig(:source, :type) == "git" # If the new requirement is a git dependency with a ref then there's diff --git a/bundler/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb b/bundler/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb index 6dec577d79e..f8964699f07 100644 --- a/bundler/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb +++ b/bundler/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb @@ -90,9 +90,9 @@ def requires_file?(node) def wrap_require(node) replace( node.loc.expression, - "begin\n"\ - "#{node.loc.expression.source_line}\n"\ - "rescue LoadError\n"\ + "begin\n" \ + "#{node.loc.expression.source_line}\n" \ + "rescue LoadError\n" \ "end" ) end @@ -100,9 +100,7 @@ def wrap_require(node) def replace_version_assignments(node) return unless node.is_a?(Parser::AST::Node) - if node_assigns_to_version_constant?(node) - return replace_constant(node) - end + return replace_constant(node) if node_assigns_to_version_constant?(node) node.children.each { |child| replace_version_assignments(child) } end @@ -110,9 +108,7 @@ def replace_version_assignments(node) def replace_version_constant_references(node) return unless node.is_a?(Parser::AST::Node) - if node_is_version_constant?(node) - return replace(node.loc.expression, %("#{replacement_version}")) - end + return replace(node.loc.expression, %("#{replacement_version}")) if node_is_version_constant?(node) node.children.each do |child| replace_version_constant_references(child) @@ -122,9 +118,7 @@ def replace_version_constant_references(node) def replace_file_assignments(node) return unless node.is_a?(Parser::AST::Node) - if node_assigns_files_to_var?(node) - return replace_file_assignment(node) - end + return replace_file_assignment(node) if node_assigns_files_to_var?(node) node.children.each { |child| replace_file_assignments(child) } end @@ -132,9 +126,7 @@ def replace_file_assignments(node) def replace_require_paths_assignments(node) return unless node.is_a?(Parser::AST::Node) - if node_assigns_require_paths?(node) - return replace_require_paths_assignment(node) - end + return replace_require_paths_assignment(node) if node_assigns_require_paths?(node) node.children.each do |child| replace_require_paths_assignments(child) @@ -242,11 +234,8 @@ def node_calls_find_dot_find?(node) def remove_unnecessary_assignments(node) return unless node.is_a?(Parser::AST::Node) - if unnecessary_assignment?(node) && - node.children.last&.location&.respond_to?(:heredoc_end) - range_to_remove = node.loc.expression.join( - node.children.last.location.heredoc_end - ) + if unnecessary_assignment?(node) && node_includes_heredoc?(node) + range_to_remove = node.loc.expression.join(find_heredoc_end_range(node)) return replace(range_to_remove, '"sanitized"') elsif unnecessary_assignment?(node) return replace(node.loc.expression, '"sanitized"') @@ -257,6 +246,30 @@ def remove_unnecessary_assignments(node) end end + def node_includes_heredoc?(node) + find_heredoc_end_range(node) + end + + # Performs a depth-first search for the first heredoc in the given + # Parser::AST::Node. + # + # Returns a Parser::Source::Range identifying the location of the end + # of the heredoc, or nil if no heredoc was found. + def find_heredoc_end_range(node) + return unless node.is_a?(Parser::AST::Node) + + node.children.each do |child| + next unless child.is_a?(Parser::AST::Node) + + return child.location.heredoc_end if child.location.respond_to?(:heredoc_end) + + range = find_heredoc_end_range(child) + return range if range + end + + nil + end + def unnecessary_assignment?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) @@ -294,22 +307,11 @@ def node_interpolates_version_constant?(node) def replace_constant(node) case node.children.last&.type when :str, :int then nil # no-op - when :float, :const, :send, :lvar, :if + when :float, :const, :send, :lvar, :if, :dstr replace( node.children.last.loc.expression, %("#{replacement_version}") ) - when :dstr - node.children.last.children. - select { |n| n.type == :begin }. - flat_map(&:children). - select { |n| node_is_version_constant?(n) }. - each do |n| - replace( - n.loc.expression, - %("#{replacement_version}") - ) - end else raise "Unexpected node type #{node.children.last&.type}" end diff --git a/bundler/lib/dependabot/bundler/file_updater/lockfile_updater.rb b/bundler/lib/dependabot/bundler/file_updater/lockfile_updater.rb index 4b152ba5f90..11efb8d86d1 100644 --- a/bundler/lib/dependabot/bundler/file_updater/lockfile_updater.rb +++ b/bundler/lib/dependabot/bundler/file_updater/lockfile_updater.rb @@ -2,14 +2,12 @@ require "bundler" -require "dependabot/monkey_patches/bundler/definition_ruby_version_patch" -require "dependabot/monkey_patches/bundler/definition_bundler_version_patch" -require "dependabot/monkey_patches/bundler/git_source_patch" - require "dependabot/shared_helpers" require "dependabot/errors" require "dependabot/bundler/file_updater" -require "dependabot/git_commit_checker" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" + module Dependabot module Bundler class FileUpdater @@ -20,17 +18,9 @@ class LockfileUpdater require_relative "gemspec_dependency_name_finder" require_relative "ruby_requirement_setter" - LOCKFILE_ENDING = - /(?\s*(?:RUBY VERSION|BUNDLED WITH).*)/m.freeze - GIT_DEPENDENCIES_SECTION = /GIT\n.*?\n\n(?!GIT)/m.freeze - GIT_DEPENDENCY_DETAILS = /GIT\n.*?\n\n/m.freeze - GEM_NOT_FOUND_ERROR_REGEX = - / - locked\sto\s(?[^\s]+)\s\(| - not\sfind\s(?[^\s]+)-\d| - has\s(?[^\s]+)\slocked\sat - /x.freeze - RETRYABLE_ERRORS = [::Bundler::HTTPError].freeze + LOCKFILE_ENDING = /(?\s*(?:RUBY VERSION|BUNDLED WITH).*)/m + GIT_DEPENDENCIES_SECTION = /GIT\n.*?\n\n(?!GIT)/m + GIT_DEPENDENCY_DETAILS = /GIT\n.*?\n\n/m # Can't be a constant because some of these don't exist in bundler # 1.15, which Heroku uses, which causes an exception on boot. @@ -41,10 +31,13 @@ def gemspec_sources ] end - def initialize(dependencies:, dependency_files:, credentials:) + def initialize(dependencies:, dependency_files:, + repo_contents_path: nil, credentials:, options:) @dependencies = dependencies @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials + @options = options end def updated_lockfile_content @@ -52,9 +45,7 @@ def updated_lockfile_content begin updated_content = build_updated_lockfile - if lockfile.content == updated_content - raise "Expected content to change!" - end + raise "Expected content to change!" if lockfile.content == updated_content updated_content end @@ -62,42 +53,32 @@ def updated_lockfile_content private - attr_reader :dependencies, :dependency_files, :credentials + attr_reader :dependencies, :dependency_files, :repo_contents_path, + :credentials, :options def build_updated_lockfile base_dir = dependency_files.first.directory lockfile_body = - SharedHelpers.in_a_temporary_directory(base_dir) do |tmp_dir| + SharedHelpers.in_a_temporary_repo_directory( + base_dir, + repo_contents_path + ) do |tmp_dir| write_temporary_dependency_files - SharedHelpers.in_a_forked_process do - # Set the path for path gemspec correctly - ::Bundler.instance_variable_set(:@root, tmp_dir) - - # Remove installed gems from the default Rubygems index - ::Gem::Specification.all = - ::Gem::Specification.send(:default_stubs, "*.gemspec") - - # Set flags and credentials - set_bundler_flags_and_credentials - - generate_lockfile - end + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "update_lockfile", + options: options, + args: { + gemfile_name: gemfile.name, + lockfile_name: lockfile.name, + dir: tmp_dir, + credentials: credentials, + dependencies: dependencies.map(&:to_h) + } + ) end post_process_lockfile(lockfile_body) - rescue SharedHelpers::ChildProcessFailed => e - raise unless ruby_lock_error?(e) - - @dont_lock_ruby_version = true - retry - end - - def ruby_lock_error?(error) - return false unless error.error_class == "Bundler::VersionConflict" - return false unless error.message.include?(" for gem \"ruby\0\"") - return false if @dont_lock_ruby_version - - dependency_files.any? { |f| f.name.end_with?(".gemspec") } end def write_temporary_dependency_files @@ -122,114 +103,6 @@ def write_temporary_dependency_files end end - def generate_lockfile - dependencies_to_unlock = dependencies.map(&:name) - - begin - definition = build_definition(dependencies_to_unlock) - - old_reqs = lock_deps_being_updated_to_exact_versions(definition) - - definition.resolve_remotely! - - old_reqs.each do |dep_name, old_req| - d_dep = definition.dependencies.find { |d| d.name == dep_name } - if old_req == :none then definition.dependencies.delete(d_dep) - else d_dep.instance_variable_set(:@requirement, old_req) - end - end - - definition.to_lock - rescue ::Bundler::GemNotFound => e - unlock_yanked_gem(dependencies_to_unlock, e) && retry - rescue ::Bundler::VersionConflict => e - unlock_blocking_subdeps(dependencies_to_unlock, e) && retry - rescue *RETRYABLE_ERRORS - raise if @retrying - - @retrying = true - sleep(rand(1.0..5.0)) - retry - end - end - - def unlock_yanked_gem(dependencies_to_unlock, error) - raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) - - gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). - named_captures["name"] - raise if dependencies_to_unlock.include?(gem_name) - - dependencies_to_unlock << gem_name - end - - def unlock_blocking_subdeps(dependencies_to_unlock, error) - all_deps = ::Bundler::LockfileParser.new(sanitized_lockfile_body). - specs.map(&:name).map(&:to_s) - top_level = build_definition([]).dependencies. - map(&:name).map(&:to_s) - allowed_new_unlocks = all_deps - top_level - dependencies_to_unlock - - raise if allowed_new_unlocks.none? - - # Unlock any sub-dependencies that Bundler reports caused the - # conflict - potentials_deps = - error.cause.conflicts.values. - flat_map(&:requirement_trees). - map do |tree| - tree.find { |req| allowed_new_unlocks.include?(req.name) } - end.compact.map(&:name) - - # If there are specific dependencies we can unlock, unlock them - if potentials_deps.any? - return dependencies_to_unlock.append(*potentials_deps) - end - - # Fall back to unlocking *all* sub-dependencies. This is required - # because Bundler's VersionConflict objects don't include enough - # information to chart the full path through all conflicts unwound - dependencies_to_unlock.append(*allowed_new_unlocks) - end - - def build_definition(dependencies_to_unlock) - defn = ::Bundler::Definition.build( - gemfile.name, - lockfile.name, - gems: dependencies_to_unlock - ) - - # Bundler unlocks the sub-dependencies of gems it is passed even - # if those sub-deps are top-level dependencies. We only want true - # subdeps unlocked, like they were in the UpdateChecker, so we - # mutate the unlocked gems array. - unlocked = defn.instance_variable_get(:@unlock).fetch(:gems) - must_not_unlock = defn.dependencies.map(&:name).map(&:to_s) - - dependencies_to_unlock - unlocked.reject! { |n| must_not_unlock.include?(n) } - - defn - end - - def lock_deps_being_updated_to_exact_versions(definition) - dependencies.each_with_object({}) do |dep, old_reqs| - defn_dep = definition.dependencies.find { |d| d.name == dep.name } - - if defn_dep.nil? - definition.dependencies << - ::Bundler::Dependency.new(dep.name, dep.version) - old_reqs[dep.name] = :none - elsif git_dependency?(dep) && - defn_dep.source.is_a?(::Bundler::Source::Git) - defn_dep.source.unlock! - elsif Gem::Version.correct?(dep.version) - new_req = Gem::Requirement.create("= #{dep.version}") - old_reqs[dep.name] = defn_dep.requirement - defn_dep.instance_variable_set(:@requirement, new_req) - end - end - end - def write_ruby_version_file return unless ruby_version_file @@ -330,6 +203,7 @@ def sanitized_gemspec_content(gemspec_content) rewrite(gemspec_content) end + # rubocop:disable Metrics/PerceivedComplexity def replacement_version_for_gemspec(gemspec_content) return "0.0.1" unless lockfile @@ -346,25 +220,10 @@ def replacement_version_for_gemspec(gemspec_content) spec = gemspec_specs.find { |s| s.name == gem_name } spec&.version || gemspec_specs.first&.version || "0.0.1" end - - def relevant_credentials - credentials. - select { |cred| cred["password"] || cred["token"] }. - select do |cred| - next true if cred["type"] == "git_source" - next true if cred["type"] == "rubygems_server" - - false - end - end + # rubocop:enable Metrics/PerceivedComplexity def prepared_gemfile_content(file) - content = - GemfileUpdater.new( - dependencies: dependencies, - gemfile: file - ).updated_gemfile_content - return content if @dont_lock_ruby_version + content = updated_gemfile_content(file) top_level_gemspecs.each do |gs| content = RubyRequirementSetter.new(gemspec: gs).rewrite(content) @@ -398,6 +257,7 @@ def lockfile dependency_files.find { |f| f.name == "gems.locked" } end + # TODO: Stop sanitizing the lockfile once we have bundler 2 installed def sanitized_lockfile_body lockfile.content.gsub(LOCKFILE_ENDING, "") end @@ -419,38 +279,8 @@ def specification_files dependency_files.select { |f| f.name.end_with?(".specification") } end - def set_bundler_flags_and_credentials - # Set auth details - relevant_credentials.each do |cred| - token = cred["token"] || - "#{cred['username']}:#{cred['password']}" - - ::Bundler.settings.set_command_option( - cred.fetch("host"), - token.gsub("@", "%40F").gsub("?", "%3F") - ) - end - - # Use HTTPS for GitHub if lockfile was generated by Bundler 2 - set_bundler_2_flags if using_bundler_2? - end - - def set_bundler_2_flags - ::Bundler.settings.set_command_option("forget_cli_options", "true") - ::Bundler.settings.set_command_option("github.https", "true") - end - - def git_dependency?(dep) - GitCommitChecker.new( - dependency: dep, - credentials: credentials - ).git_dependency? - end - - def using_bundler_2? - return unless lockfile - - lockfile.content.match?(/BUNDLED WITH\s+2/m) + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) end end end diff --git a/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb b/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb index 1c28dbd6bd9..f4a5f388f10 100644 --- a/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb +++ b/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb @@ -56,7 +56,7 @@ def update_comment_spacing_if_required(content, updated_content) if length_change.positive? updated_line.sub(/(?<=\s)\s{#{length_change}}#/, "#") elsif length_change.negative? - updated_line.sub(/(?<=\s{2})#/, " " * length_change.abs + "#") + updated_line.sub(/(?<=\s{2})#/, (" " * length_change.abs) + "#") end updated_lines[updated_line_index] = updated_line @@ -64,9 +64,7 @@ def update_comment_spacing_if_required(content, updated_content) end def length_change - unless previous_requirement.start_with?("=") - return updated_requirement.length - previous_requirement.length - end + return updated_requirement.length - previous_requirement.length unless previous_requirement.start_with?("=") updated_requirement.length - previous_requirement.gsub(/^=/, "").strip.length @@ -75,7 +73,7 @@ def length_change class Rewriter < Parser::TreeRewriter # TODO: Ideally we wouldn't have to ignore all of these, but # implementing each one will be tricky. - SKIPPED_TYPES = %i(send lvar dstr begin if splat const or).freeze + SKIPPED_TYPES = %i(send lvar dstr begin if case splat const or).freeze def initialize(dependency:, file_type:, updated_requirement:, insert_if_bare:) @@ -169,6 +167,8 @@ def space_after_specifier?(requirement_nodes) req_string.include?(" ") end + EQUALITY_OPERATOR = /(?!])=/ + def use_equality_operator?(requirement_nodes) return true if requirement_nodes.none? @@ -180,7 +180,7 @@ def use_equality_operator?(requirement_nodes) requirement_nodes.first.children.first.loc.expression.source end - req_string.match?(/(?])=/) + req_string.match?(EQUALITY_OPERATOR) end def new_requirement_string(quote_characters:, @@ -205,9 +205,7 @@ def serialized_req(req, use_equality_operator) # Gem::Requirement serializes exact matches as a string starting # with `=`. We may need to remove that equality operator if it # wasn't used originally. - unless use_equality_operator - tmp_req = tmp_req.gsub(/(?])=/, "") - end + tmp_req = tmp_req.gsub(EQUALITY_OPERATOR, "") unless use_equality_operator tmp_req.strip end diff --git a/bundler/lib/dependabot/bundler/file_updater/ruby_requirement_setter.rb b/bundler/lib/dependabot/bundler/file_updater/ruby_requirement_setter.rb index 70ca9fb06a0..a434a8dd519 100644 --- a/bundler/lib/dependabot/bundler/file_updater/ruby_requirement_setter.rb +++ b/bundler/lib/dependabot/bundler/file_updater/ruby_requirement_setter.rb @@ -2,13 +2,17 @@ require "parser/current" require "dependabot/bundler/file_updater" +require "dependabot/bundler/requirement" module Dependabot module Bundler class FileUpdater class RubyRequirementSetter - RUBY_VERSIONS = - %w(1.8.7 1.9.3 2.0.0 2.1.10 2.2.10 2.3.8 2.4.7 2.5.6 2.6.4).freeze + class RubyVersionNotFound < StandardError; end + + RUBY_VERSIONS = %w( + 1.8.7 1.9.3 2.0.0 2.1.10 2.2.10 2.3.8 2.4.10 2.5.9 2.6.7 2.7.3 3.0.1 3.1.1 + ).freeze attr_reader :gemspec @@ -46,14 +50,18 @@ def declares_ruby_version?(node) end def ruby_version - requirement = Gem::Requirement.new(ruby_requirement) + requirement = if ruby_requirement.is_a?(Gem::Requirement) + ruby_requirement + else + Dependabot::Bundler::Requirement.new(ruby_requirement) + end ruby_version = RUBY_VERSIONS. map { |v| Gem::Version.new(v) }.sort. find { |v| requirement.satisfied_by?(v) } - raise "Couldn't find Ruby version!" unless ruby_version + raise RubyVersionNotFound unless ruby_version ruby_version end diff --git a/bundler/lib/dependabot/bundler/helpers.rb b/bundler/lib/dependabot/bundler/helpers.rb new file mode 100644 index 00000000000..d59234c35dc --- /dev/null +++ b/bundler/lib/dependabot/bundler/helpers.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Dependabot + module Bundler + module Helpers + V1 = "1" + V2 = "2" + # If we are updating a project with no Gemfile.lock, we default to the + # newest version we support + DEFAULT = V2 + # If we are updating a project with a Gemfile.lock that does not specify + # the version it was bundled with, with failover to V1 on the assumption + # it was created with an old version that didn't add this information + FAILOVER = V1 + + BUNDLER_MAJOR_VERSION_REGEX = /BUNDLED WITH\s+(?\d+)\./m + + def self.bundler_version(lockfile) + return DEFAULT unless lockfile + + if (matches = lockfile.content.match(BUNDLER_MAJOR_VERSION_REGEX)) + matches[:version].to_i >= 2 ? V2 : V1 + else + FAILOVER + end + end + + def self.detected_bundler_version(lockfile) + return "unknown" unless lockfile + + if (matches = lockfile.content.match(BUNDLER_MAJOR_VERSION_REGEX)) + matches[:version] + else + "1" + end + end + end + end +end diff --git a/bundler/lib/dependabot/bundler/metadata_finder.rb b/bundler/lib/dependabot/bundler/metadata_finder.rb index a003257119b..d90a4ed7ca7 100644 --- a/bundler/lib/dependabot/bundler/metadata_finder.rb +++ b/bundler/lib/dependabot/bundler/metadata_finder.rb @@ -3,6 +3,7 @@ require "excon" require "dependabot/metadata_finders" require "dependabot/metadata_finders/base" +require "dependabot/registry_client" module Dependabot module Bundler @@ -75,7 +76,7 @@ def find_source_from_rubygems_api_response end def find_source_from_git_url - info = dependency.requirements.map { |r| r[:source] }.compact.first + info = dependency.requirements.filter_map { |r| r[:source] }.first url = info[:url] || info.fetch("url") Source.from_url(url) @@ -105,8 +106,8 @@ def changelog_url_from_gemspec_download rubygems_marshalled_gemspec_response.gsub("\x06;", "\n"). scan(Dependabot::Source::SOURCE_REGEX) do - github_urls << Regexp.last_match.to_s + - Regexp.last_match.post_match.split("\n").first + github_urls << (Regexp.last_match.to_s + + Regexp.last_match.post_match.split("\n").first) end github_urls.find do |url| @@ -117,28 +118,22 @@ def changelog_url_from_gemspec_download end end - # Note: This response MUST NOT be unmarshalled + # NOTE: This response MUST NOT be unmarshalled # (as calling Marshal.load is unsafe) def rubygems_marshalled_gemspec_response - if defined?(@rubygems_marshalled_gemspec_response) - return @rubygems_marshalled_gemspec_response - end + return @rubygems_marshalled_gemspec_response if defined?(@rubygems_marshalled_gemspec_response) gemspec_uri = - "#{registry_url}quick/Marshal.4.8/"\ + "#{registry_url}quick/Marshal.4.8/" \ "#{dependency.name}-#{dependency.version}.gemspec.rz" response = - Excon.get( - gemspec_uri, - headers: registry_auth_headers, - idempotent: true, - **SharedHelpers.excon_defaults + Dependabot::RegistryClient.get( + url: gemspec_uri, + headers: registry_auth_headers ) - if response.status >= 400 - return @rubygems_marshalled_gemspec_response = nil - end + return @rubygems_marshalled_gemspec_response = nil if response.status >= 400 @rubygems_marshalled_gemspec_response = Zlib::Inflate.inflate(response.body) @@ -150,11 +145,9 @@ def rubygems_api_response return @rubygems_api_response if defined?(@rubygems_api_response) response = - Excon.get( - "#{registry_url}api/v1/gems/#{dependency.name}.json", - headers: registry_auth_headers, - idempotent: true, - **SharedHelpers.excon_defaults + Dependabot::RegistryClient.get( + url: "#{registry_url}api/v1/gems/#{dependency.name}.json", + headers: registry_auth_headers ) return @rubygems_api_response = {} if response.status >= 400 @@ -192,11 +185,7 @@ def augment_private_response_if_appropriate(response_body) return response_body if source_url rubygems_response = - Excon.get( - "https://rubygems.org/api/v1/gems/#{dependency.name}.json", - idempotent: true, - **SharedHelpers.excon_defaults - ) + Dependabot::RegistryClient.get(url: "https://rubygems.org/api/v1/gems/#{dependency.name}.json") parsed_rubygems_body = JSON.parse(rubygems_response.body) rubygems_digest = parsed_rubygems_body.values_at("version", "authors", "info").hash @@ -207,12 +196,22 @@ def augment_private_response_if_appropriate(response_body) end def registry_url - return "https://rubygems.org/" if new_source_type == "default" + return base_url if new_source_type == "default" - info = dependency.requirements.map { |r| r[:source] }.compact.first + info = dependency.requirements.filter_map { |r| r[:source] }.first info[:url] || info.fetch("url") end + def base_url + return @base_url if defined?(@base_url) + + credential = credentials.find do |cred| + cred["type"] == "rubygems_server" && cred["replaces-base"] == true + end + host = credential ? credential["host"] : "rubygems.org" + @base_url = "https://#{host}" + ("/" unless host.end_with?("/")) + end + def registry_auth_headers return {} unless new_source_type == "rubygems" diff --git a/bundler/lib/dependabot/bundler/native_helpers.rb b/bundler/lib/dependabot/bundler/native_helpers.rb new file mode 100644 index 00000000000..f58d6b232ca --- /dev/null +++ b/bundler/lib/dependabot/bundler/native_helpers.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require "bundler" +require "dependabot/shared_helpers" + +module Dependabot + module Bundler + module NativeHelpers + class BundleCommand + MAX_SECONDS = 1800 + MIN_SECONDS = 60 + + def initialize(timeout_seconds) + @timeout_seconds = clamp(timeout_seconds) + end + + def build(script) + [timeout_command, :ruby, script].compact.join(" ") + end + + private + + attr_reader :timeout_seconds + + def timeout_command + "timeout -s HUP #{timeout_seconds}" unless timeout_seconds.zero? + end + + def clamp(seconds) + return 0 unless seconds + + seconds.to_i.clamp(MIN_SECONDS, MAX_SECONDS) + end + end + + def self.run_bundler_subprocess(function:, args:, bundler_version:, options: {}) + # Run helper suprocess with all bundler-related ENV variables removed + helpers_path = versioned_helper_path(bundler_version) + ::Bundler.with_original_env do + command = BundleCommand. + new(options[:timeout_per_operation_seconds]). + build(File.join(helpers_path, "run.rb")) + SharedHelpers.run_helper_subprocess( + command: command, + function: function, + args: args, + env: { + "BUNDLE_GEMFILE" => File.join(helpers_path, "Gemfile"), + # Prevent the GEM_HOME from being set to a folder owned by root + "GEM_HOME" => File.join(helpers_path, ".bundle") + } + ) + rescue SharedHelpers::HelperSubprocessFailed => e + # TODO: Remove once we stop stubbing out the V2 native helper + raise Dependabot::NotImplemented, e.message if e.error_class == "Functions::NotImplementedError" + + raise + end + end + + def self.versioned_helper_path(bundler_major_version) + File.join(native_helpers_root, "v#{bundler_major_version}") + end + + def self.native_helpers_root + helpers_root = ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", nil) + return File.join(helpers_root, "bundler") unless helpers_root.nil? + + File.expand_path("../../../helpers", __dir__) + end + end + end +end diff --git a/bundler/lib/dependabot/bundler/requirement.rb b/bundler/lib/dependabot/bundler/requirement.rb index a9136859c3c..7ead53b3b94 100644 --- a/bundler/lib/dependabot/bundler/requirement.rb +++ b/bundler/lib/dependabot/bundler/requirement.rb @@ -5,7 +5,7 @@ module Dependabot module Bundler class Requirement < Gem::Requirement - # For consistency with other langauges, we define a requirements array. + # For consistency with other languages, we define a requirements array. # Ruby doesn't have an `OR` separator for requirements, so it always # contains a single element. def self.requirements_array(requirement_string) @@ -16,7 +16,7 @@ def self.requirements_array(requirement_string) # "~> 4.2.5, >= 4.2.5.1" without first needing to split them. def initialize(*requirements) requirements = requirements.flatten.flat_map do |req_string| - req_string.split(",") + req_string.split(",").map(&:strip) end super(requirements) diff --git a/bundler/lib/dependabot/bundler/update_checker.rb b/bundler/lib/dependabot/bundler/update_checker.rb index 74510347783..282aa266b65 100644 --- a/bundler/lib/dependabot/bundler/update_checker.rb +++ b/bundler/lib/dependabot/bundler/update_checker.rb @@ -13,6 +13,7 @@ class UpdateChecker < Dependabot::UpdateCheckers::Base require_relative "update_checker/requirements_updater" require_relative "update_checker/version_resolver" require_relative "update_checker/latest_version_finder" + require_relative "update_checker/conflicting_dependency_resolver" def latest_version return latest_version_for_git_dependency if git_dependency? @@ -26,6 +27,11 @@ def latest_resolvable_version latest_resolvable_version_details&.fetch(:version) end + def lowest_security_fix_version + latest_version_finder(remove_git_source: false). + lowest_security_fix_version + end + def lowest_resolvable_security_fix_version raise "Dependency not vulnerable!" unless vulnerable? return latest_resolvable_version if git_dependency? @@ -94,14 +100,24 @@ def requirements_unlocked_or_can_be? def requirements_update_strategy # If passed in as an option (in the base class) honour that option - if @requirements_update_strategy - return @requirements_update_strategy.to_sym - end + return @requirements_update_strategy.to_sym if @requirements_update_strategy # Otherwise, widen ranges for libraries and bump versions for apps dependency.version.nil? ? :bump_versions_if_necessary : :bump_versions end + def conflicting_dependencies + ConflictingDependencyResolver.new( + dependency_files: dependency_files, + repo_contents_path: repo_contents_path, + credentials: credentials, + options: options + ).conflicting_dependencies( + dependency: dependency, + target_version: lowest_security_fix_version + ) + end + private def latest_version_resolvable_with_full_unlock? @@ -125,9 +141,7 @@ def updated_dependencies_after_full_unlock end def preferred_resolvable_version_details - if vulnerable? - return { version: lowest_resolvable_security_fix_version } - end + return { version: lowest_resolvable_security_fix_version } if vulnerable? latest_resolvable_version_details end @@ -145,10 +159,12 @@ def resolvable?(version) ForceUpdater.new( dependency: dependency, dependency_files: dependency_files, + repo_contents_path: repo_contents_path, credentials: credentials, target_version: version, requirements_update_strategy: requirements_update_strategy, - update_multiple_dependencies: false + update_multiple_dependencies: false, + options: options ).updated_dependencies true rescue Dependabot::DependencyFileNotResolvable @@ -165,10 +181,12 @@ def git_tag_resolvable?(tag) VersionResolver.new( dependency: dependency, unprepared_dependency_files: dependency_files, + repo_contents_path: repo_contents_path, credentials: credentials, ignored_versions: ignored_versions, raise_on_ignored: raise_on_ignored, - replacement_git_pin: tag + replacement_git_pin: tag, + options: options ).latest_resolvable_version_details true rescue Dependabot::DependencyFileNotResolvable @@ -201,9 +219,7 @@ def latest_version_for_git_dependency # Otherwise, if the gem isn't pinned, the latest version is just the # latest commit for the specified branch. - unless git_commit_checker.pinned? - return git_commit_checker.head_commit_for_current_branch - end + return git_commit_checker.head_commit_for_current_branch unless git_commit_checker.pinned? # If the dependency is pinned to a tag that looks like a version then # we want to update that tag. The latest version will then be the SHA @@ -227,9 +243,7 @@ def latest_resolvable_version_for_git_dependency # Otherwise, if the gem isn't pinned, the latest version is just the # latest commit for the specified branch. - unless git_commit_checker.pinned? - return latest_resolvable_commit_with_unchanged_git_source - end + return latest_resolvable_commit_with_unchanged_git_source unless git_commit_checker.pinned? # If the dependency is pinned to a tag that looks like a version then # we want to update that tag. The latest version will then be the SHA @@ -325,9 +339,11 @@ def force_updater ForceUpdater.new( dependency: dependency, dependency_files: dependency_files, + repo_contents_path: repo_contents_path, credentials: credentials, target_version: latest_version, - requirements_update_strategy: requirements_update_strategy + requirements_update_strategy: requirements_update_strategy, + options: options ) end @@ -343,18 +359,18 @@ def version_resolver(remove_git_source:, unlock_requirement: true) @version_resolver ||= {} @version_resolver[remove_git_source] ||= {} @version_resolver[remove_git_source][unlock_requirement] ||= - begin - VersionResolver.new( - dependency: dependency, - unprepared_dependency_files: dependency_files, - credentials: credentials, - ignored_versions: ignored_versions, - raise_on_ignored: raise_on_ignored, - remove_git_source: remove_git_source, - unlock_requirement: unlock_requirement, - latest_allowable_version: latest_version - ) - end + VersionResolver.new( + dependency: dependency, + unprepared_dependency_files: dependency_files, + repo_contents_path: repo_contents_path, + credentials: credentials, + ignored_versions: ignored_versions, + raise_on_ignored: raise_on_ignored, + remove_git_source: remove_git_source, + unlock_requirement: unlock_requirement, + latest_allowable_version: latest_version, + options: options + ) end def latest_version_finder(remove_git_source:) @@ -369,10 +385,12 @@ def latest_version_finder(remove_git_source:) LatestVersionFinder.new( dependency: dependency, dependency_files: prepared_dependency_files, + repo_contents_path: repo_contents_path, credentials: credentials, ignored_versions: ignored_versions, raise_on_ignored: raise_on_ignored, - security_advisories: security_advisories + security_advisories: security_advisories, + options: options ) end end diff --git a/bundler/lib/dependabot/bundler/update_checker/conflicting_dependency_resolver.rb b/bundler/lib/dependabot/bundler/update_checker/conflicting_dependency_resolver.rb new file mode 100644 index 00000000000..dd0404a5b03 --- /dev/null +++ b/bundler/lib/dependabot/bundler/update_checker/conflicting_dependency_resolver.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "dependabot/bundler/update_checker" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" +require "dependabot/shared_helpers" + +module Dependabot + module Bundler + class UpdateChecker < UpdateCheckers::Base + class ConflictingDependencyResolver + require_relative "shared_bundler_helpers" + include SharedBundlerHelpers + + attr_reader :options + + def initialize(dependency_files:, repo_contents_path:, credentials:, options:) + @dependency_files = dependency_files + @repo_contents_path = repo_contents_path + @credentials = credentials + @options = options + end + + # Finds any dependencies in the lockfile that have a subdependency on + # the given dependency that does not satisfly the target_version. + # + # @param dependency [Dependabot::Dependency] the dependency to check + # @param target_version [String] the version to check + # @return [Array String}] + # * name [String] the blocking dependencies name + # * version [String] the version of the blocking dependency + # * requirement [String] the requirement on the target_dependency + def conflicting_dependencies(dependency:, target_version:) + return [] if lockfile.nil? + + in_a_native_bundler_context(error_handling: false) do |tmp_dir| + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "conflicting_dependencies", + options: options, + args: { + dir: tmp_dir, + dependency_name: dependency.name, + target_version: target_version, + credentials: credentials, + lockfile_name: lockfile.name + } + ) + end + end + + private + + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) + end + end + end + end +end diff --git a/bundler/lib/dependabot/bundler/update_checker/file_preparer.rb b/bundler/lib/dependabot/bundler/update_checker/file_preparer.rb index fc515815daa..d6858cddaad 100644 --- a/bundler/lib/dependabot/bundler/update_checker/file_preparer.rb +++ b/bundler/lib/dependabot/bundler/update_checker/file_preparer.rb @@ -24,7 +24,7 @@ class UpdateChecker # version allowed by the gemspec, if the gemspec has a required ruby # version range class FilePreparer - VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze + VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/ # Can't be a constant because some of these don't exist in bundler # 1.15, which Heroku uses, which causes an exception on boot. @@ -207,13 +207,12 @@ def updated_version_requirement_string(filename) lower_bound_req = updated_version_req_lower_bound(filename) return lower_bound_req if latest_allowable_version.nil? - unless Gem::Version.correct?(latest_allowable_version) - return lower_bound_req - end + return lower_bound_req unless Gem::Version.correct?(latest_allowable_version) lower_bound_req + ", <= #{latest_allowable_version}" end + # rubocop:disable Metrics/PerceivedComplexity def updated_version_req_lower_bound(filename) original_req = dependency.requirements. find { |r| r.fetch(:file) == filename }&. @@ -234,6 +233,7 @@ def updated_version_req_lower_bound(filename) ">= #{version_for_requirement || 0}" end end + # rubocop:enable Metrics/PerceivedComplexity def remove_git_source(content) FileUpdater::GitSourceRemover.new( @@ -261,6 +261,7 @@ def lock_ruby_version?(file) @lock_ruby_version && file == gemfile end + # rubocop:disable Metrics/PerceivedComplexity def replacement_version_for_gemspec(gemspec_content) return "0.0.1" unless lockfile @@ -278,7 +279,9 @@ def replacement_version_for_gemspec(gemspec_content) spec = gemspec_specs.find { |s| s.name == gem_name } spec&.version || gemspec_specs.first&.version || "0.0.1" end + # rubocop:enable Metrics/PerceivedComplexity + # TODO: Stop sanitizing the lockfile once we have bundler 2 installed def sanitized_lockfile_content re = FileUpdater::LockfileUpdater::LOCKFILE_ENDING lockfile.content.gsub(re, "") diff --git a/bundler/lib/dependabot/bundler/update_checker/force_updater.rb b/bundler/lib/dependabot/bundler/update_checker/force_updater.rb index 4b1be234984..c14558c41d9 100644 --- a/bundler/lib/dependabot/bundler/update_checker/force_updater.rb +++ b/bundler/lib/dependabot/bundler/update_checker/force_updater.rb @@ -1,29 +1,34 @@ # frozen_string_literal: true -require "dependabot/monkey_patches/bundler/definition_ruby_version_patch" -require "dependabot/monkey_patches/bundler/definition_bundler_version_patch" -require "dependabot/monkey_patches/bundler/git_source_patch" - +require "dependabot/bundler/file_parser" +require "dependabot/bundler/file_updater/lockfile_updater" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" require "dependabot/bundler/update_checker" require "dependabot/bundler/update_checker/requirements_updater" -require "dependabot/bundler/file_updater/lockfile_updater" -require "dependabot/bundler/file_parser" -require "dependabot/shared_helpers" require "dependabot/errors" +require "dependabot/shared_helpers" module Dependabot module Bundler class UpdateChecker class ForceUpdater - def initialize(dependency:, dependency_files:, credentials:, - target_version:, requirements_update_strategy:, - update_multiple_dependencies: true) + require_relative "shared_bundler_helpers" + include SharedBundlerHelpers + + def initialize(dependency:, dependency_files:, repo_contents_path: nil, + credentials:, target_version:, + requirements_update_strategy:, + update_multiple_dependencies: true, + options:) @dependency = dependency @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials @target_version = target_version @requirements_update_strategy = requirements_update_strategy @update_multiple_dependencies = update_multiple_dependencies + @options = options end def updated_dependencies @@ -32,161 +37,37 @@ def updated_dependencies private - attr_reader :dependency, :dependency_files, :credentials, - :target_version, :requirements_update_strategy + attr_reader :dependency, :dependency_files, :repo_contents_path, + :credentials, :target_version, :requirements_update_strategy, + :options def update_multiple_dependencies? @update_multiple_dependencies end def force_update - in_a_temporary_bundler_context do - other_updates = [] - - begin - definition = build_definition(other_updates: other_updates) - definition.resolve_remotely! - specs = definition.resolve - dependencies_from([dependency] + other_updates, specs) - rescue ::Bundler::VersionConflict => e - raise unless update_multiple_dependencies? - - # TODO: Not sure this won't unlock way too many things... - new_dependencies_to_unlock = - new_dependencies_to_unlock_from( - error: e, - already_unlocked: other_updates - ) - - raise if new_dependencies_to_unlock.none? - - other_updates += new_dependencies_to_unlock - retry - end - end - rescue SharedHelpers::ChildProcessFailed => e - raise_unresolvable_error(e) - end - - ######################### - # Bundler context setup # - ######################### - - def in_a_temporary_bundler_context - base_directory = dependency_files.first.directory - SharedHelpers.in_a_temporary_directory(base_directory) do - write_temporary_dependency_files - - SharedHelpers.in_a_forked_process do - # Remove installed gems from the default Rubygems index - ::Gem::Specification.all = - ::Gem::Specification.send(:default_stubs, "*.gemspec") - - # Set flags and credentials - set_bundler_flags_and_credentials - - yield - end + in_a_native_bundler_context(error_handling: false) do |tmp_dir| + updated_deps, specs = NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "force_update", + options: options, + args: { + dir: tmp_dir, + dependency_name: dependency.name, + target_version: target_version, + credentials: credentials, + gemfile_name: gemfile.name, + lockfile_name: lockfile.name, + update_multiple_dependencies: update_multiple_dependencies? + } + ) + dependencies_from(updated_deps, specs) end - end - - def new_dependencies_to_unlock_from(error:, already_unlocked:) - potentials_deps = - relevant_conflicts(error, already_unlocked). - flat_map(&:requirement_trees). - reject do |tree| - # If the final requirement wasn't specific, it can't be binding - next true if tree.last.requirement == Gem::Requirement.new(">= 0") - - # If the conflict wasn't for the dependency we're updating then - # we don't have enough info to reject it - next false unless tree.last.name == dependency.name - - # If the final requirement *was* for the dependency we're updating - # then we can ignore the tree if it permits the target version - tree.last.requirement.satisfied_by?( - Gem::Version.new(target_version) - ) - end.map(&:first) - - potentials_deps. - reject { |dep| already_unlocked.map(&:name).include?(dep.name) }. - reject { |dep| [dependency.name, "ruby\0"].include?(dep.name) }. - uniq - end - - def relevant_conflicts(error, dependencies_being_unlocked) - names = [*dependencies_being_unlocked.map(&:name), dependency.name] - - # For a conflict to be relevant to the updates we're making it must be - # 1) caused by a new requirement introduced by our unlocking, or - # 2) caused by an old requirement that prohibits the update. - # Hence, we look at the beginning and end of the requirement trees - error.cause.conflicts.values. - select do |conflict| - conflict.requirement_trees.any? do |t| - names.include?(t.last.name) || names.include?(t.first.name) - end - end - end - - def raise_unresolvable_error(error) - msg = error.error_class + " with message: " + error.error_message + rescue SharedHelpers::HelperSubprocessFailed => e + msg = e.error_class + " with message: " + e.message raise Dependabot::DependencyFileNotResolvable, msg end - def build_definition(other_updates:) - gems_to_unlock = other_updates.map(&:name) + [dependency.name] - definition = ::Bundler::Definition.build( - gemfile.name, - lockfile&.name, - gems: gems_to_unlock + subdependencies, - lock_shared_dependencies: true - ) - - # Remove the Gemfile / gemspec requirements on the gems we're - # unlocking (i.e., completely unlock them) - gems_to_unlock.each do |gem_name| - unlock_gem(definition: definition, gem_name: gem_name) - end - - # Set the requirement for the gem we're forcing an update of - new_req = Gem::Requirement.create("= #{target_version}") - definition.dependencies. - find { |d| d.name == dependency.name }. - tap do |dep| - dep.instance_variable_set(:@requirement, new_req) - dep.source = nil if dep.source.is_a?(::Bundler::Source::Git) - end - - definition - end - - def subdependencies - # If there's no lockfile we don't need to worry about - # subdependencies - return [] unless lockfile - - all_deps = ::Bundler::LockfileParser.new(sanitized_lockfile_body). - specs.map(&:name).map(&:to_s) - top_level = ::Bundler::Definition. - build(gemfile.name, lockfile.name, {}). - dependencies.map(&:name).map(&:to_s) - - all_deps - top_level - end - - def unlock_gem(definition:, gem_name:) - dep = definition.dependencies.find { |d| d.name == gem_name } - version = definition.locked_gems.specs. - find { |d| d.name == gem_name }.version - - dep&.instance_variable_set( - :@requirement, - Gem::Requirement.create(">= #{version}") - ) - end - def original_dependencies @original_dependencies ||= FileParser.new( @@ -204,28 +85,28 @@ def dependencies_from(updated_deps, specs) # # This is kind of a bug in Bundler, and we should try to fix it, # but resolving it won't necessarily be easy. - updated_deps.map do |dep| + updated_deps.filter_map do |dep| original_dep = - original_dependencies.find { |d| d.name == dep.name } - spec = specs.find { |d| d.name == dep.name } + original_dependencies.find { |d| d.name == dep.fetch("name") } + spec = specs.find { |d| d.fetch("name") == dep.fetch("name") } - next if spec.version.to_s == original_dep.version + next if spec.fetch("version") == original_dep.version build_dependency(original_dep, spec) - end.compact + end end def build_dependency(original_dep, updated_spec) Dependency.new( - name: updated_spec.name, - version: updated_spec.version.to_s, + name: updated_spec.fetch("name"), + version: updated_spec.fetch("version"), requirements: RequirementsUpdater.new( requirements: original_dep.requirements, update_strategy: requirements_update_strategy, updated_source: source_for(original_dep), - latest_version: updated_spec.version.to_s, - latest_resolvable_version: updated_spec.version.to_s + latest_version: updated_spec.fetch("version"), + latest_resolvable_version: updated_spec.fetch("version") ).updated_requirements, previous_version: original_dep.version, previous_requirements: original_dep.requirements, @@ -264,49 +145,8 @@ def write_temporary_dependency_files File.write(lockfile.name, sanitized_lockfile_body) if lockfile end - def set_bundler_flags_and_credentials - # Set auth details - relevant_credentials.each do |cred| - token = cred["token"] || - "#{cred['username']}:#{cred['password']}" - - ::Bundler.settings.set_command_option( - cred.fetch("host"), - token.gsub("@", "%40F").gsub("?", "%3F") - ) - end - - # Only allow upgrades. Otherwise it's unlikely that this - # resolution will be found by the FileUpdater - ::Bundler.settings.set_command_option( - "only_update_to_newer_versions", - true - ) - - # Use HTTPS for GitHub if lockfile was generated by Bundler 2 - set_bundler_2_flags if using_bundler_2? - end - - def set_bundler_2_flags - ::Bundler.settings.set_command_option("forget_cli_options", "true") - ::Bundler.settings.set_command_option("github.https", "true") - end - - def relevant_credentials - credentials. - select { |cred| cred["password"] || cred["token"] }. - select do |cred| - next true if cred["type"] == "git_source" - next true if cred["type"] == "rubygems_server" - - false - end - end - - def using_bundler_2? - return unless lockfile - - lockfile.content.match?(/BUNDLED WITH\s+2/m) + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) end end end diff --git a/bundler/lib/dependabot/bundler/update_checker/latest_version_finder.rb b/bundler/lib/dependabot/bundler/update_checker/latest_version_finder.rb index 547a1a35e14..76396e8d11a 100644 --- a/bundler/lib/dependabot/bundler/update_checker/latest_version_finder.rb +++ b/bundler/lib/dependabot/bundler/update_checker/latest_version_finder.rb @@ -1,32 +1,30 @@ # frozen_string_literal: true -require "dependabot/monkey_patches/bundler/definition_ruby_version_patch" -require "dependabot/monkey_patches/bundler/definition_bundler_version_patch" -require "dependabot/monkey_patches/bundler/git_source_patch" - require "excon" require "dependabot/bundler/update_checker" +require "dependabot/update_checkers/version_filters" require "dependabot/bundler/requirement" require "dependabot/shared_helpers" require "dependabot/errors" +require "dependabot/bundler/update_checker/latest_version_finder/" \ + "dependency_source" module Dependabot module Bundler class UpdateChecker class LatestVersionFinder - require_relative "shared_bundler_helpers" - include SharedBundlerHelpers - - def initialize(dependency:, dependency_files:, credentials:, - ignored_versions:, raise_on_ignored: false, - security_advisories:) + def initialize(dependency:, dependency_files:, repo_contents_path: nil, + credentials:, ignored_versions:, raise_on_ignored: false, + security_advisories:, options:) @dependency = dependency @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials @ignored_versions = ignored_versions @raise_on_ignored = raise_on_ignored @security_advisories = security_advisories + @options = options end def latest_version_details @@ -39,15 +37,14 @@ def lowest_security_fix_version private - attr_reader :dependency, :dependency_files, :credentials, - :ignored_versions, :security_advisories + attr_reader :dependency, :dependency_files, :repo_contents_path, + :credentials, :ignored_versions, :security_advisories, + :options def fetch_latest_version_details - if dependency_source.is_a?(::Bundler::Source::Git) - return latest_git_version_details - end + return dependency_source.latest_git_version_details if dependency_source.git? - relevant_versions = registry_versions + relevant_versions = dependency_source.versions relevant_versions = filter_prerelease_versions(relevant_versions) relevant_versions = filter_ignored_versions(relevant_versions) @@ -55,11 +52,12 @@ def fetch_latest_version_details end def fetch_lowest_security_fix_version - return if dependency_source.is_a?(::Bundler::Source::Git) + return if dependency_source.git? - relevant_versions = registry_versions + relevant_versions = dependency_source.versions relevant_versions = filter_prerelease_versions(relevant_versions) - relevant_versions = filter_vulnerable_versions(relevant_versions) + relevant_versions = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(relevant_versions, + security_advisories) relevant_versions = filter_ignored_versions(relevant_versions) relevant_versions = filter_lower_versions(relevant_versions) @@ -74,121 +72,52 @@ def filter_prerelease_versions(versions_array) def filter_ignored_versions(versions_array) filtered = versions_array. - reject { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } } - if @raise_on_ignored && filtered.empty? && versions_array.any? + reject { |v| ignore_requirements.any? { |r| r.satisfied_by?(v) } } + if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(versions_array).any? raise AllVersionsIgnored end filtered end - def filter_vulnerable_versions(versions_array) - versions_array. - reject { |v| security_advisories.any? { |a| a.vulnerable?(v) } } - end - def filter_lower_versions(versions_array) - versions_array. - select { |version| version > Gem::Version.new(dependency.version) } - end - - def registry_versions - return rubygems_versions if dependency.name == "bundler" - return rubygems_versions unless dependency_source - return [] unless dependency_source.is_a?(::Bundler::Source::Rubygems) - - remote = dependency_source.remotes.first - return rubygems_versions if remote.nil? - return rubygems_versions if remote.to_s == "https://rubygems.org/" - - private_registry_versions - end - - def rubygems_versions - @rubygems_versions ||= - begin - response = Excon.get( - "https://rubygems.org/api/v1/versions/#{dependency.name}.json", - idempotent: true, - **SharedHelpers.excon_defaults - ) - - JSON.parse(response.body). - map { |d| Gem::Version.new(d["number"]) } - end - rescue JSON::ParserError, Excon::Error::Timeout - @rubygems_versions = [] - end + return versions_array unless dependency.numeric_version - def private_registry_versions - @private_registry_versions ||= - in_a_temporary_bundler_context do - dependency_source. - fetchers.flat_map do |fetcher| - fetcher. - specs_with_retry([dependency.name], dependency_source). - search_all(dependency.name) - end. - map(&:version) - end - end - - def latest_git_version_details - dependency_source_details = - dependency.requirements.map { |r| r.fetch(:source) }. - uniq.compact.first - - in_a_temporary_bundler_context do - SharedHelpers.with_git_configured(credentials: credentials) do - # Note: we don't set `ref`, as we want to unpin the dependency - source = ::Bundler::Source::Git.new( - "uri" => dependency_source_details[:url], - "branch" => dependency_source_details[:branch], - "name" => dependency.name, - "submodules" => true - ) - - # Tell Bundler we're fine with fetching the source remotely - source.instance_variable_set(:@allow_remote, true) - - spec = source.specs.first - { version: spec.version, commit_sha: spec.source.revision } - end - end + versions_array. + select { |version| version > dependency.numeric_version } end def wants_prerelease? @wants_prerelease ||= begin - current_version = dependency.version - if current_version && Gem::Version.correct?(current_version) && - Gem::Version.new(current_version).prerelease? - return true - end - - dependency.requirements.any? do |req| - req[:requirement].match?(/[a-z]/i) + current_version = dependency.numeric_version + if current_version&.prerelease? + true + else + dependency.requirements.any? do |req| + req[:requirement].match?(/[a-z]/i) + end end end end def dependency_source - return nil unless gemfile - - @dependency_source ||= - in_a_temporary_bundler_context do - definition = ::Bundler::Definition.build(gemfile.name, nil, {}) - - specified_source = - definition.dependencies. - find { |dep| dep.name == dependency.name }&.source + @dependency_source ||= DependencySource.new( + dependency: dependency, + dependency_files: dependency_files, + credentials: credentials, + options: options + ) + end - specified_source || definition.send(:sources).default_source - end + def ignore_requirements + ignored_versions.flat_map { |req| requirement_class.requirements_array(req) } end - def ignore_reqs - ignored_versions.map { |req| Gem::Requirement.new(req.split(",")) } + def requirement_class + Utils.requirement_class_for_package_manager( + dependency.package_manager + ) end def gemfile diff --git a/bundler/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb b/bundler/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb new file mode 100644 index 00000000000..9ee33310020 --- /dev/null +++ b/bundler/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require "dependabot/registry_client" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" + +module Dependabot + module Bundler + class UpdateChecker + class LatestVersionFinder + class DependencySource + require_relative "../shared_bundler_helpers" + include SharedBundlerHelpers + + RUBYGEMS = "rubygems" + PRIVATE_REGISTRY = "private" + GIT = "git" + OTHER = "other" + + attr_reader :dependency, :dependency_files, :repo_contents_path, + :credentials, :options + + def initialize(dependency:, + dependency_files:, + credentials:, + options:) + @dependency = dependency + @dependency_files = dependency_files + @credentials = credentials + @options = options + end + + # The latest version details for the dependency from a registry + # + # @return [Array] + def versions + return rubygems_versions if dependency.name == "bundler" + return rubygems_versions unless gemfile + + case source_type + when OTHER, GIT + [] + when PRIVATE_REGISTRY + private_registry_versions + else + rubygems_versions + end + end + + # The latest version details for the dependency from a git repo + # + # @return [Hash{Symbol => String}, nil] + def latest_git_version_details + return unless git? + + source_details = + dependency.requirements.map { |r| r.fetch(:source) }. + uniq.compact.first + + SharedHelpers.with_git_configured(credentials: credentials) do + in_a_native_bundler_context do |tmp_dir| + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "depencency_source_latest_git_version", + options: options, + args: { + dir: tmp_dir, + gemfile_name: gemfile.name, + dependency_name: dependency.name, + credentials: credentials, + dependency_source_url: source_details[:url], + dependency_source_branch: source_details[:branch] + } + ) + end + end.transform_keys(&:to_sym) + end + + def git? + source_type == GIT + end + + private + + def rubygems_versions + @rubygems_versions ||= + begin + response = Dependabot::RegistryClient.get( + url: dependency_rubygems_uri + ) + + JSON.parse(response.body). + map { |d| Gem::Version.new(d["number"]) } + end + rescue JSON::ParserError, Excon::Error::Timeout + @rubygems_versions = [] + end + + def dependency_rubygems_uri + "https://rubygems.org/api/v1/versions/#{dependency.name}.json" + end + + def private_registry_versions + @private_registry_versions ||= + in_a_native_bundler_context do |tmp_dir| + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "private_registry_versions", + options: options, + args: { + dir: tmp_dir, + gemfile_name: gemfile.name, + dependency_name: dependency.name, + credentials: credentials + } + ).map do |version_string| + Gem::Version.new(version_string) + end + end + end + + def source_type + return @source_type if defined? @source_type + return @source_type = RUBYGEMS unless gemfile + + @source_type = in_a_native_bundler_context do |tmp_dir| + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "dependency_source_type", + options: options, + args: { + dir: tmp_dir, + gemfile_name: gemfile.name, + dependency_name: dependency.name, + credentials: credentials + } + ) + end + end + + def gemfile + dependency_files.find { |f| f.name == "Gemfile" } || + dependency_files.find { |f| f.name == "gems.rb" } + end + + def lockfile + dependency_files.find { |f| f.name == "Gemfile.lock" } || + dependency_files.find { |f| f.name == "gems.locked" } + end + + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) + end + end + end + end + end +end diff --git a/bundler/lib/dependabot/bundler/update_checker/requirements_updater.rb b/bundler/lib/dependabot/bundler/update_checker/requirements_updater.rb index a7cd7bdd1c0..9ae4bd1e051 100644 --- a/bundler/lib/dependabot/bundler/update_checker/requirements_updater.rb +++ b/bundler/lib/dependabot/bundler/update_checker/requirements_updater.rb @@ -28,7 +28,7 @@ def initialize(requirements:, update_strategy:, updated_source:, def updated_requirements requirements.map do |req| - if req[:file].match?(/\.gemspec/) + if req[:file].include?(".gemspec") update_gemspec_requirement(req) else # If a requirement doesn't come from a gemspec, it must be from @@ -101,7 +101,7 @@ def update_gemfile_range(requirements) when "!=" [] else - raise "Unexpected operation for unsatisfied Gemfile "\ + raise "Unexpected operation for unsatisfied Gemfile " \ "requirement: #{op}" end end @@ -142,7 +142,8 @@ def update_gemspec_requirement(req) next r if requirement_satisfied?(r, req[:groups]) if req[:groups] == ["development"] then bumped_requirements(r) - else widened_requirements(r) + else + widened_requirements(r) end end @@ -188,7 +189,7 @@ def widened_requirements(req) req end when "<", "<=" then [update_greatest_version(req, latest_version)] - when "~>" then convert_twidle_to_range(req, latest_version) + when "~>" then convert_twiddle_to_range(req, latest_version) when "!=" then [] when ">", ">=" then raise UnfixableRequirement else raise "Unexpected operation for requirement: #{op}" @@ -214,7 +215,7 @@ def bumped_requirements(req) end end - def convert_twidle_to_range(requirement, version_to_be_permitted) + def convert_twiddle_to_range(requirement, version_to_be_permitted) version = requirement.requirements.first.last version = version.release if version.prerelease? @@ -228,9 +229,7 @@ def convert_twidle_to_range(requirement, version_to_be_permitted) lb_segments = version.segments lb_segments.pop while lb_segments.any? && lb_segments.last.zero? - if lb_segments.none? - return [Gem::Requirement.new("< #{ub_segments.join('.')}")] - end + return [Gem::Requirement.new("< #{ub_segments.join('.')}")] if lb_segments.none? # Ensure versions have the same length as each other (cosmetic) length = [lb_segments.count, ub_segments.count].max @@ -252,11 +251,8 @@ def update_twiddle_version(requirement, version_to_be_permitted) # Updates the version in a "<" or "<=" constraint to allow the given # version - # rubocop:disable Metrics/PerceivedComplexity def update_greatest_version(requirement, version_to_be_permitted) - if version_to_be_permitted.is_a?(String) - version_to_be_permitted = Gem::Version.new(version_to_be_permitted) - end + version_to_be_permitted = Gem::Version.new(version_to_be_permitted) if version_to_be_permitted.is_a?(String) op, version = requirement.requirements.first version = version.release if version.prerelease? @@ -272,14 +268,13 @@ def update_greatest_version(requirement, version_to_be_permitted) version_to_be_permitted.segments[index] + 1 elsif index > version_to_be_permitted.segments.count - 1 nil - else 0 + else + 0 end end.compact Gem::Requirement.new("#{op} #{new_segments.join('.')}") end - - # rubocop:enable Metrics/PerceivedComplexity end end end diff --git a/bundler/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb b/bundler/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb index efb38d0d636..213011e1fd1 100644 --- a/bundler/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb +++ b/bundler/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require "dependabot/monkey_patches/bundler/definition_ruby_version_patch" -require "dependabot/monkey_patches/bundler/definition_bundler_version_patch" -require "dependabot/monkey_patches/bundler/git_source_patch" - require "excon" +require "uri" require "dependabot/bundler/update_checker" +require "dependabot/bundler/native_helpers" +require "dependabot/bundler/helpers" +require "dependabot/registry_client" require "dependabot/shared_helpers" require "dependabot/errors" @@ -14,9 +14,17 @@ module Dependabot module Bundler class UpdateChecker module SharedBundlerHelpers - GIT_REGEX = /reset --hard [^\s]*` in directory (?[^\s]*)/.freeze - GIT_REF_REGEX = /not exist in the repository (?[^\s]*)\./.freeze - PATH_REGEX = /The path `(?.*)` does not exist/.freeze + GIT_REGEX = /reset --hard [^\s]*` in directory (?[^\s]*)/ + GIT_REF_REGEX = /not exist in the repository (?[^\s]*)\./ + PATH_REGEX = /The path `(?.*)` does not exist/ + + module BundlerErrorPatterns + MISSING_AUTH_REGEX = /bundle config (?.*) username:password/ + BAD_AUTH_REGEX = /Bad username or password for (?.*)\.$/ + BAD_CERT_REGEX = /verify the SSL certificate for (?.*)\.$/ + HTTP_ERR_REGEX = /Could not fetch specs from (?.*)$/ + end + RETRYABLE_ERRORS = %w( Bundler::HTTPError Bundler::Fetcher::FallbackError @@ -29,36 +37,24 @@ module SharedBundlerHelpers Bundler::Fetcher::FallbackError ).freeze - attr_reader :dependency_files, :credentials + attr_reader :dependency_files, :repo_contents_path, :credentials ######################### # Bundler context setup # ######################### - def in_a_temporary_bundler_context(error_handling: true) - SharedHelpers.in_a_temporary_directory(base_directory) do |tmp_dir| + def in_a_native_bundler_context(error_handling: true) + SharedHelpers. + in_a_temporary_repo_directory(base_directory, + repo_contents_path) do |tmp_dir| write_temporary_dependency_files - SharedHelpers.in_a_forked_process do - # Set the path for path gemspec correctly - ::Bundler.instance_variable_set(:@root, tmp_dir) - - # Remove installed gems from the default Rubygems index - ::Gem::Specification.all = - ::Gem::Specification.send(:default_stubs, "*.gemspec") - - # Set flags and credentials - set_bundler_flags_and_credentials - - yield - end + yield(tmp_dir) end - rescue SharedHelpers::ChildProcessFailed, ArgumentError => e + rescue SharedHelpers::HelperSubprocessFailed => e retry_count ||= 0 retry_count += 1 - if retryable_error?(e) && retry_count <= 2 - sleep(rand(1.0..5.0)) && retry - end + sleep(rand(1.0..5.0)) && retry if retryable_error?(e) && retry_count <= 2 error_handling ? handle_bundler_errors(e) : raise end @@ -68,13 +64,10 @@ def base_directory end def retryable_error?(error) - return true if error.message == "marshal data too short" - return false if error.is_a?(ArgumentError) + return true if error.error_class == "JSON::ParserError" return true if RETRYABLE_ERRORS.include?(error.error_class) - unless RETRYABLE_PRIVATE_REGISTRY_ERRORS.include?(error.error_class) - return false - end + return false unless RETRYABLE_PRIVATE_REGISTRY_ERRORS.include?(error.error_class) private_registry_credentials.any? end @@ -84,13 +77,12 @@ def retryable_error?(error) # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/MethodLength def handle_bundler_errors(error) - if error.message == "marshal data too short" + if error.error_class == "JSON::ParserError" msg = "Error evaluating your dependency files: #{error.message}" raise Dependabot::DependencyFileNotEvaluatable, msg end - raise if error.is_a?(ArgumentError) - msg = error.error_class + " with message: " + error.error_message + msg = error.error_class + " with message: " + error.message case error.error_class when "Bundler::Dsl::DSLError", "Bundler::GemspecError" @@ -98,28 +90,30 @@ def handle_bundler_errors(error) raise Dependabot::DependencyFileNotEvaluatable, msg when "Bundler::Source::Git::MissingGitRevisionError" gem_name = - error.error_message.match(GIT_REF_REGEX). + error.message.match(GIT_REF_REGEX). named_captures["path"]. split("/").last raise GitDependencyReferenceNotFound, gem_name when "Bundler::PathError" gem_name = - error.error_message.match(PATH_REGEX). + error.message.match(PATH_REGEX). named_captures["path"]. split("/").last.split("-")[0..-2].join raise Dependabot::PathDependenciesNotReachable, [gem_name] when "Bundler::Source::Git::GitCommandError" - if error.error_message.match?(GIT_REGEX) + if error.message.match?(GIT_REGEX) # We couldn't find the specified branch / commit (or the two # weren't compatible). gem_name = - error.error_message.match(GIT_REGEX). + error.message.match(GIT_REGEX). named_captures["path"]. split("/").last.split("-")[0..-2].join raise GitDependencyReferenceNotFound, gem_name end - bad_uris = inaccessible_git_dependencies.map { |s| s.source.uri } + bad_uris = inaccessible_git_dependencies.map do |spec| + spec.fetch("uri") + end raise unless bad_uris.any? # We don't have access to one of repos required @@ -132,29 +126,32 @@ def handle_bundler_errors(error) # - the gem was specified at an incompatible version raise Dependabot::DependencyFileNotResolvable, msg when "Bundler::Fetcher::AuthenticationRequiredError" - regex = /bundle config (?.*) username:password/ - source = error.error_message.match(regex)[:source] + regex = BundlerErrorPatterns::MISSING_AUTH_REGEX + source = error.message.match(regex)[:source] raise Dependabot::PrivateSourceAuthenticationFailure, source when "Bundler::Fetcher::BadAuthenticationError" - regex = /Bad username or password for (?.*)\.$/ - source = error.error_message.match(regex)[:source] + regex = BundlerErrorPatterns::BAD_AUTH_REGEX + source = error.message.match(regex)[:source] raise Dependabot::PrivateSourceAuthenticationFailure, source when "Bundler::Fetcher::CertificateFailureError" - regex = /verify the SSL certificate for (?.*)\.$/ - source = error.error_message.match(regex)[:source] + regex = BundlerErrorPatterns::BAD_CERT_REGEX + source = error.message.match(regex)[:source] raise Dependabot::PrivateSourceCertificateFailure, source when "Bundler::HTTPError" - regex = /Could not fetch specs from (?.*)$/ - if error.error_message.match?(regex) - source = error.error_message.match(regex)[:source] - raise if source.end_with?("rubygems.org/") + regex = BundlerErrorPatterns::HTTP_ERR_REGEX + if error.message.match?(regex) + source = error.message.match(regex)[:source] + raise if [ + "rubygems.org", + "www.rubygems.org" + ].include?(URI(source).host) raise Dependabot::PrivateSourceTimedOut, source end # JFrog can serve a 403 if the credentials provided are good but # don't have access to a particular gem. - raise unless error.error_message.include?("permitted to deploy") + raise unless error.message.include?("permitted to deploy") raise unless jfrog_source raise Dependabot::PrivateSourceAuthenticationFailure, jfrog_source @@ -167,39 +164,44 @@ def handle_bundler_errors(error) # rubocop:enable Metrics/MethodLength def inaccessible_git_dependencies - in_a_temporary_bundler_context(error_handling: false) do - ::Bundler::Definition.build(gemfile.name, nil, {}).dependencies. - reject do |spec| - next true unless spec.source.is_a?(::Bundler::Source::Git) - - # Piggy-back off some private Bundler methods to configure the - # URI with auth details in the same way Bundler does. - git_proxy = spec.source.send(:git_proxy) - uri = spec.source.uri.gsub("git://", "https://") - uri = git_proxy.send(:configured_uri_for, uri) - uri += ".git" unless uri.end_with?(".git") - uri += "/info/refs?service=git-upload-pack" - - begin - Excon.get( - uri, - idempotent: true, - **SharedHelpers.excon_defaults - ).status == 200 - rescue Excon::Error::Socket, Excon::Error::Timeout - false - end - end + in_a_native_bundler_context(error_handling: false) do |tmp_dir| + git_specs = NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "git_specs", + options: options, + args: { + dir: tmp_dir, + gemfile_name: gemfile.name, + credentials: credentials + } + ) + git_specs.reject do |spec| + uri = URI.parse(spec.fetch("auth_uri")) + next false unless uri.scheme&.match?(/https?/o) + + Dependabot::RegistryClient.get( + url: uri.to_s + ).status == 200 + rescue Excon::Error::Socket, Excon::Error::Timeout + false + end end end def jfrog_source - in_a_temporary_bundler_context(error_handling: false) do - ::Bundler::Definition.build(gemfile.name, nil, {}). - send(:sources). - rubygems_remotes. - find { |uri| uri.host.include?("jfrog") }&. - host + return @jfrog_source unless defined?(@jfrog_source) + + @jfrog_source = in_a_native_bundler_context(error_handling: false) do |dir| + NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "jfrog_source", + options: options, + args: { + dir: dir, + gemfile_name: gemfile.name, + credentials: credentials + } + ) end end @@ -210,35 +212,7 @@ def write_temporary_dependency_files File.write(path, file.content) end - File.write(lockfile.name, sanitized_lockfile_body) if lockfile - end - - def set_bundler_flags_and_credentials - # Set auth details - relevant_credentials.each do |cred| - token = cred["token"] || - "#{cred['username']}:#{cred['password']}" - - ::Bundler.settings.set_command_option( - cred.fetch("host"), - token.gsub("@", "%40F").gsub("?", "%3F") - ) - end - - # Use HTTPS for GitHub if lockfile was generated by Bundler 2 - set_bundler_2_flags if using_bundler_2? - end - - def set_bundler_2_flags - ::Bundler.settings.set_command_option("forget_cli_options", "true") - ::Bundler.settings.set_command_option("github.https", "true") - end - - def relevant_credentials - [ - *git_source_credentials, - *private_registry_credentials - ].select { |cred| cred["password"] || cred["token"] } + File.write(lockfile.name, lockfile.content) if lockfile end def private_registry_credentials @@ -246,12 +220,6 @@ def private_registry_credentials select { |cred| cred["type"] == "rubygems_server" } end - def git_source_credentials - credentials. - select { |cred| cred["password"] || cred["token"] }. - select { |cred| cred["type"] == "git_source" } - end - def gemfile dependency_files.find { |f| f.name == "Gemfile" } || dependency_files.find { |f| f.name == "gems.rb" } @@ -261,17 +229,6 @@ def lockfile dependency_files.find { |f| f.name == "Gemfile.lock" } || dependency_files.find { |f| f.name == "gems.locked" } end - - def sanitized_lockfile_body - re = FileUpdater::LockfileUpdater::LOCKFILE_ENDING - lockfile.content.gsub(re, "") - end - - def using_bundler_2? - return unless lockfile - - lockfile.content.match?(/BUNDLED WITH\s+2/m) - end end end end diff --git a/bundler/lib/dependabot/bundler/update_checker/version_resolver.rb b/bundler/lib/dependabot/bundler/update_checker/version_resolver.rb index 856dde1ed71..283be50d497 100644 --- a/bundler/lib/dependabot/bundler/update_checker/version_resolver.rb +++ b/bundler/lib/dependabot/bundler/update_checker/version_resolver.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true -require "dependabot/monkey_patches/bundler/definition_ruby_version_patch" -require "dependabot/monkey_patches/bundler/definition_bundler_version_patch" -require "dependabot/monkey_patches/bundler/git_source_patch" - require "excon" +require "dependabot/bundler/helpers" require "dependabot/bundler/update_checker" require "dependabot/bundler/file_updater/lockfile_updater" require "dependabot/bundler/requirement" +require "dependabot/registry_client" require "dependabot/shared_helpers" require "dependabot/errors" @@ -21,23 +19,24 @@ class VersionResolver require_relative "shared_bundler_helpers" include SharedBundlerHelpers - GEM_NOT_FOUND_ERROR_REGEX = /locked to (?[^\s]+) \(/.freeze - def initialize(dependency:, unprepared_dependency_files:, - credentials:, ignored_versions:, + repo_contents_path: nil, credentials:, ignored_versions:, raise_on_ignored: false, replacement_git_pin: nil, remove_git_source: false, unlock_requirement: true, - latest_allowable_version: nil) + latest_allowable_version: nil, + options:) @dependency = dependency @unprepared_dependency_files = unprepared_dependency_files @credentials = credentials + @repo_contents_path = repo_contents_path @ignored_versions = ignored_versions @raise_on_ignored = raise_on_ignored @replacement_git_pin = replacement_git_pin @remove_git_source = remove_git_source @unlock_requirement = unlock_requirement @latest_allowable_version = latest_allowable_version + @options = options end def latest_resolvable_version_details @@ -47,9 +46,10 @@ def latest_resolvable_version_details private - attr_reader :dependency, :unprepared_dependency_files, :credentials, - :ignored_versions, :replacement_git_pin, - :latest_allowable_version + attr_reader :dependency, :unprepared_dependency_files, + :repo_contents_path, :credentials, :ignored_versions, + :replacement_git_pin, :latest_allowable_version, + :options def remove_git_source? @remove_git_source @@ -76,42 +76,47 @@ def fetch_latest_resolvable_version_details return latest_version_details unless gemfile SharedHelpers.with_git_configured(credentials: credentials) do - in_a_temporary_bundler_context do - dep = dependency_from_definition - - # If the dependency wasn't found in the definition, but *is* - # included in a gemspec, it's because the Gemfile didn't import - # the gemspec. This is unusual, but the correct behaviour if/when - # it happens is to behave as if the repo was gemspec-only. - if dep.nil? && dependency.requirements.any? - next latest_version_details - end - - # Otherwise, if the dependency wasn't found it's because it is a - # subdependency that was removed when attempting to update it. - next nil if dep.nil? - - # If the dependency is Bundler itself then we can't trust the - # version that has been returned (it's the version Dependabot is - # running on, rather than the true latest resolvable version). - next nil if dep.name == "bundler" - - # If the old Gemfile index was used then it won't have checked - # Ruby compatibility. Fix that by doing the check manually (and - # saying no update is possible if the Ruby version is a mismatch) - next nil if ruby_version_incompatible?(dep) - - details = { version: dep.version } - if dep.source.instance_of?(::Bundler::Source::Git) - details[:commit_sha] = dep.source.revision + # We do not want the helper to handle errors for us as there are + # some errors we want to handle specifically ourselves, including + # potentially retrying in the case of the Ruby version being locked + in_a_native_bundler_context(error_handling: false) do |tmp_dir| + details = NativeHelpers.run_bundler_subprocess( + bundler_version: bundler_version, + function: "resolve_version", + options: options, + args: { + dependency_name: dependency.name, + dependency_requirements: dependency.requirements, + gemfile_name: gemfile.name, + lockfile_name: lockfile&.name, + dir: tmp_dir, + credentials: credentials + } + ) + + return latest_version_details if details == "latest" + + if details + details.transform_keys!(&:to_sym) + + # If the old Gemfile index was used then it won't have checked + # Ruby compatibility. Fix that by doing the check manually and + # saying no update is possible if the Ruby version is a + # mismatch + return nil if ruby_version_incompatible?(details) + + details[:version] = Gem::Version.new(details[:version]) end details end end - rescue Dependabot::DependencyFileNotResolvable => e + rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e return if error_due_to_restrictive_upper_bound?(e) return if circular_dependency_at_new_version?(e) - raise unless ruby_lock_error?(e) + + # If we are unable to handle the error ourselves, pass it on to the + # general bundler error handling. + handle_bundler_errors(e) unless ruby_lock_error?(e) @gemspec_ruby_unlocked = true regenerate_dependency_files_without_ruby_lock && retry @@ -119,7 +124,7 @@ def fetch_latest_resolvable_version_details # rubocop:enable Metrics/PerceivedComplexity def circular_dependency_at_new_version?(error) - return false unless error.message.include?("CyclicDependencyError") + return false unless error.error_class.include?("CyclicDependencyError") error.message.include?("'#{dependency.name}'") end @@ -135,7 +140,8 @@ def error_due_to_restrictive_upper_bound?(error) end def ruby_lock_error?(error) - return false unless error.message.include?(" for gem \"ruby\0\"") + return false unless error.message.include?(" for the Ruby\0 version") || # Bundler 2 + error.message.include?(" for gem \"ruby\0\"") # Bundler 1 return false if @gemspec_ruby_unlocked dependency_files.any? { |f| f.name.end_with?(".gemspec") } @@ -154,73 +160,29 @@ def regenerate_dependency_files_without_ruby_lock ).prepared_dependency_files end - # rubocop:disable Metrics/PerceivedComplexity - def dependency_from_definition(unlock_subdependencies: true) - dependencies_to_unlock = [dependency.name] - dependencies_to_unlock += subdependencies if unlock_subdependencies - begin - definition = build_definition(dependencies_to_unlock) - definition.resolve_remotely! - rescue ::Bundler::GemNotFound => e - unlock_yanked_gem(dependencies_to_unlock, e) && retry - rescue ::Bundler::HTTPError => e - # Retry network errors - attempt ||= 1 - attempt += 1 - raise if attempt > 3 || !e.message.include?("Network error") - - retry - end - - dep = definition.resolve.find { |d| d.name == dependency.name } - return dep if dep - return if dependency.requirements.any? || !unlock_subdependencies - - # If no definition was found and we're updating a sub-dependency, - # try again but without unlocking any other sub-dependencies - dependency_from_definition(unlock_subdependencies: false) - end - - # rubocop:enable Metrics/PerceivedComplexity - - def unlock_yanked_gem(dependencies_to_unlock, error) - raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX) - - gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX). - named_captures["name"] - raise if dependencies_to_unlock.include?(gem_name) - - dependencies_to_unlock << gem_name - end - - def subdependencies - # If there's no lockfile we don't need to worry about - # subdependencies - return [] unless lockfile - - all_deps = ::Bundler::LockfileParser.new(sanitized_lockfile_body). - specs.map(&:name).map(&:to_s).uniq - top_level = build_definition([]).dependencies. - map(&:name).map(&:to_s) - - all_deps - top_level + def latest_version_details + @latest_version_details ||= + LatestVersionFinder.new( + dependency: dependency, + dependency_files: dependency_files, + repo_contents_path: repo_contents_path, + credentials: credentials, + ignored_versions: ignored_versions, + raise_on_ignored: @raise_on_ignored, + security_advisories: [], + options: options + ).latest_version_details end - def ruby_version_incompatible?(dep) - return false unless dep.source.is_a?(::Bundler::Source::Rubygems) - - fetcher = dep.source.fetchers.first.fetchers.first - + def ruby_version_incompatible?(details) # It's only the old index we have a problem with - return false unless fetcher.is_a?(::Bundler::Fetcher::Dependency) + return false unless details[:fetcher] == "Bundler::Fetcher::Dependency" # If no Ruby version is specified, we don't have a problem - return false unless ruby_version + return false unless details[:ruby_version] - versions = Excon.get( - "#{fetcher.fetch_uri}api/v1/versions/#{dependency.name}.json", - idempotent: true, - **SharedHelpers.excon_defaults + versions = Dependabot::RegistryClient.get( + url: "https://rubygems.org/api/v1/versions/#{dependency.name}.json" ) # Give the benefit of the doubt if something goes wrong fetching @@ -229,52 +191,23 @@ def ruby_version_incompatible?(dep) ruby_requirement = JSON.parse(versions.body). - find { |details| details["number"] == dep.version.to_s }&. + find { |version| version["number"] == details[:version] }&. fetch("ruby_version", nil) # Give the benefit of the doubt if we can't find the version's # required Ruby version. return false unless ruby_requirement - ruby_requirement = Requirement.new(ruby_requirement) + ruby_requirement = Dependabot::Bundler::Requirement.new(ruby_requirement) + current_ruby_version = Dependabot::Bundler::Version.new(details[:ruby_version]) - !ruby_requirement.satisfied_by?(ruby_version) + !ruby_requirement.satisfied_by?(current_ruby_version) rescue JSON::ParserError, Excon::Error::Socket, Excon::Error::Timeout # Give the benefit of the doubt if something goes wrong fetching # version details (could be that it's a private index, etc.) false end - def build_definition(dependencies_to_unlock) - # Note: we lock shared dependencies to avoid any top-level - # dependencies getting unlocked (which would happen if they were - # also subdependencies of the dependency being unlocked) - ::Bundler::Definition.build( - gemfile.name, - lockfile&.name, - gems: dependencies_to_unlock, - lock_shared_dependencies: true - ) - end - - def ruby_version - return nil unless gemfile - - @ruby_version ||= build_definition([]).ruby_version&.gem_version - end - - def latest_version_details - @latest_version_details ||= - LatestVersionFinder.new( - dependency: dependency, - dependency_files: dependency_files, - credentials: credentials, - ignored_versions: ignored_versions, - raise_on_ignored: @raise_on_ignored, - security_advisories: [] - ).latest_version_details - end - def gemfile dependency_files.find { |f| f.name == "Gemfile" } || dependency_files.find { |f| f.name == "gems.rb" } @@ -285,9 +218,8 @@ def lockfile dependency_files.find { |f| f.name == "gems.locked" } end - def sanitized_lockfile_body - re = FileUpdater::LockfileUpdater::LOCKFILE_ENDING - lockfile.content.gsub(re, "") + def bundler_version + @bundler_version ||= Helpers.bundler_version(lockfile) end end end diff --git a/bundler/lib/dependabot/monkey_patches/bundler/definition_bundler_version_patch.rb b/bundler/lib/dependabot/monkey_patches/bundler/definition_bundler_version_patch.rb deleted file mode 100644 index 68f4840c259..00000000000 --- a/bundler/lib/dependabot/monkey_patches/bundler/definition_bundler_version_patch.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require "bundler/definition" - -# Ignore the Bundler version specified in the Gemfile (since the only Bundler -# version available to us is the one we're using). -module Bundler - class Definition - def expanded_dependencies - @expanded_dependencies ||= - expand_dependencies(dependencies + metadata_dependencies, @remote). - reject { |d| d.name == "bundler" } - end - end -end diff --git a/bundler/lib/dependabot/monkey_patches/bundler/definition_ruby_version_patch.rb b/bundler/lib/dependabot/monkey_patches/bundler/definition_ruby_version_patch.rb deleted file mode 100644 index 35b335f4e69..00000000000 --- a/bundler/lib/dependabot/monkey_patches/bundler/definition_ruby_version_patch.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module BundlerDefinitionRubyVersionPatch - def index - @index ||= super.tap do - if ruby_version - requested_version = ruby_version.to_gem_version_with_patchlevel - sources.metadata_source.specs << - Gem::Specification.new("ruby\0", requested_version) - end - - sources.metadata_source.specs << - Gem::Specification.new("ruby\0", "2.5.3p105") - end - end -end -Bundler::Definition.prepend(BundlerDefinitionRubyVersionPatch) diff --git a/bundler/lib/dependabot/monkey_patches/bundler/git_source_patch.rb b/bundler/lib/dependabot/monkey_patches/bundler/git_source_patch.rb deleted file mode 100644 index 785efc6806e..00000000000 --- a/bundler/lib/dependabot/monkey_patches/bundler/git_source_patch.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -module Bundler - class Source - class Git - class GitProxy - private - - # Bundler allows ssh authentication when talking to GitHub but there's - # no way for Dependabot to do so (it doesn't have any ssh keys). - # Instead, we convert all `git@github.com:` URLs to use HTTPS. - def configured_uri_for(uri) - uri = uri.gsub(%r{git@(.*?):/?}, 'https://\1/') - if uri.match?(/https?:/) - remote = URI(uri) - config_auth = - Bundler.settings[remote.to_s] || Bundler.settings[remote.host] - remote.userinfo ||= config_auth - remote.to_s - else - uri - end - end - end - end - end -end - -module Bundler - class Source - class Git < Path - private - - def serialize_gemspecs_in(destination) - original_load_paths = $LOAD_PATH.dup - reduced_load_paths = original_load_paths. - reject { |p| p.include?("/gems/") } - - $LOAD_PATH.shift until $LOAD_PATH.empty? - reduced_load_paths.each { |p| $LOAD_PATH << p } - - if destination.relative? - destination = destination.expand_path(Bundler.root) - end - Dir["#{destination}/#{@glob}"].each do |spec_path| - # Evaluate gemspecs and cache the result. Gemspecs - # in git might require git or other dependencies. - # The gemspecs we cache should already be evaluated. - spec = Bundler.load_gemspec(spec_path) - next unless spec - - Bundler.rubygems.set_installed_by_version(spec) - Bundler.rubygems.validate(spec) - File.open(spec_path, "wb") { |file| file.write(spec.to_ruby) } - end - $LOAD_PATH.shift until $LOAD_PATH.empty? - original_load_paths.each { |p| $LOAD_PATH << p } - end - end - end -end diff --git a/bundler/script/ci-test b/bundler/script/ci-test new file mode 100755 index 00000000000..49e6596e241 --- /dev/null +++ b/bundler/script/ci-test @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e + +bundle install +bundle exec rubocop . +bundle exec parallel_test spec/ -n "$CI_NODE_TOTAL" --only-group "$CI_NODE_INDEX" --group-by filesize --type rspec + +# NOTE: Don't use `if` branches without `else` part, since the code in some of +# then seems to not abort the script regardless of `set -e` + +# Should we only run these on one of the CI_NODE_INDEX's? +if [[ "$SUITE_NAME" == "bundler1" ]]; then + # shellcheck source=../helpers/v1/build + DEPENDABOT_NATIVE_HELPERS_PATH="" source helpers/v1/build \ + && BUNDLER_VERSION=1.17.3 bundle exec rspec spec\ + && cd - +else + # shellcheck source=../helpers/v2/build + DEPENDABOT_NATIVE_HELPERS_PATH="" source helpers/v2/build \ + && bundle exec rspec spec \ + && cd - +fi diff --git a/bundler/spec/dependabot/bundler/file_fetcher/child_gemfile_finder_spec.rb b/bundler/spec/dependabot/bundler/file_fetcher/child_gemfile_finder_spec.rb index 17444a54411..b3b28f06f5f 100644 --- a/bundler/spec/dependabot/bundler/file_fetcher/child_gemfile_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_fetcher/child_gemfile_finder_spec.rb @@ -8,28 +8,22 @@ RSpec.describe Dependabot::Bundler::FileFetcher::ChildGemfileFinder do let(:finder) { described_class.new(gemfile: gemfile) } - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: gemfile_name) - end - let(:gemfile_name) { "Gemfile" } - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:gemfile) { bundler_project_dependency_file("gemfile", filename: "Gemfile") } describe "#child_gemfile_paths" do subject(:child_gemfile_paths) { finder.child_gemfile_paths } context "when the file does not include any child Gemfiles" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:gemfile) { bundler_project_dependency_file("gemfile", filename: "Gemfile") } it { is_expected.to eq([]) } end context "when the file does include a child Gemfile" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "eval_gemfile") } + let(:gemfile) { bundler_project_dependency_file("eval_gemfile_gemfile", filename: "Gemfile") } it { is_expected.to eq(["backend/Gemfile"]) } context "whose path must be eval-ed" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "eval_gemfile_absolute") - end + let(:gemfile) { bundler_project_dependency_file("eval_gemfile_absolute", filename: "Gemfile") } it "raises a helpful error" do expect { finder.child_gemfile_paths }.to raise_error do |error| @@ -40,9 +34,7 @@ end context "that includes a variable" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "eval_gemfile_variable") - end + let(:gemfile) { bundler_project_dependency_file("eval_gemfile_variable", filename: "Gemfile") } it "raises a helpful error" do expect { finder.child_gemfile_paths }.to raise_error do |error| @@ -56,11 +48,16 @@ let(:gemfile_body) do "group :development do\neval_gemfile('some_gemfile')\nend" end + + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end + it { is_expected.to eq(["some_gemfile"]) } end context "with invalid Ruby in the Gemfile" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "invalid_ruby") } + let(:gemfile) { bundler_project_dependency_file("invalid_ruby", filename: "Gemfile") } it "raises a helpful error" do expect { finder.child_gemfile_paths }.to raise_error do |error| @@ -71,8 +68,7 @@ end context "when this Gemfile is already in a nested directory" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "eval_gemfile") } - let(:gemfile_name) { "nested/Gemfile" } + let(:gemfile) { bundler_project_dependency_file("eval_gemfile_nested", filename: "nested/Gemfile") } it { is_expected.to eq(["nested/backend/Gemfile"]) } end diff --git a/bundler/spec/dependabot/bundler/file_fetcher/gemspec_finder_spec.rb b/bundler/spec/dependabot/bundler/file_fetcher/gemspec_finder_spec.rb index 97948e80dd4..8e440c4dc5b 100644 --- a/bundler/spec/dependabot/bundler/file_fetcher/gemspec_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_fetcher/gemspec_finder_spec.rb @@ -8,22 +8,16 @@ RSpec.describe Dependabot::Bundler::FileFetcher::GemspecFinder do let(:finder) { described_class.new(gemfile: gemfile) } - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: gemfile_name) - end - let(:gemfile_name) { "Gemfile" } - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } - describe "#gemspec_directories" do subject(:gemspec_directories) { finder.gemspec_directories } context "when the file does not include any gemspecs" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:gemfile) { bundler_project_dependency_file("gemfile", filename: "Gemfile") } it { is_expected.to eq([]) } end context "with invalid Ruby in the Gemfile" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "invalid_ruby") } + let(:gemfile) { bundler_project_dependency_file("invalid_ruby", filename: "Gemfile") } it "raises a helpful error" do expect { finder.gemspec_directories }.to raise_error do |error| @@ -34,18 +28,19 @@ end context "when the file does include a gemspec reference" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "imports_gemspec") } + let(:gemfile) { bundler_project_dependency_file("imports_gemspec", filename: "Gemfile") } it { is_expected.to eq([Pathname.new(".")]) } context "that has a path specified" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "imports_gemspec_from_path") - end + let(:gemfile) { bundler_project_dependency_file("imports_gemspec_from_path", filename: "Gemfile") } it { is_expected.to eq([Pathname.new("subdir")]) } context "when this Gemfile is already in a nested directory" do - let(:gemfile_name) { "nested/Gemfile" } + let(:gemfile) do + bundler_project_dependency_file("imports_gemspec_from_nested_path", filename: "nested/Gemfile") + end + it { is_expected.to eq([Pathname.new("nested/subdir")]) } end end diff --git a/bundler/spec/dependabot/bundler/file_fetcher/path_gemspec_finder_spec.rb b/bundler/spec/dependabot/bundler/file_fetcher/path_gemspec_finder_spec.rb index 7ddea9ad0d0..baa691fa93d 100644 --- a/bundler/spec/dependabot/bundler/file_fetcher/path_gemspec_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_fetcher/path_gemspec_finder_spec.rb @@ -8,22 +8,17 @@ RSpec.describe Dependabot::Bundler::FileFetcher::PathGemspecFinder do let(:finder) { described_class.new(gemfile: gemfile) } - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: gemfile_name) - end - let(:gemfile_name) { "Gemfile" } - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:gemfile) { bundler_project_dependency_file("gemfile", filename: "Gemfile") } describe "#path_gemspec_paths" do subject(:path_gemspec_paths) { finder.path_gemspec_paths } context "when the file does not include any path gemspecs" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } it { is_expected.to eq([]) } end context "with invalid Ruby in the Gemfile" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "invalid_ruby") } + let(:gemfile) { bundler_project_dependency_file("invalid_ruby", filename: "Gemfile") } it "raises a helpful error" do expect { finder.path_gemspec_paths }.to raise_error do |error| @@ -34,11 +29,11 @@ end context "when the file does include a path gemspec" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "path_source") } + let(:gemfile) { bundler_project_dependency_file("path_source", filename: "Gemfile") } it { is_expected.to eq([Pathname.new("plugins/example")]) } context "whose path must be eval-ed" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "path_source_eval") } + let(:gemfile) { bundler_project_dependency_file("path_source_eval", filename: "Gemfile") } it "raises a helpful error" do expect { finder.path_gemspec_paths }.to raise_error do |error| @@ -49,13 +44,15 @@ end context "when this Gemfile is already in a nested directory" do - let(:gemfile_name) { "nested/Gemfile" } + let(:gemfile) do + bundler_project_dependency_file("nested_path_source", filename: "nested/Gemfile") + end it { is_expected.to eq([Pathname.new("nested/plugins/example")]) } end context "that is behind a conditional that is false" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "path_source_if") } + let(:gemfile) { bundler_project_dependency_file("path_source_if", filename: "Gemfile") } it { is_expected.to eq([Pathname.new("plugins/example")]) } end end diff --git a/bundler/spec/dependabot/bundler/file_fetcher/require_relative_finder_spec.rb b/bundler/spec/dependabot/bundler/file_fetcher/require_relative_finder_spec.rb index 4565ec90e8b..329b3f94484 100644 --- a/bundler/spec/dependabot/bundler/file_fetcher/require_relative_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_fetcher/require_relative_finder_spec.rb @@ -12,18 +12,17 @@ Dependabot::DependencyFile.new(content: file_body, name: file_name) end let(:file_name) { "Gemfile" } - let(:file_body) { fixture("ruby", "gemfiles", "includes_require_relative") } describe "#require_relative_paths" do subject(:require_relative_paths) { finder.require_relative_paths } context "when the file does not include any relative paths" do - let(:file_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:file_body) { bundler_project_dependency_file("gemfile", filename: "Gemfile").content } it { is_expected.to eq([]) } end context "with invalid Ruby in the Gemfile" do - let(:file_body) { fixture("ruby", "gemfiles", "invalid_ruby") } + let(:file_body) { bundler_project_dependency_file("invalid_ruby", filename: "Gemfile").content } it "raises a helpful error" do expect { finder.require_relative_paths }.to raise_error do |error| @@ -35,23 +34,29 @@ context "when the file does include a relative path" do let(:file_body) do - fixture("ruby", "gemfiles", "includes_require_relative") + bundler_project_dependency_file("includes_require_relative_gemfile", filename: "nested/Gemfile").content end it { is_expected.to eq(["../some_other_file.rb"]) } context "for a file that includes a .rb suffix" do - let(:file_body) { 'require_relative "../some_other_file.rb"' } + let(:file_body) do + 'require_relative "../some_other_file.rb"' + end it { is_expected.to eq(["../some_other_file.rb"]) } end # rubocop:disable Lint/InterpolationCheck context "that needs to be evaled" do - let(:file_body) { 'require_relative "./my_file_#{raise %(hell)}"' } + let(:file_body) do + 'require_relative "./my_file_#{raise %(hell)}"' + end it { is_expected.to eq([]) } context "but can't be" do - let(:file_body) { 'require_relative "./my_file_#{unknown_var}"' } + let(:file_body) do + 'require_relative "./my_file_#{unknown_var}"' + end it { is_expected.to eq([]) } end end diff --git a/bundler/spec/dependabot/bundler/file_fetcher_spec.rb b/bundler/spec/dependabot/bundler/file_fetcher_spec.rb index ab71581bffa..5c788defe94 100644 --- a/bundler/spec/dependabot/bundler/file_fetcher_spec.rb +++ b/bundler/spec/dependabot/bundler/file_fetcher_spec.rb @@ -199,12 +199,12 @@ context "with a file included with require_relative" do let(:directory) { "/Library/Homebrew/test" } let(:url) do - "https://api.github.com/repos/gocardless/bump/contents/Library/"\ - "Homebrew/test" + "https://api.github.com/repos/gocardless/bump/contents/Library/" \ + "Homebrew/test" end let(:imported_file_url) do - "https://api.github.com/repos/gocardless/bump/contents/Library/"\ - "Homebrew/constants.rb" + "https://api.github.com/repos/gocardless/bump/contents/Library/" \ + "Homebrew/constants.rb" end before do diff --git a/bundler/spec/dependabot/bundler/file_parser/file_preparer_spec.rb b/bundler/spec/dependabot/bundler/file_parser/file_preparer_spec.rb index ab68ba11ade..0000fd8c581 100644 --- a/bundler/spec/dependabot/bundler/file_parser/file_preparer_spec.rb +++ b/bundler/spec/dependabot/bundler/file_parser/file_preparer_spec.rb @@ -7,31 +7,30 @@ RSpec.describe Dependabot::Bundler::FileParser::FilePreparer do let(:preparer) { described_class.new(dependency_files: dependency_files) } - let(:dependency_files) { [gemfile, lockfile] } - - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") - end - let(:lockfile) do - Dependabot::DependencyFile.new(content: lockfile_body, name: "Gemfile.lock") - end - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } - let(:lockfile_body) { fixture("ruby", "lockfiles", "Gemfile.lock") } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } describe "#prepared_dependency_files" do subject(:prepared_dependency_files) { preparer.prepared_dependency_files } describe "the updated Gemfile" do subject { prepared_dependency_files.find { |f| f.name == "Gemfile" } } - its(:content) { is_expected.to eq(gemfile.content) } + its(:content) { is_expected.to include('gem "business", "~> 1.4.0"') } + end + + describe "the updated lockfile", :bundler_v1_only do + subject do + prepared_dependency_files.find { |f| f.name == "Gemfile.lock" } + end + + its(:content) { is_expected.to include("1.10.6") } end - describe "the updated lockfile" do + describe "the updated lockfile", :bundler_v2_only do subject do prepared_dependency_files.find { |f| f.name == "Gemfile.lock" } end - its(:content) { is_expected.to eq(lockfile.content) } + its(:content) { is_expected.to include("2.2.0") } end describe "the updated gemspec" do @@ -39,13 +38,7 @@ prepared_dependency_files.find { |f| f.name == "example.gemspec" } end - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", "with_require"), - name: "example.gemspec" - ) - end + let(:dependency_files) { bundler_project_dependency_files("gemfile_gemspec_with_require") } its(:content) { is_expected.to include("begin\nrequire ") } its(:content) { is_expected.to include(%(version = "0.0.1")) } @@ -56,31 +49,19 @@ prepared_dependency_files.find { |f| f.name == ".ruby-version" } end - let(:dependency_files) { [gemfile, lockfile, ruby_version] } - let(:ruby_version) do - Dependabot::DependencyFile.new( - content: "2.4.1", - name: ".ruby-version" - ) - end + let(:dependency_files) { bundler_project_dependency_files("ruby_version_file") } - its(:content) { is_expected.to eq(ruby_version.content) } + its(:content) { is_expected.to eq("2.2.0\n") } end describe "the updated .specification file" do subject do - prepared_dependency_files.find { |f| f.name == ".specification" } + prepared_dependency_files.find { |f| f.name == "plugins/example/.specification" } end - let(:dependency_files) { [gemfile, lockfile, specification] } - let(:specification) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "specifications", "statesman"), - name: ".specification" - ) - end + let(:dependency_files) { bundler_project_dependency_files("version_specified_gemfile_specification") } - its(:content) { is_expected.to eq(specification.content) } + its(:content) { is_expected.to start_with("--- !ruby/object:Gem::Specification") } end end end diff --git a/bundler/spec/dependabot/bundler/file_parser/gemfile_declaration_finder_spec.rb b/bundler/spec/dependabot/bundler/file_parser/gemfile_declaration_finder_spec.rb index c6774bfbca6..cb94bf6b0b8 100644 --- a/bundler/spec/dependabot/bundler/file_parser/gemfile_declaration_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_parser/gemfile_declaration_finder_spec.rb @@ -7,23 +7,25 @@ RSpec.describe Dependabot::Bundler::FileParser::GemfileDeclarationFinder do let(:checker) do - described_class.new(dependency: dependency, gemfile: gemfile) + described_class.new(gemfile: gemfile) end let(:dependency) do - ::Bundler::Dependency.new(dependency_name, dependency_requirement_sting) + dep = ::Bundler::Dependency.new(dependency_name, + dependency_requirement_sting) + { + "name" => dep.name, + "requirement" => dep.requirement.to_s + } end let(:dependency_name) { "business" } let(:dependency_requirement_sting) { "~> 1" } - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") - end - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:gemfile) { bundler_project_dependency_file("gemfile", filename: "Gemfile") } describe "#gemfile_includes_dependency?" do subject(:gemfile_includes_dependency) do - checker.gemfile_includes_dependency? + checker.gemfile_includes_dependency?(dependency) end context "when the file does not include the dependency" do @@ -32,7 +34,9 @@ end context "when the file is just comments" do - let(:gemfile_body) { "#Lol this is just a comment" } + let(:gemfile) do + Dependabot::DependencyFile.new(content: "#Lol this is just a comment", name: "Gemfile") + end it { is_expected.to eq(false) } end @@ -41,16 +45,14 @@ it { is_expected.to eq(true) } context "but it's in a source block" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "sidekiq_pro") } + let(:gemfile) { bundler_project_dependency_file("sidekiq_pro", filename: "Gemfile") } let(:dependency_name) { "sidekiq-pro" } it { is_expected.to eq(true) } end context "but it's in a group block" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "development_dependencies") - end + let(:gemfile) { bundler_project_dependency_file("development_dependencies", filename: "Gemfile") } let(:dependency_name) { "business" } it { is_expected.to eq(true) } @@ -59,7 +61,7 @@ end describe "#enhanced_req_string" do - subject(:enhanced_req_string) { checker.enhanced_req_string } + subject(:enhanced_req_string) { checker.enhanced_req_string(dependency) } context "when the file does not include the dependency" do let(:dependency_name) { "dependabot-core" } @@ -67,7 +69,10 @@ end context "when the file is just comments" do - let(:gemfile_body) { "#Lol this is just a comment" } + let(:gemfile) do + Dependabot::DependencyFile.new(content: "#Lol this is just a comment", name: "Gemfile") + end + it { is_expected.to be_nil } end @@ -77,12 +82,10 @@ it { is_expected.to eq("~> 1.4.0") } context "but doesn't specify a requirement" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "version_not_specified") - end + let(:gemfile) { bundler_project_dependency_file("version_not_specified", filename: "Gemfile") } let(:dependency_requirement_sting) { nil } - # Note: It would be equally valid to return `nil` here + # NOTE: It would be equally valid to return `nil` here it { is_expected.to eq(">= 0") } end @@ -97,9 +100,7 @@ end context "but it's using a version that would be transformed" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "prerelease_with_dash") - end + let(:gemfile) { bundler_project_dependency_file("prerelease_with_dash_gemfile", filename: "Gemfile") } let(:dependency_name) { "business" } let(:dependency_requirement_sting) { "~> 1.4.0.pre.rc1" } @@ -112,7 +113,7 @@ end context "but it's using a function version" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "function_version") } + let(:gemfile) { bundler_project_dependency_file("function_version_gemfile", filename: "Gemfile") } let(:dependency_name) { "business" } let(:dependency_requirement_sting) { "~> 1.0.0" } diff --git a/bundler/spec/dependabot/bundler/file_parser/gemspec_declaration_finder_spec.rb b/bundler/spec/dependabot/bundler/file_parser/gemspec_declaration_finder_spec.rb new file mode 100644 index 00000000000..cda5b07d302 --- /dev/null +++ b/bundler/spec/dependabot/bundler/file_parser/gemspec_declaration_finder_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/dependency" +require "dependabot/dependency_file" +require "dependabot/bundler/file_parser/gemspec_declaration_finder" + +RSpec.describe Dependabot::Bundler::FileParser::GemspecDeclarationFinder do + let(:checker) do + described_class.new(gemspec: gemspec) + end + + let(:dependency) do + dep = ::Bundler::Dependency.new(dependency_name, + dependency_requirement_sting) + { + "name" => dep.name, + "requirement" => dep.requirement.to_s + } + end + let(:dependency_name) { "business" } + let(:dependency_requirement_sting) { "~> 1" } + + let(:gemspec) { bundler_project_dependency_file("gemspec_loads_another", filename: "example.gemspec") } + + describe "#gemspec_includes_dependency?" do + subject(:gemspec_includes_dependency) do + checker.gemspec_includes_dependency?(dependency) + end + + context "when the file does not include the dependency" do + let(:dependency_name) { "dependabot-core" } + it { is_expected.to eq(false) } + end + + context "when the file does include the dependency as `add_dependency`" do + let(:dependency_name) { "excon" } + it { is_expected.to eq(true) } + end + + context "when the file does include the dependency as `add_runtime_dependency`" do + let(:dependency_name) { "bundler" } + it { is_expected.to eq(true) } + end + + context "when the file does include the dependency as `add_development_dependency`" do + let(:dependency_name) { "webmock" } + it { is_expected.to eq(true) } + end + + context "when the file loads the dependency dynamically" do + let(:dependency_name) { "rake" } + it { is_expected.to eq(false) } + end + end +end diff --git a/bundler/spec/dependabot/bundler/file_parser_spec.rb b/bundler/spec/dependabot/bundler/file_parser_spec.rb index c7d7107c78d..13df0a18a63 100644 --- a/bundler/spec/dependabot/bundler/file_parser_spec.rb +++ b/bundler/spec/dependabot/bundler/file_parser_spec.rb @@ -9,32 +9,27 @@ RSpec.describe Dependabot::Bundler::FileParser do it_behaves_like "a dependency file parser" - let(:files) { [gemfile, lockfile] } - let(:gemfile) do - Dependabot::DependencyFile.new(name: "Gemfile", content: gemfile_body) - end - let(:lockfile) do - Dependabot::DependencyFile.new(name: "Gemfile.lock", content: lockfile_body) + let(:parser) do + described_class.new( + dependency_files: dependency_files, + source: source, + reject_external_code: reject_external_code + ) end - let(:parser) { described_class.new(dependency_files: files, source: source) } let(:source) do Dependabot::Source.new( provider: "github", - repo: "gocardless/bump", + repo: "dependabot-fixtures/bump", directory: "/" ) end - let(:gemfile_body) { fixture("ruby", "gemfiles", gemfile_fixture_name) } - let(:lockfile_body) { fixture("ruby", "lockfiles", lockfile_fixture_name) } - let(:gemfile_fixture_name) { "version_specified" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_specified_gemfile") } + let(:reject_external_code) { false } describe "parse" do subject(:dependencies) { parser.parse } context "with a version specified" do - let(:gemfile_fixture_name) { "version_specified" } - its(:length) { is_expected.to eq(2) } describe "the first dependency" do @@ -55,7 +50,7 @@ end context "that is a pre-release with a dash" do - let(:gemfile_fixture_name) { "prerelease_with_dash" } + let(:dependency_files) { bundler_project_dependency_files("prerelease_with_dash_gemfile") } its(:length) { is_expected.to eq(2) } @@ -79,10 +74,8 @@ end context "with no version specified" do - let(:gemfile_fixture_name) { "version_not_specified" } - let(:lockfile_fixture_name) { "version_not_specified.lock" } - describe "the first dependency" do + let(:dependency_files) { bundler_project_dependency_files("version_not_specified") } subject { dependencies.first } let(:expected_requirements) do [{ @@ -101,8 +94,7 @@ end context "with a version specified as between two constraints" do - let(:gemfile_fixture_name) { "version_between_bounds" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_between_bounds_gemfile") } its(:length) { is_expected.to eq(2) } @@ -122,9 +114,7 @@ end context "with development dependencies" do - let(:gemfile_fixture_name) { "development_dependencies" } - let(:lockfile_fixture_name) { "development_dependencies.lock" } - + let(:dependency_files) { bundler_project_dependency_files("development_dependencies") } its(:length) { is_expected.to eq(2) } describe "the last dependency" do @@ -146,17 +136,7 @@ end context "from a gems.rb and gems.locked" do - let(:gemfile) do - Dependabot::DependencyFile.new(name: "gems.rb", content: gemfile_body) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - name: "gems.locked", - content: lockfile_body - ) - end - let(:gemfile_fixture_name) { "version_specified" } - let(:lockfile_fixture_name) { "bundler_2.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_specified_gems_rb") } its(:length) { is_expected.to eq(2) } @@ -179,12 +159,11 @@ end context "with a git dependency" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source") } its(:length) { is_expected.to eq(5) } - describe "an untagged dependency" do + describe "an untagged dependency", :bundler_v1_only do subject { dependencies.find { |d| d.name == "uk_phone_numbers" } } let(:expected_requirements) do [{ @@ -192,8 +171,8 @@ file: "Gemfile", source: { type: "git", - url: "http://github.com/gocardless/uk_phone_numbers", - branch: "master", + url: "http://github.com/dependabot-fixtures/uk_phone_numbers", + branch: nil, ref: "master" }, groups: [:default] @@ -207,6 +186,29 @@ end end + describe "an untagged dependency", :bundler_v2_only do + subject { dependencies.find { |d| d.name == "uk_phone_numbers" } } + let(:expected_requirements) do + [{ + requirement: ">= 0", + file: "Gemfile", + source: { + type: "git", + url: "http://github.com/dependabot-fixtures/uk_phone_numbers", + branch: nil, + ref: nil + }, + groups: [:default] + }] + end + + it { is_expected.to be_a(Dependabot::Dependency) } + its(:requirements) { is_expected.to eq(expected_requirements) } + its(:version) do + is_expected.to eq("1530024bd6a68d36ac18e04836ce110e0d433c36") + end + end + describe "a tagged dependency" do subject { dependencies.find { |d| d.name == "que" } } let(:expected_requirements) do @@ -215,8 +217,8 @@ file: "Gemfile", source: { type: "git", - url: "git@github.com:chanks/que", - branch: "master", + url: "git@github.com:dependabot-fixtures/que", + branch: nil, ref: "v0.11.6" }, groups: [:default] @@ -230,9 +232,8 @@ end end - describe "a github dependency" do - let(:gemfile_fixture_name) { "github_source" } - let(:lockfile_fixture_name) { "github_source.lock" } + describe "a github dependency", :bundler_v1_only do + let(:dependency_files) { bundler_project_dependency_files("github_source") } subject { dependencies.find { |d| d.name == "business" } } let(:expected_requirements) do @@ -241,8 +242,8 @@ file: "Gemfile", source: { type: "git", - url: "git://github.com/gocardless/business.git", - branch: "master", + url: "https://github.com/dependabot-fixtures/business.git", + branch: nil, ref: "master" }, groups: [:default] @@ -256,9 +257,33 @@ end end - context "with a subdependency of a git source" do - let(:lockfile_fixture_name) { "git_source_undeclared.lock" } - let(:gemfile_fixture_name) { "git_source_undeclared" } + describe "a github dependency", :bundler_v2_only do + let(:dependency_files) { bundler_project_dependency_files("github_source") } + + subject { dependencies.find { |d| d.name == "business" } } + let(:expected_requirements) do + [{ + requirement: ">= 0", + file: "Gemfile", + source: { + type: "git", + url: "https://github.com/dependabot-fixtures/business.git", + branch: nil, + ref: nil + }, + groups: [:default] + }] + end + + it { is_expected.to be_a(Dependabot::Dependency) } + its(:requirements) { is_expected.to eq(expected_requirements) } + its(:version) do + is_expected.to eq("d31e445215b5af70c1604715d97dd953e868380e") + end + end + + context "with a subdependency of a git source", :bundler_v1_only do + let(:dependency_files) { bundler_project_dependency_files("git_source_undeclared") } subject { dependencies.find { |d| d.name == "kaminari-actionview" } } let(:expected_requirements) do @@ -267,8 +292,8 @@ file: "Gemfile", source: { type: "git", - url: "https://github.com/kaminari/kaminari", - branch: "master", + url: "https://github.com/dependabot-fixtures/kaminari", + branch: nil, ref: "master" }, groups: [:default] @@ -279,11 +304,61 @@ its(:name) { is_expected.to eq("kaminari-actionview") } its(:requirements) { is_expected.to eq(expected_requirements) } end + + context "with a subdependency of a git source", :bundler_v2_only do + let(:dependency_files) { bundler_project_dependency_files("git_source_undeclared") } + + subject { dependencies.find { |d| d.name == "kaminari-actionview" } } + let(:expected_requirements) do + [{ + requirement: ">= 0", + file: "Gemfile", + source: { + type: "git", + url: "https://github.com/dependabot-fixtures/kaminari", + branch: nil, + ref: nil + }, + groups: [:default] + }] + end + + it { is_expected.to be_a(Dependabot::Dependency) } + its(:name) { is_expected.to eq("kaminari-actionview") } + its(:requirements) { is_expected.to eq(expected_requirements) } + end + end + + context "rejecting external code" do + let(:reject_external_code) { true } + + context "with no git sources" do + let(:dependency_files) { bundler_project_dependency_files("version_specified_gemfile") } + + it "does not raise exception" do + expect { parser.parse }.not_to raise_error + end + end + + context "with a git source" do + let(:dependency_files) { bundler_project_dependency_files("git_source") } + + it "raises exception" do + expect { parser.parse }.to raise_error(::Dependabot::UnexpectedExternalCode) + end + end + + context "with a subdependency of a git source" do + let(:dependency_files) { bundler_project_dependency_files("git_source_undeclared") } + + it "raises exception" do + expect { parser.parse }.to raise_error(::Dependabot::UnexpectedExternalCode) + end + end end context "with a dependency that only appears in the lockfile" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } its(:length) { is_expected.to eq(2) } it "is included" do @@ -292,8 +367,7 @@ end context "with a dependency that doesn't appear in the lockfile" do - let(:gemfile_fixture_name) { "platform_windows" } - let(:lockfile_fixture_name) { "platform_windows.lock" } + let(:dependency_files) { bundler_project_dependency_files("platform_windows") } its(:length) { is_expected.to eq(1) } it "is not included" do @@ -302,15 +376,11 @@ end context "with a path-based dependency" do - let(:files) { [gemfile, lockfile, gemspec] } - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "plugins/example/example.gemspec", - content: fixture("ruby", "gemspecs", "example"), - support_file: true - ) + let(:dependency_files) do + bundler_project_dependency_files("path_source").tap do |files| + gemspec = files.find { |f| f.name == "plugins/example/example.gemspec" } + gemspec.support_file = true + end end let(:expected_requirements) do @@ -336,14 +406,7 @@ end context "that comes from a .specification file" do - let(:files) { [gemfile, lockfile, specification] } - let(:specification) do - Dependabot::DependencyFile.new( - name: "plugins/example/.specification", - content: fixture("ruby", "specifications", "statesman"), - support_file: true - ) - end + let(:dependency_files) { bundler_project_dependency_files("version_specified_gemfile_specification") } it "includes the path dependency" do path_dep = dependencies.find { |dep| dep.name == "example" } @@ -353,9 +416,7 @@ end context "with a gem from a private gem source" do - let(:lockfile_fixture_name) { "specified_source.lock" } - let(:gemfile_fixture_name) { "specified_source" } - + let(:dependency_files) { bundler_project_dependency_files("specified_source") } its(:length) { is_expected.to eq(2) } describe "the private dependency" do @@ -380,23 +441,20 @@ end context "with a gem from a plugin gem source" do - let(:lockfile_fixture_name) { "specified_plugin_source.lock" } - let(:gemfile_fixture_name) { "specified_plugin_source" } + let(:dependency_files) { bundler_project_dependency_files("specified_plugin_source") } it "raises a helpful error" do expect { parser.parse }. to raise_error do |error| - expect(error.class).to eq(Dependabot::DependencyFileNotEvaluatable) - expect(error.message). - to include("No plugin sources available for aws-s3") - end + expect(error.class).to eq(Dependabot::DependencyFileNotEvaluatable) + expect(error.message). + to include("No plugin sources available for aws-s3") + end end end context "with a gem from the default source, specified as a block" do - let(:lockfile_fixture_name) { "block_source_rubygems.lock" } - let(:gemfile_fixture_name) { "block_source_rubygems" } - + let(:dependency_files) { bundler_project_dependency_files("block_source_rubygems") } its(:length) { is_expected.to eq(2) } describe "the first dependency" do @@ -418,48 +476,39 @@ end context "when the Gemfile can't be evaluated" do - let(:gemfile_fixture_name) { "unevaluatable_japanese" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("unevaluatable_japanese_gemfile") } it "raises a helpful error" do expect { parser.parse }. to raise_error do |error| - expect(error.class).to eq(Dependabot::DependencyFileNotEvaluatable) - expect(error.message.encoding.to_s).to eq("UTF-8") - end + expect(error.class).to eq(Dependabot::DependencyFileNotEvaluatable) + expect(error.message.encoding.to_s).to eq("UTF-8") + end end context "because it contains an exec command" do - let(:gemfile_fixture_name) { "exec_error" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("exec_error_gemfile") } it "raises a helpful error" do expect { parser.parse }. to raise_error do |error| - expect(error.class). - to eq(Dependabot::DependencyFileNotEvaluatable) - end + expect(error.message). + to start_with("Error evaluating your dependency files") + expect(error.class). + to eq(Dependabot::DependencyFileNotEvaluatable) + end end end end context "with a Gemfile that uses eval_gemfile" do - let(:files) { [gemfile, lockfile, evaled_gemfile] } - let(:gemfile_fixture_name) { "eval_gemfile" } - let(:evaled_gemfile) do - Dependabot::DependencyFile.new( - name: "backend/Gemfile", - content: fixture("ruby", "gemfiles", "only_statesman") - ) - end - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("eval_gemfile_gemfile") } its(:length) { is_expected.to eq(2) } end context "with a Gemfile that includes a require" do - let(:gemfile_fixture_name) { "includes_requires" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("includes_requires_gemfile") } it "blows up with a useful error" do expect { parser.parse }. @@ -468,44 +517,29 @@ end context "with a Gemfile that includes a file with require_relative" do - let(:files) { [gemfile, lockfile, required_file] } - let(:gemfile_fixture_name) { "includes_require_relative" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:required_file) do - Dependabot::DependencyFile.new( - name: "../some_other_file.rb", - content: "SOME_CONSTANT = 5" - ) + let(:dependency_files) do + bundler_project_dependency_files("includes_require_relative_gemfile").map do |file| + path = Pathname.new(file.name) + file.name = File.basename(path) + dir = File.dirname(path) + file.directory = dir + file.name = "../#{file.name}" if dir != "nested" + file + end end its(:length) { is_expected.to eq(2) } end context "with a Gemfile that imports a gemspec" do - let(:files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "example.gemspec", - content: gemspec_content - ) - end - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:lockfile_fixture_name) { "imports_gemspec.lock" } - let(:gemspec_content) { fixture("ruby", "gemspecs", "small_example") } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec") } it "doesn't include the gemspec dependency (i.e., itself)" do expect(dependencies.map(&:name)).to match_array(%w(business statesman)) end context "with a gemspec from a specific path" do - let(:gemfile_fixture_name) { "imports_gemspec_from_path" } - let(:lockfile_fixture_name) { "imports_gemspec_from_path.lock" } - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "subdir/example.gemspec", - content: fixture("ruby", "gemspecs", "small_example") - ) - end + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_from_path") } it "fetches details from the gemspec" do expect(dependencies.map(&:name)). @@ -528,18 +562,7 @@ end context "with a gemspec with a float version number" do - let(:files) { [gemspec, gemfile] } - - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "version_as_float.gemspec", - content: gemspec_content - ) - end - let(:gemspec_content) do - fixture("ruby", "gemspecs", "version_as_float") - end - let(:gemfile_fixture_name) { "imports_gemspec" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_version_as_float") } it "includes the gemspec dependency" do expect(dependencies.map(&:name)). @@ -548,10 +571,8 @@ end end - context "with an unparseable git dep that also appears in the gemspec" do - let(:gemfile_fixture_name) { "git_source_unparseable" } - let(:lockfile_fixture_name) { "git_source_unparseable.lock" } - let(:gemspec_content) { fixture("ruby", "gemspecs", "small_example") } + context "with an unparseable git dep that also appears in the gemspec", :bundler_v1_only do + let(:dependency_files) { bundler_project_dependency_files("git_source_unparseable") } it "includes source details on the gemspec requirement" do expect(dependencies.map(&:name)).to match_array(%w(business)) @@ -566,25 +587,38 @@ groups: ["runtime"], source: { type: "git", - url: "git@github.com:gocardless/business", - branch: "master", + url: "git@github.com:dependabot-fixtures/business", + branch: nil, ref: "master" } }] ) end + + it "includes source details on the gemspec requirement", :bundler_v2_only do + expect(dependencies.map(&:name)).to match_array(%w(business)) + expect(dependencies.first.name).to eq("business") + expect(dependencies.first.version). + to eq("1378a2b0b446d991b7567efbc7eeeed2720e4d8f") + expect(dependencies.first.requirements). + to match_array( + [{ + file: "example.gemspec", + requirement: "~> 1.0", + groups: ["runtime"], + source: { + type: "git", + url: "git@github.com:dependabot-fixtures/business", + branch: nil, + ref: nil + } + }] + ) + end end context "with two gemspecs" do - let(:gemfile_fixture_name) { "imports_two_gemspecs" } - let(:lockfile_fixture_name) { "imports_two_gemspecs.lock" } - let(:gemspec2) do - Dependabot::DependencyFile.new( - name: "example2.gemspec", - content: fixture("ruby", "gemspecs", "small_example2") - ) - end - let(:files) { [gemfile, lockfile, gemspec, gemspec2] } + let(:dependency_files) { bundler_project_dependency_files("imports_two_gemspecs") } it "fetches details from both gemspecs" do expect(dependencies.map(&:name)). @@ -610,15 +644,14 @@ end context "with a large gemspec" do - let(:gemspec_content) { fixture("ruby", "gemspecs", "example") } - let(:lockfile_fixture_name) { "imports_gemspec_large.lock" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_imports_gemspec_large") } it "includes details of each declaration" do - expect(dependencies.select(&:top_level?).count).to eq(13) + expect(dependencies.count(&:top_level?)).to eq(13) end it "includes details of each sub-dependency" do - expect(dependencies.reject(&:top_level?).count).to eq(23) + expect(dependencies.count { |dep| !dep.top_level? }).to eq(23) diff_lcs = dependencies.find { |d| d.name == "diff-lcs" } expect(diff_lcs.subdependency_metadata).to eq([{ production: false }]) @@ -663,14 +696,15 @@ end context "that needs to be sanitized" do - let(:gemspec_content) { fixture("ruby", "gemspecs", "with_require") } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_with_require") } + it "includes details of each declaration" do - expect(dependencies.select(&:top_level?).count).to eq(13) + expect(dependencies.count(&:top_level?)).to eq(13) end end context "that can't be evaluated" do - let(:gemspec_content) { fixture("ruby", "gemspecs", "unevaluatable") } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_unevaluatable") } it "raises a helpful error" do expect { parser.parse }. @@ -680,23 +714,26 @@ end end - context "with a gemspec and Gemfile (no lockfile)" do - let(:files) { [gemspec, gemfile] } + context "with a gemspec that loads dependencies from another gemspec dynamically" do + let(:dependency_files) { bundler_project_dependency_files("gemspec_loads_another") } - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "example.gemspec", - content: gemspec_content - ) + describe "a development dependency loaded from an external gemspec" do + subject { dependencies.find { |d| d.name == "rake" } } + + it "is only loaded with its own gemspec as requirement" do + expect(subject.name).to eq("rake") + expect(subject.requirements.size).to eq(1) + expect(subject.requirements.first[:file]).to eq("another.gemspec") + end end - let(:gemspec_content) { fixture("ruby", "gemspecs", "example") } - let(:gemfile_fixture_name) { "imports_gemspec" } + end + context "with a gemspec and Gemfile (no lockfile)" do + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_no_lockfile") } its(:length) { is_expected.to eq(13) } context "when a dependency appears in both" do - let(:gemfile_fixture_name) { "imports_gemspec_git_override" } - let(:gemspec_content) { fixture("ruby", "gemspecs", "small_example") } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_git_override_no_lockfile") } its(:length) { is_expected.to eq(1) } @@ -715,9 +752,9 @@ file: "Gemfile", source: { type: "git", - url: "https://github.com/gocardless/business", - branch: "master", - ref: "master" + url: "https://github.com/dependabot-fixtures/business", + branch: nil, + ref: nil }, groups: [:default] } @@ -735,15 +772,7 @@ end context "with only a gemspec" do - let(:files) { [gemspec] } - - let(:gemspec) do - Dependabot::DependencyFile.new( - name: "example.gemspec", - content: gemspec_content - ) - end - let(:gemspec_content) { fixture("ruby", "gemspecs", "example") } + let(:dependency_files) { bundler_project_dependency_files("gemspec_no_lockfile") } its(:length) { is_expected.to eq(11) } @@ -765,14 +794,13 @@ end context "that needs to be sanitized" do - let(:gemspec_content) { fixture("ruby", "gemspecs", "with_require") } + let(:dependency_files) { bundler_project_dependency_files("gemspec_with_require_no_lockfile") } its(:length) { is_expected.to eq(11) } end end context "with only a gemfile" do - let(:files) { [gemfile] } - let(:gemfile_fixture_name) { "version_specified" } + let(:dependency_files) { bundler_project_dependency_files("version_specified_no_lockfile") } its(:length) { is_expected.to eq(2) } @@ -794,7 +822,7 @@ end context "with a dependency for an alternative platform" do - let(:gemfile_fixture_name) { "platform_windows" } + let(:dependency_files) { bundler_project_dependency_files("platform_windows_no_lockfile") } its(:length) { is_expected.to eq(1) } it "is not included" do @@ -802,5 +830,18 @@ end end end + + it "instruments the package manager version" do + events = [] + Dependabot.subscribe(Dependabot::Notifications::FILE_PARSER_PACKAGE_MANAGER_VERSION_PARSED) do |*args| + events << ActiveSupport::Notifications::Event.new(*args) + end + + parser.parse + + expect(events.last.payload).to eq( + { ecosystem: "bundler", package_managers: { "bundler" => PackageManagerHelper.bundler_version } } + ) + end end end diff --git a/bundler/spec/dependabot/bundler/file_updater/gemfile_updater_spec.rb b/bundler/spec/dependabot/bundler/file_updater/gemfile_updater_spec.rb index 26c36533a9d..72dbbf7f2cf 100644 --- a/bundler/spec/dependabot/bundler/file_updater/gemfile_updater_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/gemfile_updater_spec.rb @@ -14,10 +14,8 @@ end let(:dependencies) { [dependency] } let(:gemfile) do - Dependabot::DependencyFile.new(name: "Gemfile", content: gemfile_body) + bundler_project_dependency_file("gemfile", filename: "Gemfile") end - let(:gemfile_body) { fixture("ruby", "gemfiles", gemfile_fixture_name) } - let(:gemfile_fixture_name) { "Gemfile" } let(:dependency) do Dependabot::Dependency.new( name: dependency_name, @@ -42,18 +40,22 @@ subject(:updated_gemfile_content) { updater.updated_gemfile_content } context "when no change is required" do - let(:gemfile_fixture_name) { "version_not_specified" } + let(:gemfile) do + bundler_project_dependency_file("version_not_specified", filename: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end let(:previous_requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end - it { is_expected.to eq(gemfile_body) } + it { is_expected.to eq(gemfile.content) } end context "when the full version is specified" do - let(:gemfile_fixture_name) { "version_specified" } + let(:gemfile) do + bundler_project_dependency_file("version_specified_gemfile", filename: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", requirement: "~> 1.5.0", groups: [], source: nil }] end @@ -66,7 +68,7 @@ context "with a gems.rb" do let(:gemfile) do - Dependabot::DependencyFile.new(name: "gems.rb", content: gemfile_body) + bundler_project_dependency_file("gems_rb", filename: "gems.rb") end let(:requirements) do [{ @@ -91,19 +93,22 @@ end context "when updating a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:gemfile) do + bundler_project_dependency_file("subdependency", filename: "Gemfile") + end let(:dependency_name) { "i18n" } let(:dependency_version) { "1.6.0.beta" } let(:dependency_previous_version) { "0.7.0.beta1" } let(:requirements) { [] } let(:previous_requirements) { [] } - it { is_expected.to eq(gemfile_body) } + it { is_expected.to eq(gemfile.content) } end context "when a pre-release is specified" do - let(:gemfile_fixture_name) { "prerelease_specified" } + let(:gemfile) do + bundler_project_dependency_file("prerelease_specified", filename: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", @@ -124,7 +129,9 @@ end context "when the minor version is specified" do - let(:gemfile_fixture_name) { "minor_version_specified" } + let(:gemfile) do + bundler_project_dependency_file("minor_version_specified_gemfile", filename: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", requirement: "~> 1.5", groups: [], source: nil }] end @@ -136,8 +143,9 @@ end context "with a gem whose name includes a number" do - let(:gemfile_fixture_name) { "gem_with_number" } - let(:lockfile_fixture_name) { "gem_with_number.lock" } + let(:gemfile) do + bundler_project_dependency_file("gem_with_number", filename: "Gemfile") + end let(:dependency) do Dependabot::Dependency.new( name: "i18n", @@ -161,25 +169,32 @@ end context "when there is a comment" do - let(:gemfile_fixture_name) { "comments" } + let(:gemfile) do + bundler_project_dependency_file("comments_no_lockfile", filename: "Gemfile") + end it do is_expected.to include "\"business\", \"~> 1.5.0\" # Business time" end end context "when the previous version used string interpolation" do - let(:gemfile_fixture_name) { "interpolated_version" } + let(:gemfile) do + bundler_project_dependency_file("interpolated_version_no_lockfile", filename: "Gemfile") + end it { is_expected.to include "\"business\", \"~> #" } end context "when the previous version used a function" do - let(:gemfile_fixture_name) { "function_version" } + let(:gemfile) do + bundler_project_dependency_file("function_version_gemfile", filename: "Gemfile") + end it { is_expected.to include "\"business\", version" } end context "with multiple dependencies" do - let(:gemfile_fixture_name) { "version_conflict" } - let(:lockfile_fixture_name) { "version_conflict.lock" } + let(:gemfile) do + bundler_project_dependency_file("version_conflict", filename: "Gemfile") + end let(:dependencies) do [ Dependabot::Dependency.new( @@ -216,8 +231,9 @@ end context "with a gem that has a git source" do - let(:gemfile_fixture_name) { "git_source_with_version" } - let(:lockfile_fixture_name) { "git_source_with_version.lock" } + let(:gemfile) do + bundler_project_dependency_file("git_source_with_version_gemfile", filename: "Gemfile") + end let(:dependency_name) { "dependabot-test-ruby-package" } let(:dependency) do Dependabot::Dependency.new( @@ -236,8 +252,8 @@ groups: [], source: { type: "git", - url: "http://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package" + url: "http://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" } }] end @@ -248,8 +264,8 @@ groups: [], source: { type: "git", - url: "http://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package" + url: "http://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" } }] end @@ -266,6 +282,9 @@ %(git: "https://github.com/dependabot-fixtures/\ dependabot-test-ruby-package", tag: "v1.0.0") end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", @@ -273,8 +292,8 @@ groups: [], source: { type: "git", - url: "http://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package", + url: "http://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package", ref: "v1.1.0" } }] @@ -287,6 +306,20 @@ end it { is_expected.to eq(expected_string) } + + context "but updating an evaled gemfile including a different git sourced dependency" do + let(:gemfile_body) do + %(gem "dependabot-test-other", git: "https://github.com/dependabot-fixtures/dependabot-other") + end + + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile.included") + end + + it "leaves the evaled gemfile untouched" do + is_expected.to eq(gemfile_body) + end + end end context "that should be removed" do @@ -320,6 +353,9 @@ %(gem "dependabot-test-ruby-package",) + %(git: "git_url", tag: "old_tag") end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it { is_expected.to eq(%(gem "dependabot-test-ruby-package")) } end @@ -328,6 +364,9 @@ %(gem "dependabot-test-ruby-package", "1.0.0", ) + %(require: false, git: "git_url") end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq( %(gem "dependabot-test-ruby-package", "~> 1.1.0", require: false) @@ -340,6 +379,9 @@ %(gem "dependabot-test-ruby-package", "1.0.0", ) + %(git: "git_url", require: false) end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq( %(gem "dependabot-test-ruby-package", "~> 1.1.0", require: false) @@ -352,6 +394,9 @@ %{gem("dependabot-test-ruby-package", "1.0.0", } + %{git: "git_url",\nrequire: false)} end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq( %(gem("dependabot-test-ruby-package", "~> 1.1.0", require: false)) @@ -364,6 +409,9 @@ %(gem "dependabot-test-ruby-package", '1.0.0', ) + %(require: false,\ngit: "git_url") end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq( %(gem "dependabot-test-ruby-package", '~> 1.1.0', require: false) @@ -375,6 +423,9 @@ let(:gemfile_body) do %(gem "dependabot-test-ruby-package", "1.0.0", github: "git_url") end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq(%(gem "dependabot-test-ruby-package", "~> 1.1.0")) end @@ -384,6 +435,9 @@ let(:gemfile_body) do %(gem "dependabot-test-ruby-package", git: "git_url" # My gem) end + let(:gemfile) do + Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") + end it do is_expected.to eq(%(gem "dependabot-test-ruby-package" # My gem)) end @@ -392,7 +446,9 @@ end context "when the new (and old) requirement is a range" do - let(:gemfile_fixture_name) { "version_between_bounds" } + let(:gemfile) do + bundler_project_dependency_file("version_between_bounds_gemfile", filename: "Gemfile") + end let(:requirements) do [{ file: "Gemfile", diff --git a/bundler/spec/dependabot/bundler/file_updater/gemspec_dependency_name_finder_spec.rb b/bundler/spec/dependabot/bundler/file_updater/gemspec_dependency_name_finder_spec.rb index db446848ca2..9e50b51c5da 100644 --- a/bundler/spec/dependabot/bundler/file_updater/gemspec_dependency_name_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/gemspec_dependency_name_finder_spec.rb @@ -4,10 +4,11 @@ require "dependabot/dependency_file" require "dependabot/bundler/file_updater/gemspec_dependency_name_finder" -module_to_test = Dependabot::Bundler::FileUpdater -RSpec.describe module_to_test::GemspecDependencyNameFinder do +RSpec.describe Dependabot::Bundler::FileUpdater::GemspecDependencyNameFinder do let(:finder) { described_class.new(gemspec_content: gemspec_content) } - let(:gemspec_content) { fixture("ruby", "gemspecs", "small_example") } + let(:gemspec_content) do + bundler_project_dependency_file("gemfile_small_example", filename: "example.gemspec").content + end describe "#dependency_name" do subject(:dependency_name) { finder.dependency_name } @@ -15,7 +16,9 @@ it { is_expected.to eq("example") } context "with an unevaluatable gemspec name" do - let(:gemspec_content) { fixture("ruby", "gemspecs", "function_name") } + let(:gemspec_content) do + bundler_project_dependency_file("gemfile_function_name", filename: "example.gemspec").content + end it { is_expected.to be_nil } end end diff --git a/bundler/spec/dependabot/bundler/file_updater/gemspec_sanitizer_spec.rb b/bundler/spec/dependabot/bundler/file_updater/gemspec_sanitizer_spec.rb index 2c68420de5b..253b9c1965b 100644 --- a/bundler/spec/dependabot/bundler/file_updater/gemspec_sanitizer_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/gemspec_sanitizer_spec.rb @@ -13,7 +13,9 @@ describe "#rewrite" do subject(:rewrite) { sanitizer.rewrite(content) } - let(:content) { fixture("ruby", "gemspecs", "with_require") } + let(:content) do + bundler_project_dependency_file("gemfile_with_require", filename: "example.gemspec").content + end context "with a requirement line" do let(:content) do @@ -22,10 +24,10 @@ it do is_expected.to eq( - "begin\n"\ - "require 'example/version'\n"\ - "rescue LoadError\n"\ - "end\n"\ + "begin\n" \ + "require 'example/version'\n" \ + "rescue LoadError\n" \ + "end\n" \ 'add_dependency "require"' ) end @@ -38,10 +40,10 @@ it do is_expected.to eq( - "begin\n"\ - "require_relative 'example/version'\n"\ - "rescue LoadError\n"\ - "end\n"\ + "begin\n" \ + "require_relative 'example/version'\n" \ + "rescue LoadError\n" \ + "end\n" \ 'add_dependency "require"' ) end @@ -98,8 +100,8 @@ context "that uses a conditional" do let(:content) do - "Spec.new { |s| s.version = '0.1.0'\n "\ - "s.post_install_message = \"a\" if true }" + "Spec.new { |s| s.version = '0.1.0'\n " \ + "s.post_install_message = \"a\" if true }" end it "maintains a valid conditional" do expect(rewrite).to eq( @@ -110,8 +112,8 @@ context "that assigns to the metadata hash" do let(:content) do - "Spec.new { |s| s.version = '0.1.0'\n "\ - "s.metadata['homepage'] = \"a\" }" + "Spec.new { |s| s.version = '0.1.0'\n " \ + "s.metadata['homepage'] = \"a\" }" end it "removes the assignment" do expect(rewrite).to eq( @@ -131,7 +133,24 @@ end it "removes the whole heredoc" do expect(rewrite).to eq( - "Spec.new do |s|\n s.version = \"0.1.0\""\ + "Spec.new do |s|\n s.version = \"0.1.0\"" \ + "\n \"sanitized\"\n end" + ) + end + end + + context "that uses a heredoc with methods chained onto it" do + let(:content) do + %(Spec.new do |s| + s.version = "0.1.0" + s.post_install_message = <<~DESCRIPTION.strip.downcase + My description + DESCRIPTION + end) + end + it "removes the whole heredoc" do + expect(rewrite).to eq( + "Spec.new do |s|\n s.version = \"0.1.0\"" \ "\n \"sanitized\"\n end" ) end @@ -210,7 +229,12 @@ # rubocop:disable Lint/InterpolationCheck context "with an assignment to a string-interpolated constant" do let(:content) { 'Spec.new { |s| s.version = "#{Example::Version}" }' } - it { is_expected.to eq('Spec.new { |s| s.version = "#{"1.5.0"}" }') } + it { is_expected.to eq('Spec.new { |s| s.version = "1.5.0" }') } + end + + context "with an assignment to a string-interpolated constant with multiple values" do + let(:content) { 'Spec.new { |s| s.version = "#{Example::Version}-#{git_commit}" }' } + it { is_expected.to eq('Spec.new { |s| s.version = "1.5.0" }') } end context "with a version constant used elsewhere in the file" do @@ -230,7 +254,9 @@ end context "with a block" do - let(:content) { fixture("ruby", "gemspecs", "with_nested_block") } + let(:content) do + bundler_project_dependency_file("gemfile_with_nested_block", filename: "example.gemspec").content + end specify { expect { sanitizer.rewrite(content) }.to_not raise_error } end end @@ -249,7 +275,9 @@ end context "with an assignment to Dir[..]" do - let(:content) { fixture("ruby", "gemspecs", "example") } + let(:content) do + bundler_project_dependency_file("gemfile_example", filename: "example.gemspec").content + end it { is_expected.to include("spec.files = []") } end end diff --git a/bundler/spec/dependabot/bundler/file_updater/git_pin_replacer_spec.rb b/bundler/spec/dependabot/bundler/file_updater/git_pin_replacer_spec.rb index 8b8e4ab8dae..14dc0089412 100644 --- a/bundler/spec/dependabot/bundler/file_updater/git_pin_replacer_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/git_pin_replacer_spec.rb @@ -24,7 +24,9 @@ describe "#rewrite" do subject(:rewrite) { replacer.rewrite(content) } - let(:content) { fixture("ruby", "gemfiles", "git_source") } + let(:content) do + bundler_project_dependency_file("git_source", filename: "Gemfile").content + end context "with a dependency that specifies a ref" do let(:dependency_name) { "business" } diff --git a/bundler/spec/dependabot/bundler/file_updater/git_source_remover_spec.rb b/bundler/spec/dependabot/bundler/file_updater/git_source_remover_spec.rb index 2ef07dee0d4..83764e89f5b 100644 --- a/bundler/spec/dependabot/bundler/file_updater/git_source_remover_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/git_source_remover_spec.rb @@ -21,7 +21,9 @@ describe "#rewrite" do subject(:rewrite) { remover.rewrite(content) } - let(:content) { fixture("ruby", "gemfiles", "git_source") } + let(:content) do + bundler_project_dependency_file("git_source", filename: "Gemfile").content + end context "with a dependency that specifies a ref" do let(:dependency_name) { "business" } diff --git a/bundler/spec/dependabot/bundler/file_updater/requirement_replacer_spec.rb b/bundler/spec/dependabot/bundler/file_updater/requirement_replacer_spec.rb index cc4773e9b8b..e594a7bde0d 100644 --- a/bundler/spec/dependabot/bundler/file_updater/requirement_replacer_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/requirement_replacer_spec.rb @@ -40,13 +40,13 @@ describe "#rewrite" do subject(:rewrite) { replacer.rewrite(content) } - let(:content) { fixture("ruby", "gemfiles", "git_source") } - context "with a Gemfile" do let(:file_type) { :gemfile } context "when the declaration spans multiple lines" do - let(:content) { fixture("ruby", "gemfiles", "git_source") } + let(:content) do + bundler_project_dependency_file("git_source", filename: "Gemfile").content + end it { is_expected.to include(%(gem "business", "~> 1.5.0",\n git: )) } it { is_expected.to include(%(gem "statesman", "~> 1.2.0")) } end @@ -68,9 +68,9 @@ context "within a source block" do let(:content) do - "source 'https://example.com' do\n"\ - " gem \"business\", \"~> 1.0\", require: true\n"\ - "end" + "source 'https://example.com' do\n" \ + " gem \"business\", \"~> 1.0\", require: true\n" \ + "end" end it { is_expected.to include(%(gem "business", "~> 1.5.0", require:)) } end @@ -186,6 +186,11 @@ end end + context "with a case statement" do + let(:content) { %(gem "business", case true\n when true\n "1.0.0"\n else\n "1.2.0"\n end) } + it { is_expected.to eq(content) } + end + context "with a conditional" do let(:content) { %(gem "business", ENV["ROUGE"] if ENV["ROUGE"]) } it { is_expected.to eq(content) } @@ -214,7 +219,9 @@ context "with a gemspec" do let(:file_type) { :gemspec } - let(:content) { fixture("ruby", "gemspecs", "example") } + let(:content) do + bundler_project_dependency_file("gemfile_example", filename: "example.gemspec").content + end context "when declared with `add_runtime_dependency`" do let(:dependency_name) { "bundler" } @@ -239,7 +246,9 @@ end context "with an exact requirement" do - let(:content) { fixture("ruby", "gemspecs", "exact") } + let(:content) do + bundler_project_dependency_file("gemfile_exact", filename: "example.gemspec").content + end context "when declared with `=` operator" do let(:dependency_name) { "statesman" } @@ -256,6 +265,16 @@ end end + context "with inequality matchers" do + let(:previous_requirement) { ">= 2.0.0, != 2.0.3, != 2.0.4" } + let(:updated_requirement) { "~> 2.0.1, != 2.0.3, != 2.0.4" } + let(:content) do + %(s.add_runtime_dependency("business", "~> 2.0.1", "!= 2.0.3", "!= 2.0.4")) + end + + it { is_expected.to eq(content) } + end + context "when declared with `add_development_dependency`" do let(:dependency_name) { "rspec" } it { is_expected.to include(%(ent_dependency "rspec", "~> 1.5.0"\n)) } diff --git a/bundler/spec/dependabot/bundler/file_updater/ruby_requirement_setter_spec.rb b/bundler/spec/dependabot/bundler/file_updater/ruby_requirement_setter_spec.rb index b3d83fbaad4..d88e53a82a8 100644 --- a/bundler/spec/dependabot/bundler/file_updater/ruby_requirement_setter_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater/ruby_requirement_setter_spec.rb @@ -4,56 +4,132 @@ require "dependabot/dependency_file" require "dependabot/bundler/file_updater/ruby_requirement_setter" -module_to_test = Dependabot::Bundler::FileUpdater -RSpec.describe module_to_test::RubyRequirementSetter do +RSpec.describe Dependabot::Bundler::FileUpdater::RubyRequirementSetter do let(:setter) { described_class.new(gemspec: gemspec) } let(:gemspec) do - Dependabot::DependencyFile.new(content: gemspec_body, name: "some.gemspec") + bundler_project_dependency_file("gemfile_small_example", filename: "example.gemspec") end - let(:gemspec_body) { fixture("ruby", "gemspecs", "small_example") } describe "#rewrite" do subject(:rewrite) { setter.rewrite(content) } context "when the gemspec does not include a required_ruby_version" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "no_required_ruby") } + let(:gemspec) do + bundler_project_dependency_file("gemfile_no_required_ruby", filename: "example.gemspec") + end + context "without an existing ruby version" do - let(:content) { fixture("ruby", "gemfiles", "Gemfile") } + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end it { is_expected.to eq(content) } end context "with an existing ruby version" do - let(:content) { fixture("ruby", "gemfiles", "explicit_ruby") } + let(:content) do + bundler_project_dependency_file("explicit_ruby", filename: "Gemfile").content + end it { is_expected.to eq(content) } end end context "when the gemspec includes a required_ruby_version" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "old_required_ruby") } + let(:gemspec) do + bundler_project_dependency_file("gemfile_old_required_ruby", filename: "example.gemspec") + end + + context "with a required ruby version range" do + let(:gemspec) do + bundler_project_dependency_file("gemspec_required_ruby_version_range", filename: "example.gemspec") + end + let(:content) do + bundler_project_dependency_file("gemspec_required_ruby_version_range", filename: "Gemfile").content + end + it { is_expected.to include("ruby '2.2.10'\n") } + it { is_expected.to include(%(gem "statesman", "~> 1.2.0")) } + end + + context "with a required ruby version range array" do + let(:gemspec) do + bundler_project_dependency_file("gemspec_required_ruby_version_range_array", filename: "example.gemspec") + end + let(:content) do + bundler_project_dependency_file("gemspec_required_ruby_version_range_array", filename: "Gemfile").content + end + it { is_expected.to include("ruby '2.2.10'\n") } + it { is_expected.to include(%(gem "statesman", "~> 1.2.0")) } + end + + context "with a required ruby version requirement class" do + let(:gemspec) do + bundler_project_dependency_file("gemspec_required_ruby_version_requirement_class", + filename: "example.gemspec") + end + let(:content) do + bundler_project_dependency_file("gemspec_required_ruby_version_requirement_class", + filename: "Gemfile").content + end + it { is_expected.to include("ruby '2.1.10'\n") } + it { is_expected.to include(%(gem "statesman", "~> 1.2.0")) } + end context "without an existing ruby version" do - let(:content) { fixture("ruby", "gemfiles", "Gemfile") } + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end it { is_expected.to include("ruby '1.9.3'\n") } it { is_expected.to include(%(gem "business", "~> 1.4.0")) } end context "that none of our Ruby versions satisfy" do - let(:content) { fixture("ruby", "gemfiles", "Gemfile") } - let(:gemspec_body) { fixture("ruby", "gemspecs", "impossible_ruby") } + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end + let(:gemspec) do + bundler_project_dependency_file("gemfile_impossible_ruby", filename: "example.gemspec") + end + + specify { expect { rewrite }.to raise_error(described_class::RubyVersionNotFound) } + end + + context "when requiring ruby 3" do + let(:gemspec) do + bundler_project_dependency_file("gemfile_require_ruby_3", filename: "example.gemspec") + end + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end + it { is_expected.to include("ruby '3.0.1'\n") } + it { is_expected.to include(%(gem "business", "~> 1.4.0")) } + end - specify { expect { rewrite }.to raise_error(/Ruby version/) } + context "when requiring ruby 3.1" do + let(:gemspec) do + bundler_project_dependency_file("gemfile_require_ruby_3_1", filename: "example.gemspec") + end + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end + it { is_expected.to include("ruby '3.1.1'\n") } + it { is_expected.to include(%(gem "business", "~> 1.4.0")) } end context "that can't be evaluated" do - let(:content) { fixture("ruby", "gemfiles", "Gemfile") } - let(:gemspec_body) { fixture("ruby", "gemspecs", "unevaluatable_ruby") } + let(:content) do + bundler_project_dependency_file("gemfile", filename: "Gemfile").content + end + let(:gemspec) do + bundler_project_dependency_file("gemfile_unevaluatable_ruby", filename: "example.gemspec") + end it { is_expected.to_not include("ruby '") } end context "with an existing ruby version" do context "at top level" do - let(:content) { fixture("ruby", "gemfiles", "explicit_ruby") } + let(:content) do + bundler_project_dependency_file("explicit_ruby", filename: "Gemfile").content + end it { is_expected.to include("ruby '1.9.3'\n") } it { is_expected.to_not include(%(ruby "2.2.0")) } @@ -62,16 +138,18 @@ context "within a source block" do let(:content) do - "source 'https://example.com' do\n"\ - " ruby \"2.2.0\"\n"\ - "end" + "source 'https://example.com' do\n" \ + " ruby \"2.2.0\"\n" \ + "end" end it { is_expected.to include("ruby '1.9.3'\n") } it { is_expected.to_not include(%(ruby "2.2.0")) } end context "loaded from a file" do - let(:content) { fixture("ruby", "gemfiles", "ruby_version_file") } + let(:content) do + bundler_project_dependency_file("ruby_version_file", filename: "Gemfile").content + end it { is_expected.to include("ruby '1.9.3'\n") } it { is_expected.to_not include("ruby File.open") } diff --git a/bundler/spec/dependabot/bundler/file_updater_spec.rb b/bundler/spec/dependabot/bundler/file_updater_spec.rb index a197e159f96..786068cd160 100644 --- a/bundler/spec/dependabot/bundler/file_updater_spec.rb +++ b/bundler/spec/dependabot/bundler/file_updater_spec.rb @@ -19,30 +19,14 @@ credentials: [{ "type" => "git_source", "host" => "github.com" - }] + }], + repo_contents_path: repo_contents_path ) end let(:dependencies) { [dependency] } - let(:dependency_files) { [gemfile, lockfile] } - let(:gemfile) do - Dependabot::DependencyFile.new( - name: "Gemfile", - content: gemfile_body, - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - name: "Gemfile.lock", - content: lockfile_body, - directory: directory - ) - end - let(:gemfile_body) { fixture("ruby", "gemfiles", gemfile_fixture_name) } - let(:lockfile_body) { fixture("ruby", "lockfiles", lockfile_fixture_name) } - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:project_name) { "gemfile" } let(:directory) { "/" } + let(:dependency_files) { bundler_project_dependency_files(project_name, directory: directory) } let(:dependency) do Dependabot::Dependency.new( name: dependency_name, @@ -62,15 +46,16 @@ let(:previous_requirements) do [{ file: "Gemfile", requirement: "~> 1.4.0", groups: [], source: nil }] end - let(:tmp_path) { Dependabot::SharedHelpers::BUMP_TMP_DIR_PATH } + let(:tmp_path) { Dependabot::Utils::BUMP_TMP_DIR_PATH } + let(:repo_contents_path) { nil } - before { Dir.mkdir(tmp_path) unless Dir.exist?(tmp_path) } + before { FileUtils.mkdir_p(tmp_path) } describe "#updated_dependency_files" do subject(:updated_files) { updater.updated_dependency_files } it "doesn't store the files permanently" do - expect { updated_files }.to_not(change { Dir.entries(tmp_path) }) + expect { updated_files }.not_to(change { Dir.entries(tmp_path) }) end it "returns DependencyFile objects" do @@ -85,7 +70,8 @@ end context "when no change is required" do - let(:gemfile_fixture_name) { "version_not_specified" } + let(:project_name) { "version_not_specified" } + let(:requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end @@ -96,7 +82,9 @@ end context "when the full version is specified" do - let(:gemfile_fixture_name) { "version_specified" } + let(:project_name) { "version_specified_gemfile" } + let(:gemfile) { bundler_project_dependency_file(project_name, filename: "Gemfile") } + let(:requirements) do [{ file: "Gemfile", @@ -132,20 +120,9 @@ updated_files.find { |f| f.name == "gems.rb" } end - let(:gemfile) do - Dependabot::DependencyFile.new( - name: "gems.rb", - content: gemfile_body, - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - name: "gems.locked", - content: lockfile_body, - directory: directory - ) - end + let(:project_name) { "gems_rb" } + let(:gemfile) { bundler_project_dependency_file(project_name, filename: "gems.rb") } + let(:requirements) do [{ file: "gems.rb", @@ -179,8 +156,8 @@ end context "when updating a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:project_name) { "subdependency" } + let(:dependency_name) { "i18n" } let(:dependency_version) { "0.7.0" } let(:dependency_previous_version) { "0.7.0.beta1" } @@ -192,23 +169,12 @@ end describe "a child gemfile" do - let(:dependency_files) { [gemfile, lockfile, child_gemfile] } - let(:child_gemfile) do - Dependabot::DependencyFile.new( - content: child_gemfile_body, - name: "backend/Gemfile" - ) - end - let(:child_gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } subject(:updated_gemfile) do updated_files.find { |f| f.name == "backend/Gemfile" } end context "when no change is required" do - let(:gemfile_fixture_name) { "version_not_specified" } - let(:child_gemfile_body) do - fixture("ruby", "gemfiles", "version_not_specified") - end + let(:project_name) { "nested_gemfile_version_not_specified" } let(:requirements) do [{ file: "Gemfile", @@ -239,9 +205,7 @@ end context "when a change is required" do - let(:child_gemfile_body) do - fixture("ruby", "gemfiles", "version_specified") - end + let(:project_name) { "nested_gemfile" } let(:requirements) do [{ file: "Gemfile", @@ -277,7 +241,6 @@ subject(:file) { updated_files.find { |f| f.name == "Gemfile.lock" } } context "when no change is required" do - let(:gemfile_fixture_name) { "Gemfile" } let(:dependency_version) { "1.4.0" } let(:requirements) do [{ file: "Gemfile", requirement: "~>1.4.0", groups: [], source: nil }] @@ -292,8 +255,7 @@ end context "when updating a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:project_name) { "subdependency" } let(:dependency_name) { "i18n" } let(:dependency_version) { "0.7.0" } let(:dependency_previous_version) { "0.7.0.beta1" } @@ -303,22 +265,20 @@ its(:content) { is_expected.to include("i18n (0.7.0)") } context "which is blocked by another sub-dep" do - let(:gemfile_fixture_name) { "subdep_blocked_by_subdep" } - let(:lockfile_fixture_name) { "subdep_blocked_by_subdep.lock" } + let(:project_name) { "subdep_blocked_by_subdep" } let(:dependency_name) { "dummy-pkg-a" } let(:dependency_version) { "1.1.0" } let(:dependency_previous_version) { "1.0.1" } it "updates the lockfile correctly" do expect(file.content).to include("dummy-pkg-a (1.1.0)") - expect(file.content).to_not include("\n dummy-pkg-a (= 1.1.0)") + expect(file.content).not_to include("\n dummy-pkg-a (= 1.1.0)") end end end context "when updating a dep blocked by a sub-dep" do - let(:gemfile_fixture_name) { "blocked_by_subdep" } - let(:lockfile_fixture_name) { "blocked_by_subdep.lock" } + let(:project_name) { "blocked_by_subdep" } let(:dependency_name) { "dummy-pkg-a" } let(:dependency_version) { "1.1.0" } let(:dependency_previous_version) { "1.0.1" } @@ -331,12 +291,14 @@ end context "when a gem has been yanked" do - let(:gemfile_fixture_name) { "minor_version_specified" } - let(:lockfile_fixture_name) { "yanked_gem.lock" } + let(:project_name) { "minor_version_specified_yanked_gem" } context "and it's that gem that we're attempting to bump" do it "locks the updated gem to the latest version" do expect(file.content).to include("business (1.5.0)") + end + + it "does not update unrelated dependencies" do expect(file.content).to include("statesman (1.2.1)") end end @@ -363,14 +325,21 @@ end it "locks the updated gem to the latest version" do - expect(file.content).to include("business (1.18.0)") expect(file.content).to include("statesman (1.3.1)") end + + it "locks the yanked gem to the latest version allowed by the Gemfile", :bundler_v1_only do + expect(file.content).to include("business (1.18.0)") + end + + it "does not touch the yanked gem", :bundler_v2_only do + expect(file.content).to include("business (1.4.1)") + end end end context "when the old Gemfile specified the version" do - let(:gemfile_fixture_name) { "version_specified" } + let(:project_name) { "version_specified_gemfile" } it "locks the updated gem to the latest version" do expect(file.content).to include("business (1.5.0)") @@ -380,31 +349,23 @@ expect(file.content).to include("statesman (1.2.1)") end - it "preserves the BUNDLED WITH line in the lockfile" do + it "preserves the BUNDLED WITH line in the lockfile", :bundler_v1_only do expect(file.content).to include("BUNDLED WITH\n 1.10.6") end + it "preserves the BUNDLED WITH line in the lockfile", :bundler_v2_only do + expect(file.content).to include("BUNDLED WITH\n 2.2.0") + end + it "doesn't add in a RUBY VERSION" do - expect(file.content).to_not include("RUBY VERSION") + expect(file.content).not_to include("RUBY VERSION") end context "for a gems.rb setup" do + let(:project_name) { "gems_rb" } + subject(:file) { updated_files.find { |f| f.name == "gems.locked" } } - let(:gemfile) do - Dependabot::DependencyFile.new( - name: "gems.rb", - content: gemfile_body, - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - name: "gems.locked", - content: lockfile_body, - directory: directory - ) - end let(:requirements) do [{ file: "gems.rb", @@ -429,8 +390,7 @@ end context "when unlocking another top-level dep would cause an error" do - let(:gemfile_fixture_name) { "cant_unlock_subdep" } - let(:lockfile_fixture_name) { "cant_unlock_subdep.lock" } + let(:project_name) { "cant_unlock_subdep" } let(:dependency_name) { "ibandit" } let(:dependency_version) { "0.11.5" } let(:dependency_previous_version) { "0.6.6" } @@ -459,17 +419,7 @@ end context "with a Gemfile that includes a file with require_relative" do - let(:dependency_files) { [gemfile, lockfile, required_file] } - let(:gemfile_fixture_name) { "includes_require_relative" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:required_file) do - Dependabot::DependencyFile.new( - name: "../some_other_file.rb", - content: "SOME_CONSTANT = 5", - directory: directory - ) - end - let(:directory) { "app/" } + let(:project_name) { "includes_require_relative_nested" } it "locks the updated gem to the latest version" do expect(file.content).to include("business (1.5.0)") @@ -477,8 +427,7 @@ end context "with a default gem specified" do - let(:gemfile_fixture_name) { "default_gem_specified" } - let(:lockfile_fixture_name) { "default_gem_specified.lock" } + let(:project_name) { "default_gem_specified" } let(:requirements) do [{ file: "Gemfile", requirement: "~> 1.5", groups: [], source: nil }] end @@ -491,9 +440,29 @@ end end + context "with an imported gemspec that specifies a minimum Ruby version not satisfied by the running Ruby" do + let(:project_name) { "unsatisfied_required_ruby_version" } + + before do + require "dependabot/bundler/file_updater/ruby_requirement_setter" + + stub_const( + "#{described_class}::RubyRequirementSetter::RUBY_VERSIONS", + described_class::RubyRequirementSetter::RUBY_VERSIONS + ["99.0.0"] + ) + end + + it "locks the updated gem to the latest version" do + expect(file.content).to include("business (1.5.0)") + end + + it "doesn't add in a RUBY VERSION" do + expect(file.content).not_to include("RUBY VERSION") + end + end + context "when the Gemfile specifies a Ruby version" do - let(:gemfile_fixture_name) { "explicit_ruby" } - let(:lockfile_fixture_name) { "explicit_ruby.lock" } + let(:project_name) { "explicit_ruby_in_lockfile" } it "locks the updated gem to the latest version" do expect(file.content).to include("business (1.5.0)") @@ -504,16 +473,15 @@ end context "but the lockfile didn't include that version" do - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:project_name) { "explicit_ruby" } it "doesn't add in a RUBY VERSION" do - expect(file.content).to_not include("RUBY VERSION") + expect(file.content).not_to include("RUBY VERSION") end end context "that is legacy" do - let(:gemfile_fixture_name) { "legacy_ruby" } - let(:lockfile_fixture_name) { "legacy_ruby.lock" } + let(:project_name) { "legacy_ruby" } let(:dependency) do Dependabot::Dependency.new( name: "public_suffix", @@ -546,13 +514,10 @@ end context "given a Gemfile that loads a .ruby-version file" do - let(:gemfile_fixture_name) { "ruby_version_file" } - let(:ruby_version_file) do - Dependabot::DependencyFile.new(content: "2.2", name: ".ruby-version") - end + let(:project_name) { "ruby_version_file" } let(:updater) do described_class.new( - dependency_files: [gemfile, lockfile, ruby_version_file], + dependency_files: dependency_files, dependencies: [dependency], credentials: [{ "type" => "git_source", @@ -567,16 +532,15 @@ end context "when the Gemfile.lock didn't have a BUNDLED WITH line" do - let(:lockfile_fixture_name) { "no_bundled_with.lock" } + let(:project_name) { "no_bundled_with" } it "doesn't add in a BUNDLED WITH" do - expect(file.content).to_not include "BUNDLED WITH" + expect(file.content).not_to include "BUNDLED WITH" end end context "when the old Gemfile didn't specify the version" do - let(:gemfile_fixture_name) { "version_not_specified" } - let(:lockfile_fixture_name) { "version_not_specified.lock" } + let(:project_name) { "version_not_specified" } it "locks the updated gem to the desired version" do expect(file.content).to include "business (1.5.0)" @@ -589,8 +553,7 @@ end context "with multiple dependencies" do - let(:gemfile_fixture_name) { "version_conflict" } - let(:lockfile_fixture_name) { "version_conflict.lock" } + let(:project_name) { "version_conflict" } let(:dependencies) do [ Dependabot::Dependency.new( @@ -635,8 +598,7 @@ end context "when another gem in the Gemfile has a git source" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } + let(:project_name) { "git_source" } let(:dependency) do Dependabot::Dependency.new( name: "statesman", @@ -669,17 +631,17 @@ end it "doesn't update the git dependencies" do - old_lock = lockfile_body.split(/^/) + old_lock = bundler_project_dependency_file("git_source", filename: "Gemfile.lock").content.split(/^/) new_lock = file.content.split(/^/) %w(business prius uk_phone_numbers).each do |dep| original_remote_line = - old_lock.find { |l| l.include?("gocardless/#{dep}") } + old_lock.find { |l| l.include?("dependabot-fixtures/#{dep}") } original_revision_line = old_lock[old_lock.find_index(original_remote_line) + 1] new_remote_line = - new_lock.find { |l| l.include?("gocardless/#{dep}") } + new_lock.find { |l| l.include?("dependabot-fixtures/#{dep}") } new_revision_line = new_lock[new_lock.find_index(original_remote_line) + 1] @@ -691,23 +653,22 @@ end context "that specifies the dependency using github:" do - let(:gemfile_fixture_name) { "github_source" } - let(:lockfile_fixture_name) { "github_source_bundler_2.lock" } + let(:project_name) { "github_source" } it "doesn't update the git dependencies" do - old_lock = lockfile_body.split(/^/) + old_lock = bundler_project_dependency_file("github_source", filename: "Gemfile.lock").content.split(/^/) new_lock = file.content.split(/^/) original_remote_line = - old_lock.find { |l| l.include?("gocardless/business") } + old_lock.find { |l| l.include?("dependabot-fixtures/business") } original_revision_line = old_lock[old_lock.find_index(original_remote_line) + 1] new_remote_line = - new_lock.find { |l| l.include?("gocardless/business") } + new_lock.find { |l| l.include?("dependabot-fixtures/business") } new_revision_line = - new_lock[new_lock.find_index(original_remote_line) + 1] + new_lock[new_lock.find_index(new_remote_line) + 1] expect(new_remote_line).to eq(original_remote_line) expect(new_revision_line).to eq(original_revision_line) @@ -717,8 +678,7 @@ end context "and the git dependency is used internally" do - let(:gemfile_fixture_name) { "git_source_internal" } - let(:lockfile_fixture_name) { "git_source_internal.lock" } + let(:project_name) { "git_source_internal" } it "doesn't update the git dependency's version" do expect(file.content).to include("parallel (1.12.0)") @@ -726,20 +686,21 @@ end context "and the git dependencies are in a weird order" do - let(:lockfile_fixture_name) { "git_source_reordered.lock" } + let(:project_name) { "git_source_reordered" } it "doesn't update the order of the git dependencies" do - old_lock = lockfile_body.split(/^/) + old_lock = bundler_project_dependency_file("git_source_reordered", + filename: "Gemfile.lock").content.split(/^/) new_lock = file.content.split(/^/) %w(business prius uk_phone_numbers).each do |dep| original_remote_line = - old_lock.find { |l| l.include?("gocardless/#{dep}") } + old_lock.find { |l| l.include?("dependabot-fixtures/#{dep}") } original_revision_line = old_lock[old_lock.find_index(original_remote_line) + 1] new_remote_line = - new_lock.find { |l| l.include?("gocardless/#{dep}") } + new_lock.find { |l| l.include?("dependabot-fixtures/#{dep}") } new_revision_line = new_lock[new_lock.find_index(original_remote_line) + 1] @@ -751,25 +712,25 @@ # Check that nothing strange has happened to the formatting anywhere expected_lockfile = - lockfile_body.gsub("1.2.5", "2.0.1").gsub("~> 1.2.0", "~> 2.0.1") + bundler_project_dependency_file("git_source_reordered", filename: "Gemfile.lock").content. + gsub("1.2.5", "2.0.1").gsub("~> 1.2.0", "~> 2.0.1") expect(file.content).to eq(expected_lockfile) end end context "and the lockfile was wrong before" do - let(:lockfile_fixture_name) { "git_source_outdated.lock" } + let(:project_name) { "git_source_outdated" } it "generates the correct lockfile" do expect(file.content).to include("statesman (2.0.1)") expect(file.content). - to include "remote: http://github.com/gocardless/uk_phone_numbers" + to include "remote: http://github.com/dependabot-fixtures/uk_phone_numbers" end end end context "for a git dependency" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } + let(:project_name) { "git_source" } let(:dependency) do Dependabot::Dependency.new( name: "prius", @@ -787,7 +748,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/prius", + url: "https://github.com/dependabot-fixtures/prius", branch: "master", ref: "master" } @@ -800,7 +761,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/prius", + url: "https://github.com/dependabot-fixtures/prius", branch: "master", ref: "master" } @@ -808,28 +769,27 @@ end it "updates the dependency's revision" do - old_lock = lockfile_body.split(/^/) + old_lock = dependency_files.find { |f| f.name == "Gemfile.lock" }.content.split(/^/) new_lock = file.content.split(/^/) original_remote_line = - old_lock.find { |l| l.include?("gocardless/prius") } + old_lock.find { |l| l.include?("dependabot-fixtures/prius") } original_revision_line = old_lock[old_lock.find_index(original_remote_line) + 1] new_remote_line = - new_lock.find { |l| l.include?("gocardless/prius") } + new_lock.find { |l| l.include?("dependabot-fixtures/prius") } new_revision_line = new_lock[new_lock.find_index(original_remote_line) + 1] expect(new_remote_line).to eq(original_remote_line) - expect(new_revision_line).to_not eq(original_revision_line) + expect(new_revision_line).not_to eq(original_revision_line) expect(new_lock.index(new_remote_line)). to eq(old_lock.index(original_remote_line)) end context "when a git source is specified that multiple deps use" do - let(:gemfile_fixture_name) { "git_source_with_multiple_deps" } - let(:lockfile_fixture_name) { "git_source_with_multiple_deps.lock" } + let(:project_name) { "git_source_with_multiple_deps" } let(:dependency) do Dependabot::Dependency.new( name: "elasticsearch-dsl", @@ -848,7 +808,7 @@ groups: [], source: { type: "git", - url: "https://github.com/elastic/elasticsearch-ruby", + url: "https://github.com/dependabot-fixtures/elasticsearch-ruby.git", branch: "5.x", ref: "5.x" } @@ -856,7 +816,7 @@ end it "updates the dependency's revision" do - old_lock = lockfile_body.split(/^/) + old_lock = dependency_files.find { |f| f.name == "Gemfile.lock" }.content.split(/^/) new_lock = file.content.split(/^/) original_remote_line = @@ -867,10 +827,10 @@ new_remote_line = new_lock.find { |l| l.include?("elasticsearch-ruby") } new_revision_line = - new_lock[new_lock.find_index(original_remote_line) + 1] + new_lock[new_lock.find_index(new_remote_line) + 1] expect(new_remote_line).to eq(original_remote_line) - expect(new_revision_line).to_not eq(original_revision_line) + expect(new_revision_line).not_to eq(original_revision_line) expect(new_lock.index(new_remote_line)). to eq(old_lock.index(original_remote_line)) end @@ -878,8 +838,7 @@ context "that specifies a version that needs updating" do context "with a gem that has a git source" do - let(:gemfile_fixture_name) { "git_source_with_version" } - let(:lockfile_fixture_name) { "git_source_with_version.lock" } + let(:project_name) { "git_source_with_version_gemfile" } let(:dependency) do Dependabot::Dependency.new( name: "dependabot-test-ruby-package", @@ -897,8 +856,8 @@ groups: [], source: { type: "git", - url: "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package" + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" } }] end @@ -909,8 +868,8 @@ groups: [], source: { type: "git", - url: "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package" + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" } }] end @@ -922,20 +881,8 @@ end context "when another gem in the Gemfile has a path source" do - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } - context "that we've downloaded" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "no_overlap") } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "plugins/example/example.gemspec", - support_file: true - ) - end - - let(:dependency_files) { [gemfile, lockfile, gemspec] } + let(:project_name) { "path_source_no_overlap" } it "updates the gem just fine" do expect(file.content).to include "business (1.5.0)" @@ -944,22 +891,13 @@ it "does not change the original path" do expect(file.content).to include "remote: plugins/example" expect(file.content). - not_to include Dependabot::SharedHelpers::BUMP_TMP_FILE_PREFIX + not_to include Dependabot::Utils::BUMP_TMP_FILE_PREFIX expect(file.content). - not_to include Dependabot::SharedHelpers::BUMP_TMP_DIR_PATH + not_to include Dependabot::Utils::BUMP_TMP_DIR_PATH end context "as a .specification" do - let(:dependency_files) { [gemfile, lockfile, specification] } - let(:gemfile_fixture_name) { "path_source_statesman" } - let(:lockfile_fixture_name) { "path_source_statesman.lock" } - let(:specification) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "specifications", "statesman"), - name: "vendor/gems/statesman-4.1.1/.specification", - support_file: true - ) - end + let(:project_name) { "path_source_statesman" } it "updates the gem just fine" do expect(file.content).to include "business (1.5.0)" @@ -983,16 +921,7 @@ end context "when the Gemfile evals a child gemfile" do - let(:dependency_files) { [gemfile, lockfile, child_gemfile] } - let(:gemfile_fixture_name) { "eval_gemfile" } - let(:child_gemfile) do - Dependabot::DependencyFile.new( - content: child_gemfile_body, - name: "backend/Gemfile" - ) - end - let(:child_gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } - let(:lockfile_fixture_name) { "path_source.lock" } + let(:project_name) { "eval_gemfile_gemfile" } let(:requirements) do [{ file: "Gemfile", @@ -1052,17 +981,7 @@ end context "with a Gemfile that imports a gemspec" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "small_example") } - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:lockfile_fixture_name) { "imports_gemspec.lock" } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "example.gemspec" - ) - end - - let(:dependency_files) { [gemfile, lockfile, gemspec] } + let(:project_name) { "imports_gemspec" } context "when the gem in the gemspec isn't being updated" do let(:dependency) do @@ -1149,14 +1068,8 @@ end context "when updating a gemspec with a path" do - let(:gemfile_fixture_name) { "imports_gemspec_from_path" } - let(:lockfile_fixture_name) { "imports_gemspec_from_path.lock" } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "subdir/example.gemspec" - ) - end + let(:project_name) { "imports_gemspec_from_path" } + let(:dependency) do Dependabot::Dependency.new( name: "business", @@ -1195,8 +1108,7 @@ end context "and only appears in the gemspec" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "no_overlap") } - let(:lockfile_fixture_name) { "imports_gemspec_no_overlap.lock" } + let(:project_name) { "imports_gemspec_no_overlap" } let(:dependency) do Dependabot::Dependency.new( name: "json", @@ -1228,15 +1140,7 @@ end context "when provided with only a gemspec" do - let(:dependency_files) { [gemspec] } - - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "example.gemspec" - ) - end - let(:gemspec_body) { fixture("ruby", "gemspecs", "example") } + let(:project_name) { "gemspec_no_lockfile" } let(:dependency) do Dependabot::Dependency.new( name: dependency_name, @@ -1340,16 +1244,7 @@ end context "when provided with a Gemfile and a gemspec" do - let(:dependency_files) { [gemfile, gemspec] } - - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "example.gemspec" - ) - end - let(:gemspec_body) { fixture("ruby", "gemspecs", "example") } - let(:gemfile_fixture_name) { "imports_gemspec" } + let(:project_name) { "imports_gemspec_no_lockfile" } let(:dependency) do Dependabot::Dependency.new( name: dependency_name, @@ -1384,7 +1279,7 @@ end context "when the gem appears in both" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "small_example") } + let(:project_name) { "imports_gemspec_small_example_no_lockfile" } let(:dependency_name) { "business" } let(:requirements) do [{ @@ -1436,7 +1331,7 @@ end context "when provided with only a Gemfile" do - let(:dependency_files) { [gemfile] } + let(:project_name) { "no_lockfile" } describe "the updated gemfile" do subject(:updated_gemfile) do @@ -1448,13 +1343,7 @@ end context "with a Gemfile, Gemfile.lock and gemspec (not imported)" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", "with_require"), - name: "some.gemspec" - ) - end + let(:project_name) { "gemspec_not_imported" } context "with a dependency that appears in the Gemfile" do let(:dependency) do @@ -1492,13 +1381,13 @@ Dependabot::Dependency.new( name: "octokit", requirements: [{ - file: "some.gemspec", + file: "example.gemspec", requirement: ">= 4.6, < 6.0", groups: [], source: nil }], previous_requirements: [{ - file: "some.gemspec", + file: "example.gemspec", requirement: "~> 4.6", groups: [], source: nil @@ -1509,7 +1398,7 @@ describe "the updated gemspec" do subject(:updated_gemspec) do - updated_files.find { |f| f.name == "some.gemspec" } + updated_files.find { |f| f.name == "example.gemspec" } end its(:content) do @@ -1520,7 +1409,7 @@ end context "when provided with only a Gemfile.lock" do - let(:dependency_files) { [lockfile] } + let(:project_name) { "lockfile_only" } it "raises on initialization" do expect { updater }.to raise_error(/Gemfile must be provided/) @@ -1528,17 +1417,226 @@ end context "when provided with only a gemspec and Gemfile.lock" do - let(:dependency_files) { [lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", "example"), - name: "example.gemspec" - ) - end + let(:project_name) { "gemspec_no_gemfile" } it "raises on initialization" do expect { updater }.to raise_error(/Gemfile must be provided/) end end + + context "for a gem that depends on bundler" do + subject(:updated_gemfile) do + updated_files.find { |f| f.name == "Gemfile" } + end + + let(:project_name) { "guard_bundler" } + let(:dependency_name) { "guard-bundler" } + let(:dependency_version) { "3.0.0" } + let(:dependency_previous_version) { "2.2.1" } + let(:requirements) do + [{ + file: "Gemfile", + requirement: "~> 2.2.1", + groups: [], + source: nil + }] + end + + it "raises an error", :bundler_v1_only do + expect { updated_gemfile }.to raise_error(/Bundler could not find compatible versions for gem "bundler"/) + end + + it "returns the latest version", :bundler_v2_only do + expect(updated_gemfile.content).to include("\"guard-bundler\", \"~> 2.2.1\"") + end + end + + context "vendoring" do + let(:project_name) { "vendored_gems" } + let(:repo_contents_path) { bundler_build_tmp_repo(project_name) } + + before do + stub_request(:get, "https://rubygems.org/gems/business-1.5.0.gem"). + to_return( + status: 200, + body: fixture("ruby", "gems", "business-1.5.0.gem") + ) + end + + after do + FileUtils.remove_entry repo_contents_path + ::Bundler.settings.temporary(persistent_gems_after_clean: nil) + end + + it "vendors the new dependency" do + expect(updater.updated_dependency_files.map(&:name)).to match_array( + [ + "vendor/cache/business-1.4.0.gem", + "vendor/cache/business-1.5.0.gem", + "Gemfile", + "Gemfile.lock" + ] + ) + end + + it "base64 encodes vendored gems" do + file = updater.updated_dependency_files.find do |f| + f.name == "vendor/cache/business-1.5.0.gem" + end + + expect(file.content_encoding).to eq("base64") + end + + it "deletes the old vendored gem" do + file = updater.updated_dependency_files.find do |f| + f.name == "vendor/cache/business-1.4.0.gem" + end + + expect(file.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end + + context "persistent gems after clean" do + let(:project_name) { "vendored_persistent_gems" } + + it "does not delete cached files marked as persistent" do + file = updater.updated_dependency_files.find do |f| + f.name == "vendor/cache/business-1.4.0.gem" + end + + vendor_files = + Dir.entries(Pathname.new(repo_contents_path).join("vendor/cache")) + + expect(file).to be_nil + expect(vendor_files).to include("business-1.4.0.gem") + end + end + + context "with dependencies that are not unlocked by the update" do + let(:project_name) { "conditional" } + + before do + stub_request(:get, "https://rubygems.org/gems/statesman-1.2.1.gem"). + to_return( + status: 200, + body: fixture("ruby", "gems", "statesman-1.2.1.gem") + ) + end + + it "does not delete the cached file" do + file = updater.updated_dependency_files.find do |f| + f.name == "vendor/cache/addressable-7.2.0.gem" + end + vendor_files = + Dir.entries(Pathname.new(repo_contents_path).join("vendor/cache")) + + expect(file).to be_nil + expect(vendor_files).to include("statesman-7.2.0.gem") + end + end + + context "with a git dependency" do + let(:project_name) { "vendored_git" } + + let(:dependency) do + Dependabot::Dependency.new( + name: "dependabot-test-ruby-package", + version: "1c6331732c41e4557a16dacb82534f1d1c831848", + previous_version: "81073f9462f228c6894e3e384d0718def310d99f", + requirements: requirements, + previous_requirements: previous_requirements, + package_manager: "bundler" + ) + end + let(:requirements) do + [{ + file: "Gemfile", + requirement: "~> 1.0.1", + groups: [], + source: { + type: "git", + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" + } + }] + end + let(:previous_requirements) do + [{ + file: "Gemfile", + requirement: "~> 1.0.0", + groups: [], + source: { + type: "git", + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package" + } + }] + end + + removed = "vendor/cache/dependabot-test-ruby-package-81073f9462f2" + added = "vendor/cache/dependabot-test-ruby-package-1c6331732c41" + + it "vendors the new dependency" do + expect(updater.updated_dependency_files.map(&:name)).to match_array( + [ + "#{removed}/.bundlecache", + "#{removed}/README.md", + "#{removed}/test-ruby-package.gemspec", + "#{added}/.bundlecache", + "#{added}/.gitignore", + "#{added}/README.md", + "#{added}/dependabot-test-ruby-package.gemspec", + # modified: + "Gemfile", + "Gemfile.lock" + ] + ) + end + + it "deletes the old vendored repo" do + file = updater.updated_dependency_files.find do |f| + f.name == "#{removed}/.bundlecache" + end + + expect(file&.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end + + it "does not base64 encode vendored code" do + updater.updated_dependency_files. + select { |f| f.name.start_with?(added) }. + reject { |f| f.name.end_with?(".bundlecache") }. + each { |f| expect(f.content_encoding).to eq("") } + end + end + end + + context "vendoring with subdir" do + let(:project_name) { "vendored_gems_with_subdir" } + let(:directory) { "/acceptance" } + let(:repo_contents_path) { bundler_build_tmp_repo(project_name) } + + before do + stub_request(:get, "https://rubygems.org/gems/business-1.5.0.gem"). + to_return( + status: 200, + body: fixture("ruby", "gems", "business-1.5.0.gem") + ) + end + + after do + FileUtils.remove_entry repo_contents_path + ::Bundler.settings.temporary(persistent_gems_after_clean: nil) + end + + it "vendors the new dependency" do + expect(updater.updated_dependency_files.map(&:name)).to match_array( + [ + "vendor/cache/business-1.4.0.gem", + "vendor/cache/business-1.5.0.gem", + "Gemfile", + "Gemfile.lock" + ] + ) + end + end end end diff --git a/bundler/spec/dependabot/bundler/helper_spec.rb b/bundler/spec/dependabot/bundler/helper_spec.rb new file mode 100644 index 00000000000..d9b88a06715 --- /dev/null +++ b/bundler/spec/dependabot/bundler/helper_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require "spec_helper" + +require "dependabot/bundler/helpers" + +RSpec.describe Dependabot::Bundler::Helpers do + let(:no_lockfile) { nil } + + let(:lockfile_bundled_with_missing) do + Dependabot::DependencyFile.new(name: "Gemfile.lock", content: <<~LOCKFILE) + Mock Gemfile.lock Content Goes Here + LOCKFILE + end + + let(:lockfile_bundled_with_v1) do + Dependabot::DependencyFile.new(name: "Gemfile.lock", content: <<~LOCKFILE) + Mock Gemfile.lock Content Goes Here + + BUNDLED WITH + 1.17.3 + LOCKFILE + end + + let(:lockfile_bundled_with_v2) do + Dependabot::DependencyFile.new(name: "Gemfile.lock", content: <<~LOCKFILE) + Mock Gemfile.lock Content Goes Here + + BUNDLED WITH + 2.2.11 + LOCKFILE + end + + let(:lockfile_bundled_with_future_version) do + Dependabot::DependencyFile.new(name: "Gemfile.lock", content: <<~LOCKFILE) + Mock Gemfile.lock Content Goes Here + + BUNDLED WITH + 3.9.99 + LOCKFILE + end + + describe "#bundler_version" do + def described_method(lockfile) + described_class.bundler_version(lockfile) + end + + it "is 2 if there is no lockfile" do + expect(described_method(no_lockfile)).to eql("2") + end + + it "is 1 if there is no bundled with string" do + expect(described_method(lockfile_bundled_with_missing)).to eql("1") + end + + it "is 1 if it was bundled with a v1.x version" do + expect(described_method(lockfile_bundled_with_v1)).to eql("1") + end + + it "is 2 if it was bundled with a v2.x version" do + expect(described_method(lockfile_bundled_with_v2)).to eql("2") + end + + it "is 2 if it was bundled with a future version" do + expect(described_method(lockfile_bundled_with_future_version)).to eql("2") + end + end + + describe "#detected_bundler_version" do + def described_method(lockfile) + described_class.detected_bundler_version(lockfile) + end + + it "is unknown if there is no lockfile" do + expect(described_method(no_lockfile)).to eql("unknown") + end + + it "is 1 if there is no bundled with string" do + expect(described_method(lockfile_bundled_with_missing)).to eql("1") + end + + it "is 1 if it was bundled with a v1.x version" do + expect(described_method(lockfile_bundled_with_v1)).to eql("1") + end + + it "is 2 if it was bundled with a v2.x version" do + expect(described_method(lockfile_bundled_with_v2)).to eql("2") + end + + it "is 1 if it was bundled with a future version" do + expect(described_method(lockfile_bundled_with_future_version)).to eql("3") + end + end +end diff --git a/bundler/spec/dependabot/bundler/metadata_finder_spec.rb b/bundler/spec/dependabot/bundler/metadata_finder_spec.rb index e216b38f1b9..086bf397c50 100644 --- a/bundler/spec/dependabot/bundler/metadata_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/metadata_finder_spec.rb @@ -33,6 +33,20 @@ end let(:dependency_name) { "business" } + before do + stub_request(:get, "https://example.com/status").to_return( + status: 200, + body: "Not GHES", + headers: {} + ) + + stub_request(:get, "https://www.rubydoc.info/status").to_return( + status: 200, + body: "Not GHES", + headers: {} + ) + end + describe "#source_url" do subject(:source_url) { finder.source_url } @@ -63,7 +77,7 @@ "https://repo.fury.io/grey/quick/Marshal.4.8/business-1.0.gemspec.rz" end let(:gemspec_response) do - fixture("ruby", "rubygems_responses", "business-1.0.0.gemspec.rz") + fixture("rubygems_responses", "business-1.0.0.gemspec.rz") end let(:rubygems_response) { fixture("ruby", "rubygems_response.json") } before do @@ -105,6 +119,60 @@ it { is_expected.to eq("https://github.com/gocardless/business") } end + context "with a replaces-base credential" do + before do + stub_request(:get, "https://gems.example.com/api/v1/gems/business.json"). + to_return( + status: 200, + body: fixture("ruby", "rubygems_response.json") + ) + end + + let(:source) do + { type: "rubygems", url: "https://gems.example.com/" } + end + let(:credentials) do + [ + { + "type" => "rubygems_server", + "host" => "gems.greysteil.com", + "replaces-base" => true + } + ] + end + + it "prefers the source URL still" do + expect(finder.source_url). + to eq("https://github.com/gocardless/business") + expect(WebMock). + to have_requested( + :get, + "https://gems.example.com/api/v1/gems/business.json" + ) + expect(WebMock).to_not have_requested(:get, rubygems_gemspec_url) + end + + context "but with no source" do + let(:source) { nil } + + before do + stub_request(:get, "https://gems.greysteil.com/api/v1/gems/business.json"). + to_return( + status: 200, + body: fixture("ruby", "rubygems_response.json") + ) + end + + it "uses the replaces-base URL" do + expect(finder.source_url). + to eq("https://github.com/gocardless/business") + expect(WebMock). + to have_requested(:get, "https://gems.greysteil.com/api/v1/gems/business.json") + expect(WebMock).to_not have_requested(:get, rubygems_gemspec_url) + end + end + end + context "without a source" do let(:rubygems_response) do fixture("ruby", "rubygems_response_no_source.json") @@ -377,12 +445,12 @@ context "when there is a changelog link in the rubygems response" do let(:rubygems_response) do - fixture("ruby", "rubygems_responses", "api_changelog_uri.json") + fixture("rubygems_responses", "api_changelog_uri.json") end it "gets the URL from the changelog_uri" do expect(suggested_changelog_url).to eq( - "https://github.com/rails/rails/blob/v5.2.2/"\ + "https://github.com/rails/rails/blob/v5.2.2/" \ "activerecord/CHANGELOG.md" ) end @@ -421,7 +489,7 @@ "https://repo.fury.io/grey/quick/Marshal.4.8/business-1.0.gemspec.rz" end let(:gemspec_response) do - fixture("ruby", "rubygems_responses", "business-1.0.0.gemspec.rz") + fixture("rubygems_responses", "business-1.0.0.gemspec.rz") end context "but the response is a 400" do @@ -440,7 +508,7 @@ context "and there is a changelog URL in the gemspec" do let(:gemspec_response) do fixture( - "ruby", "rubygems_responses", "activerecord-5.2.1.gemspec.rz" + "rubygems_responses", "activerecord-5.2.1.gemspec.rz" ) end diff --git a/bundler/spec/dependabot/bundler/native_helpers_spec.rb b/bundler/spec/dependabot/bundler/native_helpers_spec.rb new file mode 100644 index 00000000000..0bf5c13dfb9 --- /dev/null +++ b/bundler/spec/dependabot/bundler/native_helpers_spec.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/bundler/native_helpers" + +RSpec.describe Dependabot::Bundler::NativeHelpers do + subject { described_class } + + describe ".run_bundler_subprocess" do + let(:options) { {} } + + let(:native_helpers_path) { "/opt" } + + before do + allow(Dependabot::SharedHelpers).to receive(:run_helper_subprocess) + + with_env("DEPENDABOT_NATIVE_HELPERS_PATH", native_helpers_path) do + subject.run_bundler_subprocess( + function: "noop", + args: [], + bundler_version: "2", + options: options + ) + end + end + + context "with a timeout provided" do + let(:options) { { timeout_per_operation_seconds: 120 } } + + it "terminates the spawned process when the timeout is exceeded" do + expect(Dependabot::SharedHelpers). + to have_received(:run_helper_subprocess). + with( + command: "timeout -s HUP 120 ruby /opt/bundler/v2/run.rb", + function: "noop", + args: [], + env: anything + ) + end + end + + context "with a timeout that is too high" do + let(:thirty_minutes_plus_one_second) { 1801 } + let(:options) do + { + timeout_per_operation_seconds: thirty_minutes_plus_one_second + } + end + + it "applies the maximum timeout" do + expect(Dependabot::SharedHelpers). + to have_received(:run_helper_subprocess). + with( + command: "timeout -s HUP 1800 ruby /opt/bundler/v2/run.rb", + function: "noop", + args: [], + env: anything + ) + end + end + + context "with a timeout that is too low" do + let(:fifty_nine_seconds) { 59 } + let(:options) do + { + timeout_per_operation_seconds: fifty_nine_seconds + } + end + + it "applies the minimum timeout" do + expect(Dependabot::SharedHelpers). + to have_received(:run_helper_subprocess). + with( + command: "timeout -s HUP 60 ruby /opt/bundler/v2/run.rb", + function: "noop", + args: [], + env: anything + ) + end + end + + context "without a timeout" do + let(:options) { {} } + + it "does not apply a timeout" do + expect(Dependabot::SharedHelpers). + to have_received(:run_helper_subprocess). + with( + command: "ruby /opt/bundler/v2/run.rb", + function: "noop", + args: [], + env: anything + ) + end + end + + context "with DEPENDABOT_NATIVE_HELPERS_PATH not set" do + let(:native_helpers_path) { nil } + + it "uses the full path to the uninstalled run.rb command" do + expect(Dependabot::SharedHelpers). + to have_received(:run_helper_subprocess). + with( + command: "ruby #{File.expand_path('../../../helpers/v2/run.rb', __dir__)}", + function: "noop", + args: [], + env: anything + ) + end + end + + private + + def with_env(key, value) + previous_value = ENV.fetch(key, nil) + ENV[key] = value + yield + ensure + ENV[key] = previous_value + end + end +end diff --git a/bundler/spec/dependabot/bundler/update_checker/conflicting_dependency_resolver_spec.rb b/bundler/spec/dependabot/bundler/update_checker/conflicting_dependency_resolver_spec.rb new file mode 100644 index 00000000000..b3efbd7b467 --- /dev/null +++ b/bundler/spec/dependabot/bundler/update_checker/conflicting_dependency_resolver_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require "spec_helper" +require "shared_contexts" +require "dependabot/dependency" +require "dependabot/dependency_file" +require "dependabot/bundler/update_checker/conflicting_dependency_resolver" + +RSpec.describe(Dependabot::Bundler::UpdateChecker::ConflictingDependencyResolver) do + include_context "stub rubygems compact index" + + let(:resolver) do + described_class.new( + dependency_files: dependency_files, + repo_contents_path: nil, + credentials: [{ + "type" => "git_source", + "host" => "github.com", + "username" => "x-access-token", + "password" => "token" + }], + options: {} + ) + end + let(:dependency_files) do + bundler_project_dependency_files("subdep_blocked_by_subdep") + end + + let(:dependency) do + Dependabot::Dependency.new( + name: dependency_name, + version: current_version, + requirements: [], + package_manager: "bundler" + ) + end + let(:dependency_name) { "dummy-pkg-a" } + let(:current_version) { "1.0.1" } + let(:target_version) { "2.0.0" } + + describe "#conflicting_dependencies" do + subject(:conflicting_dependencies) do + resolver.conflicting_dependencies( + dependency: dependency, + target_version: target_version + ) + end + + it "returns the right array of blocking dependencies" do + expect(conflicting_dependencies).to match_array( + [ + { + "explanation" => "dummy-pkg-b (1.0.0) requires dummy-pkg-a (< 2.0.0)", + "name" => "dummy-pkg-b", + "version" => "1.0.0", + "requirement" => "< 2.0.0" + } + ] + ) + end + + context "with no blocking dependencies" do + let(:target_version) { "1.5.0" } + + it "returns an empty array" do + expect(conflicting_dependencies).to match_array([]) + end + end + end +end diff --git a/bundler/spec/dependabot/bundler/update_checker/file_preparer_spec.rb b/bundler/spec/dependabot/bundler/update_checker/file_preparer_spec.rb index 345c4b34ef8..4671c0ed0b4 100644 --- a/bundler/spec/dependabot/bundler/update_checker/file_preparer_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker/file_preparer_spec.rb @@ -16,8 +16,6 @@ ) end - let(:dependency_files) { [gemfile, lockfile] } - let(:dependency) do Dependabot::Dependency.new( name: dependency_name, @@ -37,14 +35,7 @@ let(:replacement_git_pin) { nil } let(:latest_allowable_version) { nil } - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") - end - let(:lockfile) do - Dependabot::DependencyFile.new(content: lockfile_body, name: "Gemfile.lock") - end - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } - let(:lockfile_body) { fixture("ruby", "lockfiles", "Gemfile.lock") } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } describe "#prepared_dependency_files" do subject(:prepared_dependency_files) { preparer.prepared_dependency_files } @@ -53,7 +44,6 @@ subject { prepared_dependency_files.find { |f| f.name == "Gemfile" } } context "with a ~> matcher" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } let(:version) { "1.4.3" } its(:content) { is_expected.to include(%("business", ">= 1.4.3"\n)) } @@ -75,21 +65,9 @@ end context "with a gems.rb and gems.locked setup" do + let(:dependency_files) { bundler_project_dependency_files("gems_rb") } subject { prepared_dependency_files.find { |f| f.name == "gems.rb" } } - let(:gemfile) do - Dependabot::DependencyFile.new( - content: gemfile_body, - name: "gems.rb" - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: lockfile_body, - name: "gems.locked" - ) - end - it "returns the right files" do expect(prepared_dependency_files.map(&:name)). to match_array(%w(gems.rb gems.locked)) @@ -114,44 +92,36 @@ end context "within a source block" do - let(:gemfile_body) do - "source 'https://example.com' do\n"\ - " gem \"business\", \"~> 1.0\", require: true\n"\ - "end" - end + let(:dependency_files) { bundler_project_dependency_files("source_block_gemfile") } let(:version) { "1.4.3" } its(:content) { is_expected.to include(%("business", ">= 1.4.3")) } end context "with multiple requirements" do + let(:dependency_files) { bundler_project_dependency_files("gemfile_multiple_requirements") } let(:version) { "1.4.3" } - let(:gemfile_body) { %(gem "business", ">= 1", "< 3", require: true) } its(:content) do - is_expected.to eq(%(gem "business", ">= 1.4.3", require: true)) + is_expected.to eq(%(gem "business", ">= 1.4.3", require: true\n)) end context "given as an array" do - let(:gemfile_body) do - %(gem "business", [">= 1", "<3"], require: true) - end + let(:dependency_files) { bundler_project_dependency_files("gemfile_multiple_requirements_array") } its(:content) do - is_expected.to eq(%(gem "business", ">= 1.4.3", require: true)) + is_expected.to eq(%(gem "business", ">= 1.4.3", require: true\n)) end end end context "with a git source" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "git_source") } + let(:dependency_files) { bundler_project_dependency_files("git_source_gemfile") } let(:version) { "df9f605d7111b6814fe493cf8f41de3f9f0978b2" } let(:dependency_name) { "prius" } its(:content) { is_expected.to include(%("prius", ">= 0", git:)) } context "and a version specified" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "git_source_with_version") - end + let(:dependency_files) { bundler_project_dependency_files("git_source_with_version_gemfile") } let(:dependency_name) { "dependabot-test-ruby-package" } its(:content) do @@ -167,56 +137,47 @@ its(:content) { is_expected.to include(%("que", git:)) } context "with a tag (i.e., multiple git-related arguments)" do + let(:dependency_files) { bundler_project_dependency_files("git_source_gemfile") } let(:dependency_name) { "que" } its(:content) { is_expected.to include(%("que", ">= 0"\n)) } end context "with non-git tags at the start" do - let(:gemfile_body) do - %(gem "prius", "1.0.0", require: false, git: "git_url") - end + let(:dependency_files) { bundler_project_dependency_files("non_git_tags_at_start_gemfile") } its(:content) do - is_expected.to eq(%(gem "prius", ">= 0", require: false)) + is_expected.to eq(%(gem "prius", ">= 0", require: false\n)) end end context "with non-git tags at the end" do - let(:gemfile_body) do - %(gem "prius", "1.0.0", git: "git_url", require: false) - end + let(:dependency_files) { bundler_project_dependency_files("non_git_tags_at_end_gemfile") } its(:content) do - is_expected.to eq(%(gem "prius", ">= 0", require: false)) + is_expected.to eq(%(gem "prius", ">= 0", require: false\n)) end end context "with non-git tags on a subsequent line" do - let(:gemfile_body) do - %(gem "prius", "1.0.0", git: "git_url",\nrequire: false) - end + let(:dependency_files) { bundler_project_dependency_files("non_git_tags_on_newline_gemfile") } its(:content) do - is_expected.to eq(%(gem "prius", ">= 0", require: false)) + is_expected.to eq(%(gem "prius", ">= 0", require: false\n)) end end context "with git tags on a subsequent line" do - let(:gemfile_body) do - %(gem "prius", "1.0.0", require: false,\ngit: "git_url") - end + let(:dependency_files) { bundler_project_dependency_files("git_tags_on_newline_gemfile") } its(:content) do - is_expected.to eq(%(gem "prius", ">= 0", require: false)) + is_expected.to eq(%(gem "prius", ">= 0", require: false\n)) end end context "with a custom tag" do - let(:gemfile_body) { %(gem "prius", "1.0.0", github: "git_url") } - its(:content) { is_expected.to eq(%(gem "prius", ">= 0")) } + let(:dependency_files) { bundler_project_dependency_files("custom_tag_gemfile") } + its(:content) { is_expected.to eq(%(gem "prius", ">= 0"\n)) } end context "with a comment" do - let(:gemfile_body) do - %(gem "prius", "1.0.0", git: "git_url" # My gem) - end - its(:content) { is_expected.to eq(%(gem "prius", ">= 0" # My gem)) } + let(:dependency_files) { bundler_project_dependency_files("comment_gemfile") } + its(:content) { is_expected.to eq(%(gem "prius", ">= 0" # My gem\n)) } end end @@ -228,21 +189,14 @@ end context "with a function call" do - let(:gemfile_body) { "gem \"business\", version" } + let(:dependency_files) { bundler_project_dependency_files("function_version_gemfile") } let(:version) { "1.4.3" } its(:content) { is_expected.to include(%("business", version)) } end context "with a required ruby version in the gemspec" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "example.gemspec" - ) - end - let(:gemspec_body) { fixture("ruby", "gemspecs", "old_required_ruby") } + let(:dependency_files) { bundler_project_dependency_files("gemfile_old_required_ruby") } let(:version) { "1.4.3" } its(:content) { is_expected.to include("ruby '1.9.3'") } @@ -266,14 +220,7 @@ end describe "the updated gemspec" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "example.gemspec" - ) - end - let(:gemspec_body) { fixture("ruby", "gemspecs", "small_example") } + let(:dependency_files) { bundler_project_dependency_files("gemfile_small_example") } let(:version) { "1.4.3" } subject do @@ -283,7 +230,7 @@ its(:content) { is_expected.to include("'business', '>= 1.4.3'\n") } context "when the file requires sanitizing" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "with_require") } + let(:dependency_files) { bundler_project_dependency_files("gemfile_with_require") } let(:dependency_name) { "gitlab" } its(:content) { is_expected.to include(%("gitlab", ">= 1.4.3"\n)) } @@ -314,50 +261,45 @@ context "with multiple requirements" do let(:version) { "1.4.3" } - let(:gemspec_body) { %(spec.add_dependency "business", ">= 1", "< 3") } + let(:gemspec_fixture_name) { "multiple_requirements" } + let(:dependency_files) { bundler_project_dependency_files("gemspec_multiple_requirements") } its(:content) do - is_expected.to eq(%(spec.add_dependency "business", ">= 1.4.3")) + is_expected.to eq(%(spec.add_dependency "business", ">= 1.4.3"\n)) end context "given as an array" do - let(:gemspec_body) do - %(spec.add_dependency "business", [">= 1", "<3"]) - end + let(:dependency_files) { bundler_project_dependency_files("gemspec_multiple_requirements_array") } + let(:gemspec_fixture_name) { "multiple_requirements_array" } its(:content) do - is_expected.to eq(%(spec.add_dependency "business", ">= 1.4.3")) + is_expected.to eq(%(spec.add_dependency "business", ">= 1.4.3"\n)) end end end context "with parentheses" do let(:version) { "1.4.3" } - let(:gemspec_body) { %(spec.add_dependency("business", ">= 1", "< 3")) } + let(:dependency_files) { bundler_project_dependency_files("gemfile_multiple_requirements_parenthesis") } its(:content) do - is_expected.to eq(%(spec.add_dependency("business", ">= 1.4.3"))) + is_expected.to eq(%(spec.add_dependency("business", ">= 1.4.3")\n)) end end end describe "the updated path gemspec" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: gemspec_body, - name: "some/example.gemspec", - support_file: true - ) + let(:dependency_files) do + bundler_project_dependency_files("nested_gemspec").tap do |files| + file = files.find { |f| f.name == "some/example.gemspec" } + file.support_file = true + end end - let(:gemspec_body) { fixture("ruby", "gemspecs", "small_example") } + subject { prepared_dependency_files.find { |f| f.name == "some/example.gemspec" } } let(:version) { "1.4.3" } - subject do - prepared_dependency_files.find { |f| f.name == "some/example.gemspec" } - end - - its(:content) { is_expected.to include("'business', '~> 1.0'\n") } + its(:content) { is_expected.to include(%("business", "~> 1.0")) } context "when the file requires sanitizing" do - let(:gemspec_body) { fixture("ruby", "gemspecs", "with_require") } + subject { prepared_dependency_files.find { |f| f.name == "example.gemspec" } } + let(:dependency_files) { bundler_project_dependency_files("gemfile_with_require") } its(:content) { is_expected.to include("begin\nrequire ") } its(:content) { is_expected.to include(%(version = "0.0.1")) } @@ -365,15 +307,7 @@ end describe "the updated child gemfile" do - let(:dependency_files) { [gemfile, lockfile, child_gemfile] } - let(:child_gemfile) do - Dependabot::DependencyFile.new( - content: child_gemfile_body, - name: "backend/Gemfile" - ) - end - let(:gemfile_body) { fixture("ruby", "gemfiles", "eval_gemfile") } - let(:child_gemfile_body) { fixture("ruby", "gemfiles", "Gemfile") } + let(:dependency_files) { bundler_project_dependency_files("nested_gemfile") } let(:version) { "1.4.3" } subject do diff --git a/bundler/spec/dependabot/bundler/update_checker/force_updater_spec.rb b/bundler/spec/dependabot/bundler/update_checker/force_updater_spec.rb index 82c27846e60..1c0fd2ff978 100644 --- a/bundler/spec/dependabot/bundler/update_checker/force_updater_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker/force_updater_spec.rb @@ -20,10 +20,11 @@ "host" => "github.com", "username" => "x-access-token", "password" => "token" - }] + }], + options: {} ) end - let(:dependency_files) { [gemfile, lockfile] } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } let(:dependency) do Dependabot::Dependency.new( @@ -54,21 +55,11 @@ }] end - let(:gemfile) do - Dependabot::DependencyFile.new(content: gemfile_body, name: "Gemfile") - end - let(:lockfile) do - Dependabot::DependencyFile.new(content: lockfile_body, name: "Gemfile.lock") - end - describe "#updated_dependencies" do subject(:updated_dependencies) { updater.updated_dependencies } context "when updating the dependency that requires the other" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "version_conflict") } - let(:lockfile_body) do - fixture("ruby", "lockfiles", "version_conflict.lock") - end + let(:dependency_files) { bundler_project_dependency_files("version_conflict") } let(:target_version) { "3.6.0" } let(:dependency_name) { "rspec-mocks" } let(:requirements) do @@ -113,10 +104,7 @@ end context "when updating the dependency that is required by the other" do - let(:gemfile_body) { fixture("ruby", "gemfiles", "version_conflict") } - let(:lockfile_body) do - fixture("ruby", "lockfiles", "version_conflict.lock") - end + let(:dependency_files) { bundler_project_dependency_files("version_conflict") } let(:target_version) { "3.6.0" } let(:dependency_name) { "rspec-support" } let(:requirements) do @@ -161,12 +149,7 @@ end context "when two dependencies require the same subdependency" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "version_conflict_mutual_sub") - end - let(:lockfile_body) do - fixture("ruby", "lockfiles", "version_conflict_mutual_sub.lock") - end + let(:dependency_files) { bundler_project_dependency_files("version_conflict_mutual_sub") } let(:dependency_name) { "rspec-mocks" } let(:target_version) { "3.6.0" } @@ -212,12 +195,7 @@ end context "when another dependency would need to be downgraded" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "subdep_blocked_by_subdep") - end - let(:lockfile_body) do - fixture("ruby", "lockfiles", "subdep_blocked_by_subdep.lock") - end + let(:dependency_files) { bundler_project_dependency_files("subdep_blocked_by_subdep") } let(:target_version) { "2.0.0" } let(:dependency_name) { "dummy-pkg-a" } @@ -228,12 +206,7 @@ end context "when the ruby version would need to change" do - let(:gemfile_body) do - fixture("ruby", "gemfiles", "legacy_ruby") - end - let(:lockfile_body) do - fixture("ruby", "lockfiles", "legacy_ruby.lock") - end + let(:dependency_files) { bundler_project_dependency_files("legacy_ruby") } let(:target_version) { "2.0.5" } let(:dependency_name) { "public_suffix" } diff --git a/bundler/spec/dependabot/bundler/update_checker/latest_version_finder/dependency_source_spec.rb b/bundler/spec/dependabot/bundler/update_checker/latest_version_finder/dependency_source_spec.rb new file mode 100644 index 00000000000..59d2f457435 --- /dev/null +++ b/bundler/spec/dependabot/bundler/update_checker/latest_version_finder/dependency_source_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/bundler/update_checker" + +RSpec.describe Dependabot::Bundler::UpdateChecker::LatestVersionFinder::DependencySource do + let(:project_name) { "git_source" } + let(:files) { project_dependency_files(File.join("bundler2", project_name)) } + let(:credentials) do + [{ + "type" => "git_source", + "host" => "github.com", + "username" => "x-access-token", + "password" => "token" + }] + end + let(:source) { described_class.new(dependency: nil, dependency_files: files, credentials: credentials, options: {}) } + + describe "#inaccessible_git_dependencies", :vcr do + subject(:inaccessible_git_dependencies) { source.inaccessible_git_dependencies } + + it "is empty when all dependencies are accessible" do + expect(inaccessible_git_dependencies).to be_empty + end + + context "with inaccessible dependency", :vcr do + let(:project_name) { "private_git_source" } + + it "includes inaccessible dependency" do + expect(inaccessible_git_dependencies.size).to eq(1) + expect(inaccessible_git_dependencies.first).to eq({ + "auth_uri" => "https://x-access-token:token@github.com/no-exist-sorry/prius.git/info/refs?service=git-upload-pack", + "uri" => "git@github.com:no-exist-sorry/prius" + }) + end + end + + context "with non-URI dependency", :vcr do + let(:project_name) { "git_source_invalid_github" } + + it "includes invalid dependency" do + expect(inaccessible_git_dependencies.size).to eq(1) + expect(inaccessible_git_dependencies.first).to eq({ + "auth_uri" => "dependabot-fixtures/business.git/info/refs?service=git-upload-pack", + "uri" => "dependabot-fixtures/business" + }) + end + end + end +end diff --git a/bundler/spec/dependabot/bundler/update_checker/latest_version_finder_spec.rb b/bundler/spec/dependabot/bundler/update_checker/latest_version_finder_spec.rb index 3e1114a3e11..0ea7bb02510 100644 --- a/bundler/spec/dependabot/bundler/update_checker/latest_version_finder_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker/latest_version_finder_spec.rb @@ -19,10 +19,12 @@ "host" => "github.com", "username" => "x-access-token", "password" => "token" - }] + }], + options: {} ) end - let(:dependency_files) { [gemfile, lockfile] } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } + let(:bundler_version) { PackageManagerHelper.bundler_version } let(:ignored_versions) { [] } let(:raise_on_ignored) { false } let(:security_advisories) { [] } @@ -48,27 +50,6 @@ let(:source) { nil } let(:requirement_string) { ">= 0" } - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "Gemfile" - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "Gemfile.lock" - ) - end - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "example.gemspec" - ) - end - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:gemspec_fixture_name) { "example" } let(:rubygems_url) { "https://rubygems.org/api/v1/" } describe "#latest_version_details" do @@ -100,32 +81,13 @@ end context "with a gems.rb setup" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb" - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked" - ) - end - let(:requirements) do - [{ - file: "gems.rb", - requirement: requirement_string, - groups: [], - source: source - }] - end + let(:dependency_files) { bundler_project_dependency_files("gems_rb") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end context "when the gem is Bundler" do - let(:gemfile_fixture_name) { "bundler_specified" } + let(:dependency_files) { bundler_project_dependency_files("bundler_specified") } let(:dependency_name) { "bundler" } before do rubygems_response = fixture("ruby", "rubygems_response_versions.json") @@ -136,11 +98,65 @@ its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } context "wrapped in a source block" do - let(:gemfile_fixture_name) { "bundler_specified_in_source" } + let(:dependency_files) { bundler_project_dependency_files("bundler_specified_in_source_bundler_specified") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end end + context "raise_on_ignored when later versions are allowed" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + + context "when the user is on the latest version" do + let(:current_version) { "1.5.0" } + its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end + + context "when the current version isn't known" do + let(:current_version) { nil } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end + + context "when the dependency is a git dependency" do + let(:current_version) { "a1b78a929dac93a52f08db4f2847d76d6cfe39bd" } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end + + context "when the user has ignored all later versions" do + let(:ignored_versions) { ["> 1.3.0"] } + + its([:version]) { is_expected.to eq(Gem::Version.new("1.3.0")) } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "raises an error" do + expect { subject }.to raise_error(Dependabot::AllVersionsIgnored) + end + end + end + context "when the user is ignoring the latest version" do let(:ignored_versions) { [">= 1.5.0.a, < 1.6"] } its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } @@ -162,7 +178,7 @@ end context "with a prerelease version specified" do - let(:gemfile_fixture_name) { "prerelease_specified" } + let(:dependency_files) { bundler_project_dependency_files("prerelease_specified") } let(:requirement_string) { "~> 1.4.0.rc1" } before do @@ -174,29 +190,23 @@ end context "with a Ruby version specified" do - let(:gemfile_fixture_name) { "explicit_ruby" } + let(:dependency_files) { bundler_project_dependency_files("explicit_ruby") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end context "given a Gemfile that loads a .ruby-version file" do - let(:gemfile_fixture_name) { "ruby_version_file" } - let(:ruby_version_file) do - Dependabot::DependencyFile.new content: "2.2.0", name: ".ruby-version" - end - let(:dependency_files) { [gemfile, lockfile, ruby_version_file] } + let(:dependency_files) { bundler_project_dependency_files("ruby_version_file") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end context "with a gemspec and a Gemfile" do - let(:dependency_files) { [gemfile, gemspec] } - let(:gemspec_fixture_name) { "small_example" } - let(:gemfile_fixture_name) { "imports_gemspec" } + let(:dependency_files) { bundler_project_dependency_files("gemfile_small_example") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } context "with a dependency that only appears in the gemspec" do - let(:gemspec_fixture_name) { "example" } + let(:dependency_files) { bundler_project_dependency_files("gemfile_small_example") } let(:dependency_name) { "octokit" } before do @@ -208,30 +218,27 @@ its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } context "when there is no default source" do - let(:gemfile_fixture_name) { "imports_gemspec_no_default_source" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_no_default_source_no_lockfile") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end end end context "with only a gemspec" do - let(:dependency_files) { [gemspec] } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("gemspec_small_example_no_lockfile") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end context "with only a Gemfile" do - let(:dependency_files) { [gemfile] } - let(:gemfile_fixture_name) { "Gemfile" } + let(:dependency_files) { bundler_project_dependency_files("no_lockfile") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end end context "with a private rubygems source" do - let(:gemfile_fixture_name) { "specified_source" } - let(:lockfile_fixture_name) { "specified_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("specified_source") } let(:source) { { type: "rubygems" } } let(:registry_url) { "https://repo.fury.io/greysteil/" } let(:gemfury_business_url) do @@ -239,22 +246,34 @@ end before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 404) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 200) - stub_request(:get, gemfury_business_url). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) + # We only need to stub out the version callout since it would + # otherwise call out to the internet in a shell command + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "dependency_source_type", + options: anything, + args: anything + }).and_call_original + + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_return( + ["1.5.0", "1.9.0", "1.10.0.beta"] + ) end its([:version]) { is_expected.to eq(Gem::Version.new("1.9.0")) } context "specified as the default source" do - let(:gemfile_fixture_name) { "specified_default_source" } - let(:lockfile_fixture_name) { "specified_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("specified_default_source") } its([:version]) { is_expected.to eq(Gem::Version.new("1.9.0")) } end @@ -264,17 +283,37 @@ its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end - context "that we don't have authentication details for" do + let(:subprocess_error) do + Dependabot::SharedHelpers::HelperSubprocessFailed.new( + message: error_message, + error_context: {}, + error_class: error_class + ) + end + + context "that we don't have authentication details for", :bundler_v1_only do + let(:error_message) do + <<~ERR + Authentication is required for repo.fury.io. + Please supply credentials for this source. You can do this by running: + bundle config repo.fury.io username:password + ERR + end + + let(:error_class) do + "Bundler::Fetcher::AuthenticationRequiredError" + end + before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 401) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 401) - stub_request(:get, registry_url + "specs.4.8.gz"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 401) + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_raise(subprocess_error) end it "blows up with a useful error" do @@ -287,17 +326,62 @@ end end + context "that we don't have authentication details for", :bundler_v2_only do + let(:error_message) do + <<~ERR + Bad username or password for https://user:secret@repo.fury.io/greysteil/. + Please double-check your credentials and correct them. + ERR + end + + let(:error_class) do + "Bundler::Fetcher::BadAuthenticationError" + end + + before do + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_raise(subprocess_error) + end + + it "blows up with a useful error" do + error_class = Dependabot::PrivateSourceAuthenticationFailure + expect { finder.latest_version_details }. + to raise_error do |error| + expect(error).to be_a(error_class) + expect(error.source).to eq("https://repo.fury.io/") + end + end + end + context "that we have bad authentication details for" do + let(:error_message) do + <<~ERR + Bad username or password for https://user:secret@repo.fury.io/greysteil/. + Please double-check your credentials and correct them. + ERR + end + + let(:error_class) do + "Bundler::Fetcher::BadAuthenticationError" + end + before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 403) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 403) - stub_request(:get, registry_url + "specs.4.8.gz"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 403) + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_raise(subprocess_error) end it "blows up with a useful error" do @@ -306,22 +390,32 @@ to raise_error do |error| expect(error).to be_a(error_class) expect(error.source). - to eq("https://SECRET_CODES@repo.fury.io/greysteil/") + to eq("https://repo.fury.io/") end end end context "that bad-requested, but was a private repo" do + let(:error_message) do + <<~ERR + Could not fetch specs from https://repo.fury.io/greysteil/ + ERR + end + + let(:error_class) do + "Bundler::HTTPError" + end + before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 400) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 400) - stub_request(:get, registry_url + "specs.4.8.gz"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 400) + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_raise(subprocess_error) end it "blows up with a useful error" do @@ -329,72 +423,32 @@ to raise_error do |error| expect(error).to be_a(Dependabot::PrivateSourceTimedOut) expect(error.source). - to eq("https://repo.fury.io/greysteil/") + to eq("https://repo.fury.io/") end end end context "that doesn't have details of the gem" do before do - stub_request(:get, gemfury_business_url). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 404) - - # Stub indexes to return details of other gems (but not this one) - stub_request(:get, registry_url + "specs.4.8.gz"). - to_return( - status: 200, - body: fixture("ruby", "contribsys_old_index_response") - ) - stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). - to_return( - status: 200, - body: fixture("ruby", "contribsys_old_index_prerelease_response") + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_return( + [] ) end it { is_expected.to be_nil } end - - context "that only implements the old Bundler index format..." do - let(:gemfile_fixture_name) { "sidekiq_pro" } - let(:lockfile_fixture_name) { "sidekiq_pro.lock" } - let(:dependency_name) { "sidekiq-pro" } - let(:registry_url) { "https://gems.contribsys.com/" } - before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: %w(username password)). - to_return(status: 404) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: %w(username password)). - to_return(status: 404) - stub_request(:get, registry_url + "specs.4.8.gz"). - with(basic_auth: %w(username password)). - to_return( - status: 200, - body: fixture("ruby", "contribsys_old_index_response") - ) - stub_request(:get, registry_url + "prerelease_specs.4.8.gz"). - with(basic_auth: %w(username password)). - to_return( - status: 200, - body: fixture("ruby", "contribsys_old_index_prerelease_response") - ) - end - - its([:version]) { is_expected.to eq(Gem::Version.new("3.5.2")) } - end end context "given a git source" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } - - before do - rubygems_response = fixture("ruby", "rubygems_response_versions.json") - stub_request(:get, rubygems_url + "versions/business.json"). - to_return(status: 200, body: rubygems_response) - end + let(:dependency_files) { bundler_project_dependency_files("git_source") } context "that is the gem we're checking for" do let(:dependency_name) { "business" } @@ -402,7 +456,7 @@ let(:source) do { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "a1b78a9" # Pinned, to ensure we unpin } @@ -415,12 +469,11 @@ end context "when the gem has a bad branch" do - let(:gemfile_fixture_name) { "bad_branch_business" } - let(:lockfile_fixture_name) { "bad_branch_business.lock" } + let(:dependency_files) { bundler_project_dependency_files("bad_branch_business") } let(:source) do { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "bad_branch", ref: "bad_branch" } @@ -438,8 +491,6 @@ end context "that is not the gem we're checking" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } let(:dependency_name) { "statesman" } before do @@ -453,8 +504,7 @@ its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } context "that is private" do - let(:gemfile_fixture_name) { "private_git_source" } - let(:lockfile_fixture_name) { "private_git_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("private_git_source") } its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } end @@ -462,8 +512,7 @@ end context "given a path source" do - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("path_source") } before do rubygems_response = fixture("ruby", "rubygems_response_versions.json") @@ -472,14 +521,7 @@ end context "with a downloaded gemspec" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec_fixture_name) { "example" } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "plugins/example/example.gemspec" - ) - end + let(:dependency_files) { bundler_project_dependency_files("path_source") } context "that is not the gem we're checking" do its([:version]) { is_expected.to eq(Gem::Version.new("1.5.0")) } @@ -520,8 +562,7 @@ end context "with a private rubygems source" do - let(:gemfile_fixture_name) { "specified_source" } - let(:lockfile_fixture_name) { "specified_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("specified_source") } let(:source) { { type: "rubygems" } } let(:registry_url) { "https://repo.fury.io/greysteil/" } let(:gemfury_business_url) do @@ -529,18 +570,46 @@ end before do - stub_request(:get, registry_url + "versions"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 404) - stub_request(:get, registry_url + "api/v1/dependencies"). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 200) - stub_request(:get, gemfury_business_url). - with(basic_auth: ["SECRET_CODES", ""]). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) + # We only need to stub out the version callout since it would + # otherwise call out to the internet in a shell command + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "dependency_source_type", + options: anything, + args: anything + }).and_call_original + + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_return( + ["1.5.0", "1.9.0", "1.10.0.beta"] + ) end it { is_expected.to eq(Gem::Version.new("1.5.0")) } end + + context "with a git source" do + let(:dependency_files) { bundler_project_dependency_files("git_source") } + + it { is_expected.to be_nil } + end + + context "with a path source" do + let(:dependency_files) { bundler_project_dependency_files("path_source") } + + let(:dependency_name) { "example" } + let(:source) { { type: "path" } } + + it { is_expected.to be_nil } + end end end diff --git a/bundler/spec/dependabot/bundler/update_checker/version_resolver_spec.rb b/bundler/spec/dependabot/bundler/update_checker/version_resolver_spec.rb index 1e09bbc0102..20f77cc8d0a 100644 --- a/bundler/spec/dependabot/bundler/update_checker/version_resolver_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker/version_resolver_spec.rb @@ -19,10 +19,10 @@ "password" => "token" }], unlock_requirement: unlock_requirement, - latest_allowable_version: latest_allowable_version + latest_allowable_version: latest_allowable_version, + options: {} ) end - let(:dependency_files) { [gemfile, lockfile] } let(:ignored_versions) { [] } let(:latest_allowable_version) { nil } let(:unlock_requirement) { false } @@ -48,69 +48,40 @@ let(:source) { nil } let(:requirement_string) { ">= 0" } - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "Gemfile" - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "Gemfile.lock" - ) - end - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "example.gemspec" - ) - end - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:gemspec_fixture_name) { "example" } - let(:rubygems_url) { "https://index.rubygems.org/api/v1/" } - describe "#latest_resolvable_version_details" do subject { resolver.latest_resolvable_version_details } - include_context "stub rubygems compact index" - context "with a rubygems source" do context "with a ~> version specified constraining the update" do - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } let(:requirement_string) { "~> 1.4.0" } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } end context "with a minor version specified that can update" do - let(:gemfile_fixture_name) { "minor_version_specified" } - let(:lockfile_fixture_name) { "Gemfile.lock" } let(:requirement_string) { "~> 1.4" } + let(:dependency_files) { bundler_project_dependency_files("minor_version_specified_gemfile") } its([:version]) { is_expected.to eq(Gem::Version.new("1.18.0")) } end context "when updating a dep blocked by a sub-dep" do - let(:gemfile_fixture_name) { "blocked_by_subdep" } - let(:lockfile_fixture_name) { "blocked_by_subdep.lock" } let(:dependency_name) { "dummy-pkg-a" } let(:current_version) { "1.0.1" } let(:requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end + let(:dependency_files) { bundler_project_dependency_files("blocked_by_subdep") } its([:version]) { is_expected.to eq(Gem::Version.new("1.1.0")) } end context "that only appears in the lockfile" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } let(:dependency_name) { "i18n" } let(:requirements) { [] } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } its([:version]) { is_expected.to eq(Gem::Version.new("0.7.0")) } context "that will be removed if other sub-dependencies are updated" do @@ -119,25 +90,29 @@ let(:dependency_name) { "nokogiri" } let(:requirements) { [] } - its([:version]) { is_expected.to eq(Gem::Version.new("1.10.9")) } + pending "is updated, skipped due to https://github.com/dependabot/dependabot-core/issues/2364" do + expect(subject.version).to eq(Gem::Version.new("1.10.9")) + end end end - context "with a Bundler version specified" do - let(:gemfile_fixture_name) { "bundler_specified" } - let(:lockfile_fixture_name) { "bundler_specified.lock" } + context "with a Bundler v1 version specified", :bundler_v1_only do let(:requirement_string) { "~> 1.4.0" } + let(:dependency_files) { bundler_project_dependency_files("bundler_specified") } its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } context "attempting to update Bundler" do let(:dependency_name) { "bundler" } include_context "stub rubygems versions api" + let(:dependency_files) { bundler_project_dependency_files("bundler_specified") } its([:version]) { is_expected.to eq(Gem::Version.new("1.16.3")) } context "when wrapped in a source block" do - let(:gemfile_fixture_name) { "bundler_specified_in_source" } + let(:dependency_files) do + bundler_project_dependency_files("bundler_specified_in_source_bundler_specified") + end its([:version]) { is_expected.to eq(Gem::Version.new("1.16.3")) } end @@ -147,42 +122,91 @@ "bundler_specified_and_required.lock" end - it { is_expected.to be_nil } + pending "skipped due to https://github.com/dependabot/dependabot-core/issues/2364" do + is_expected.to be_nil + end + end + end + end + + context "with a Bundler v2 version specified", :bundler_v2_only do + let(:requirement_string) { "~> 1.4.0" } + + let(:dependency_files) { bundler_project_dependency_files("bundler_specified") } + its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) } + + context "attempting to update Bundler" do + let(:dependency_name) { "bundler" } + let(:requirement_string) { "~> 2.3.0" } + + let(:dependency_files) { bundler_project_dependency_files("bundler_specified") } + + it "returns nil as resolution returns the bundler version installed by core" do + expect(subject).to be_nil end end end + context "with a dependency that requires bundler v1", :bundler_v1_only do + let(:dependency_name) { "guard-bundler" } + let(:requirement_string) { "2.2.1" } + + let(:dependency_files) { bundler_project_dependency_files("requires_bundler") } + its([:version]) { is_expected.to eq(Gem::Version.new("2.2.1")) } + end + + context "when bundled with v1 and requesting a version that requires bundler v2", :bundler_v1_only do + let(:dependency_name) { "guard-bundler" } + let(:requirement_string) { "~> 3.0.0" } + + let(:dependency_files) { bundler_project_dependency_files("requires_bundler") } + + it "raises a DependencyFileNotResolvable error" do + expect { subject }. + to raise_error(Dependabot::DependencyFileNotResolvable) + end + end + + context "with a dependency that requires bundler v2", :bundler_v2_only do + let(:dependency_name) { "guard-bundler" } + let(:requirement_string) { "3.0.0" } + + let(:dependency_files) { bundler_project_dependency_files("requires_bundler") } + + pending "resolves version" do + expect(subject.version).to eq(Gem::Version.new("3.0.0")) + end + end + + context "when bundled with v2 and requesting a version that requires bundler v1", :bundler_v2_only do + let(:dependency_name) { "guard-bundler" } + let(:requirement_string) { "~> 2.2.0" } + + let(:dependency_files) { bundler_project_dependency_files("requires_bundler") } + + pending "raises a DependencyFileNotResolvable error" do + expect { subject }. + to raise_error(Dependabot::DependencyFileNotResolvable) + end + end + context "with a default gem specified" do - let(:gemfile_fixture_name) { "default_gem_specified" } - let(:lockfile_fixture_name) { "default_gem_specified.lock" } let(:requirement_string) { "~> 1.4" } + let(:dependency_files) { bundler_project_dependency_files("default_gem_specified") } its([:version]) { is_expected.to eq(Gem::Version.new("1.18.0")) } end context "with a version conflict at the latest version" do - let(:gemfile_fixture_name) { "version_conflict_no_req_change" } - let(:lockfile_fixture_name) { "version_conflict_no_req_change.lock" } let(:dependency_name) { "ibandit" } let(:requirement_string) { "~> 0.1" } # The latest version of ibandit is 0.8.5, but 0.11.28 is the latest # version compatible with the version of i18n in the Gemfile.lock. + let(:dependency_files) { bundler_project_dependency_files("version_conflict_no_req_change") } its([:version]) { is_expected.to eq(Gem::Version.new("0.11.28")) } context "with a gems.rb and gems.locked" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb" - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked" - ) - end let(:requirements) do [{ file: "gems.rb", @@ -192,106 +216,123 @@ }] end + let(:dependency_files) { bundler_project_dependency_files("version_conflict_no_req_change_gems_rb") } its([:version]) { is_expected.to eq(Gem::Version.new("0.11.28")) } end end context "with no update possible due to a version conflict" do - let(:gemfile_fixture_name) { "version_conflict_with_listed_subdep" } - let(:lockfile_fixture_name) do - "version_conflict_with_listed_subdep.lock" - end let(:dependency_name) { "rspec-mocks" } let(:requirement_string) { ">= 0" } + let(:dependency_files) { bundler_project_dependency_files("version_conflict_with_listed_subdep") } its([:version]) { is_expected.to eq(Gem::Version.new("3.6.0")) } end context "with a legacy Ruby which disallows the latest version" do - let(:gemfile_fixture_name) { "legacy_ruby" } - let(:lockfile_fixture_name) { "legacy_ruby.lock" } let(:dependency_name) { "public_suffix" } let(:requirement_string) { ">= 0" } # The latest version of public_suffix is 2.0.5, but requires Ruby 2.0.0 # or greater. + let(:dependency_files) { bundler_project_dependency_files("legacy_ruby") } its([:version]) { is_expected.to eq(Gem::Version.new("1.4.6")) } + end - context "when Bundler's compact index is down" do - before do - old_index_url = "https://index.rubygems.org/api/v1/dependencies" - stub_request(:get, "https://index.rubygems.org/versions"). - to_return(status: 500, body: "We'll be back soon") - stub_request(:get, "https://index.rubygems.org/info/public_suffix"). - to_return(status: 500, body: "We'll be back soon") - stub_request(:get, old_index_url).to_return(status: 200) - stub_request(:get, old_index_url + "?gems=public_suffix"). - to_return( - status: 200, - body: fixture("ruby", - "rubygems_responses", - "dependencies-public_suffix") - ) - - stub_request(:get, rubygems_url + "versions/public_suffix.json"). - to_return(status: 200, body: rubygems_versions) - end + context "with a legacy Ruby when Bundler's compact index is down" do + let(:dependency_name) { "public_suffix" } + let(:requirement_string) { ">= 0" } + let(:dependency_files) { bundler_project_dependency_files("legacy_ruby") } + let(:versions_url) do + "https://rubygems.org/api/v1/versions/public_suffix.json" + end + let(:rubygems_versions) do + fixture("rubygems_responses", "versions-public_suffix.json") + end + + before do + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: PackageManagerHelper.bundler_version, + function: "resolve_version", + options: anything, + args: anything + }). + and_return( + { + version: "3.0.2", + ruby_version: "1.9.3", + fetcher: "Bundler::Fetcher::Dependency" + } + ) + + stub_request(:get, versions_url). + to_return(status: 200, body: rubygems_versions) + end + + it { is_expected.to be_nil } + + context "and the dependency doesn't have a required Ruby version" do let(:rubygems_versions) do - fixture("ruby", "rubygems_responses", "versions-public_suffix.json") + fixture( + "rubygems_responses", + "versions-public_suffix.json" + ).gsub(/"ruby_version": .*,/, '"ruby_version": null,') end - it { is_expected.to be_nil } - - context "and the dependency doesn't have a required Ruby version" do - let(:rubygems_versions) do - fixture( - "ruby", - "rubygems_responses", - "versions-public_suffix.json" - ).gsub(/"ruby_version": .*,/, '"ruby_version": null,') - end + let(:dependency_files) { bundler_project_dependency_files("legacy_ruby") } + its([:version]) { is_expected.to eq(Gem::Version.new("3.0.2")) } + end - its([:version]) { is_expected.to eq(Gem::Version.new("3.0.2")) } + context "and the dependency has a required Ruby version range" do + let(:rubygems_versions) do + fixture( + "rubygems_responses", + "versions-public_suffix.json" + ).gsub(/"ruby_version": .*,/, '"ruby_version": ">= 2.2, < 4.0",') end + + it { is_expected.to be_nil } end end context "with JRuby" do - let(:gemfile_fixture_name) { "jruby" } - let(:lockfile_fixture_name) { "jruby.lock" } let(:dependency_name) { "json" } let(:requirement_string) { ">= 0" } + let(:dependency_files) { bundler_project_dependency_files("jruby") } its([:version]) { is_expected.to be >= Gem::Version.new("1.4.6") } end context "when a gem has been yanked" do - let(:gemfile_fixture_name) { "minor_version_specified" } - let(:lockfile_fixture_name) { "yanked_gem.lock" } let(:requirement_string) { "~> 1.4" } context "and it's that gem that we're attempting to bump" do + let(:dependency_files) { bundler_project_dependency_files("minor_version_specified_yanked_gem") } its([:version]) { is_expected.to eq(Gem::Version.new("1.18.0")) } end context "and it's another gem" do let(:dependency_name) { "statesman" } let(:requirement_string) { "~> 1.2" } + let(:dependency_files) { bundler_project_dependency_files("minor_version_specified_yanked_gem") } its([:version]) { is_expected.to eq(Gem::Version.new("1.3.1")) } end end context "when unlocking a git dependency would cause errors" do let(:current_version) { "1.4.0" } - let(:gemfile_fixture_name) { "git_source_circular" } - let(:lockfile_fixture_name) { "git_source_circular.lock" } - its([:version]) { is_expected.to eq(Gem::Version.new("2.1.0")) } + let(:dependency_files) { bundler_project_dependency_files("git_source_circular") } + + it "unlocks the version" do + expect(resolver.latest_resolvable_version_details[:version].canonical_segments.first).to eq(2) + end end context "with a ruby exec command that fails" do - let(:gemfile_fixture_name) { "exec_error" } - let(:dependency_files) { [gemfile] } + let(:dependency_files) { bundler_project_dependency_files("exec_error_no_lockfile") } it "raises a DependencyFileNotEvaluatable error" do expect { subject }. @@ -300,32 +341,8 @@ end end - context "with a private gemserver source" do - let(:gemfile_fixture_name) { "specified_source" } - let(:lockfile_fixture_name) { "specified_source.lock" } - let(:requirement_string) { ">= 0" } - - before do - gemfury_url = "https://repo.fury.io/greysteil/" - gemfury_deps_url = gemfury_url + "api/v1/dependencies" - - stub_request(:get, gemfury_url + "versions"). - to_return(status: 200, body: fixture("ruby", "gemfury-index")) - stub_request(:get, gemfury_url + "info/business").to_return(status: 404) - stub_request(:get, gemfury_deps_url).to_return(status: 200) - stub_request(:get, gemfury_deps_url + "?gems=business,statesman"). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) - stub_request(:get, gemfury_deps_url + "?gems=business"). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) - stub_request(:get, gemfury_deps_url + "?gems=statesman"). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) - end - - its([:version]) { is_expected.to eq(Gem::Version.new("1.9.0")) } - end - context "when the Gem can't be found" do - let(:gemfile_fixture_name) { "unavailable_gem" } + let(:dependency_files) { bundler_project_dependency_files("unavailable_gem_gemfile") } let(:requirement_string) { "~> 1.4" } it "raises a DependencyFileNotResolvable error" do @@ -335,24 +352,22 @@ end context "given an unreadable Gemfile" do - let(:gemfile_fixture_name) { "includes_requires" } + let(:dependency_files) { bundler_project_dependency_files("includes_requires_gemfile") } it "raises a useful error" do expect { subject }. to raise_error(Dependabot::DependencyFileNotEvaluatable) do |error| - # Test that the temporary path isn't included in the error message - expect(error.message).to_not include("dependabot_20") - end + # Test that the temporary path isn't included in the error message + expect(error.message).to_not include("dependabot_20") + end end end context "given a path source" do - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } let(:requirement_string) { "~> 1.4.0" } context "without a downloaded gemspec" do - let(:dependency_files) { [gemfile, lockfile] } + let(:dependency_files) { bundler_project_dependency_files("path_source_not_reachable") } it "raises a PathDependenciesNotReachable error" do expect { subject }. @@ -363,15 +378,14 @@ context "given a git source" do context "where updating would cause a circular dependency" do - let(:gemfile_fixture_name) { "git_source_circular" } - let(:lockfile_fixture_name) { "git_source_circular.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source_circular") } let(:dependency_name) { "rubygems-circular-dependency" } let(:current_version) { "3c85f0bd8d6977b4dfda6a12acf93a282c4f5bf1" } let(:source) do { type: "git", - url: "https://github.com/dependabot-fixtures/"\ + url: "https://github.com/dependabot-fixtures/" \ "rubygems-circular-dependency", branch: "master", ref: "master" @@ -383,9 +397,7 @@ end context "with a gemspec and a Gemfile" do - let(:dependency_files) { [gemfile, gemspec] } - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_small_example_no_lockfile") } let(:unlock_requirement) { true } let(:current_version) { nil } let(:requirements) do @@ -403,11 +415,11 @@ end it "unlocks the latest version" do - expect(resolver.latest_resolvable_version_details[:version]). - to eq(Gem::Version.new("2.1.0")) + expect(resolver.latest_resolvable_version_details[:version].canonical_segments.first).to eq(2) end context "with an upper bound that is lower than the current req" do + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_small_example_no_lockfile") } let(:latest_allowable_version) { "1.0.0" } let(:ignored_versions) { ["> 1.0.0"] } @@ -430,13 +442,15 @@ source: nil }] end - - it { is_expected.to be_nil } + pending "skipped due to https://github.com/dependabot/dependabot-core/issues/2364" do + is_expected.to be_nil + end end context "when an old required ruby is specified in the gemspec" do - let(:gemspec_fixture_name) { "old_required_ruby" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_old_required_ruby_no_lockfile") } let(:dependency_name) { "statesman" } + let(:latest_allowable_version) { "7.2.0" } it "takes the minimum ruby version into account" do expect(resolver.latest_resolvable_version_details[:version]). @@ -444,7 +458,9 @@ end context "that isn't satisfied by the dependencies" do - let(:gemfile_fixture_name) { "imports_gemspec_version_clash" } + let(:dependency_files) do + bundler_project_dependency_files("imports_gemspec_version_clash_old_required_ruby_no_lockfile") + end let(:current_version) { "3.0.1" } it "ignores the minimum ruby version in the gemspec" do diff --git a/bundler/spec/dependabot/bundler/update_checker_spec.rb b/bundler/spec/dependabot/bundler/update_checker_spec.rb index 8c76b10089c..2b9be3cc537 100644 --- a/bundler/spec/dependabot/bundler/update_checker_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker_spec.rb @@ -27,7 +27,8 @@ "password" => "token" }] end - let(:dependency_files) { [gemfile, lockfile] } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } + let(:github_token) { "token" } let(:directory) { "/" } let(:ignored_versions) { [] } @@ -47,29 +48,6 @@ [{ file: "Gemfile", requirement: "~> 1.4.0", groups: [], source: nil }] end - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "Gemfile", - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "Gemfile.lock", - directory: directory - ) - end - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "example.gemspec" - ) - end - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:gemspec_fixture_name) { "example" } let(:rubygems_url) { "https://rubygems.org/api/v1/" } describe "#latest_version" do @@ -85,8 +63,8 @@ it { is_expected.to eq(Gem::Version.new("1.5.0")) } context "that only appears in the lockfile" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } + let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -110,36 +88,14 @@ end context "with a Gemfile that includes a file with require_relative" do - let(:dependency_files) { [gemfile, lockfile, required_file] } - let(:gemfile_fixture_name) { "includes_require_relative" } - let(:lockfile_fixture_name) { "Gemfile.lock" } - let(:required_file) do - Dependabot::DependencyFile.new( - name: "../some_other_file.rb", - content: "SOME_CONSTANT = 5", - directory: directory - ) - end + let(:dependency_files) { bundler_project_dependency_files("includes_require_relative_gemfile") } let(:directory) { "app/" } it { is_expected.to eq(Gem::Version.new("1.5.0")) } end context "with a gem.rb and gems.locked setup" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb", - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked", - directory: directory - ) - end + let(:dependency_files) { bundler_project_dependency_files("gems_rb") } let(:requirements) do [{ @@ -154,9 +110,32 @@ end end + context "with extra nonrelevant credentials" do + before do + rubygems_response = fixture("ruby", "rubygems_response_versions.json") + stub_request(:get, rubygems_url + "versions/business.json"). + to_return(status: 200, body: rubygems_response) + end + + let(:credentials) do + [{ + "type" => "git_source", + "host" => "github.com", + "username" => "x-access-token", + "password" => "token" + }, { + "type" => "npm_registry", + "registry" => "npm.fury.io/dependabot", + "token" => "secret_token" + }] + end + + it { is_expected.to eq(Gem::Version.new("1.5.0")) } + end + context "with a private rubygems source" do - let(:lockfile_fixture_name) { "specified_source.lock" } - let(:gemfile_fixture_name) { "specified_source" } + let(:dependency_files) { bundler_project_dependency_files("specified_source") } + let(:requirements) do [{ file: "Gemfile", @@ -170,20 +149,37 @@ "https://repo.fury.io/greysteil/api/v1/dependencies?gems=business" end before do - stub_request(:get, registry_url + "versions").to_return(status: 404) - stub_request(:get, registry_url + "api/v1/dependencies"). - to_return(status: 200) - # Note: returns details of three versions: 1.5.0, 1.9.0, and 1.10.0.beta - stub_request(:get, gemfury_business_url). - to_return(status: 200, body: fixture("ruby", "gemfury_response")) + bundler_version = PackageManagerHelper.bundler_version + + # We only need to stub out the version callout since it would + # otherwise call out to the internet in a shell command + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "dependency_source_type", + options: anything, + args: anything + }).and_call_original + + allow(Dependabot::Bundler::NativeHelpers). + to receive(:run_bundler_subprocess). + with({ + bundler_version: bundler_version, + function: "private_registry_versions", + options: anything, + args: anything + }). + and_return( + ["1.5.0", "1.9.0", "1.10.0.beta"] + ) end it { is_expected.to eq(Gem::Version.new("1.9.0")) } end context "given a git source" do - let(:lockfile_fixture_name) { "git_source_no_ref.lock" } - let(:gemfile_fixture_name) { "git_source_no_ref" } + let(:dependency_files) { bundler_project_dependency_files("git_source_no_ref") } before do rubygems_response = fixture("ruby", "rubygems_response_versions.json") @@ -201,7 +197,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "master" } @@ -223,7 +219,7 @@ allow_any_instance_of(Dependabot::GitCommitChecker). to receive(:branch_or_ref_in_release?). and_return(false) - git_url = "https://github.com/gocardless/business.git" + git_url = "https://github.com/dependabot-fixtures/business.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -242,8 +238,7 @@ end context "when the gem's tag is pinned" do - let(:lockfile_fixture_name) { "git_source.lock" } - let(:gemfile_fixture_name) { "git_source" } + let(:dependency_files) { bundler_project_dependency_files("git_source") } let(:requirements) do [{ @@ -252,7 +247,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "a1b78a9" } @@ -300,7 +295,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "v1.0.0" } @@ -310,7 +305,7 @@ before do stub_request(:get, rubygems_url + "versions/business.json"). to_return(status: 404, body: "This rubygem could not be found.") - url = "https://github.com/gocardless/business.git" + url = "https://github.com/dependabot-fixtures/business.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -342,8 +337,7 @@ end context "given a path source" do - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("path_source") } before do rubygems_response = fixture("ruby", "rubygems_response_versions.json") @@ -352,9 +346,6 @@ end context "with a downloaded gemspec" do - let(:gemspec_fixture_name) { "example" } - let(:dependency_files) { [gemfile, lockfile, gemspec] } - context "that is the gem we're checking" do let(:dependency_name) { "example" } let(:current_version) { "0.9.3" } @@ -373,6 +364,43 @@ end end + describe "#lowest_security_fix_version" do + subject { checker.lowest_security_fix_version } + + context "with a rubygems source" do + let(:current_version) { "1.2.0" } + let(:requirements) do + [{ file: "Gemfile", requirement: "~> 1.2.0", groups: [], source: nil }] + end + + before do + rubygems_response = fixture("ruby", "rubygems_response_versions.json") + stub_request(:get, rubygems_url + "versions/business.json"). + to_return(status: 200, body: rubygems_response) + end + + it "finds the lowest available non-vulnerable version" do + is_expected.to eq(Gem::Version.new("1.3.0")) + end + + context "with a security vulnerability" do + let(:security_advisories) do + [ + Dependabot::SecurityAdvisory.new( + dependency_name: dependency_name, + package_manager: "bundler", + vulnerable_versions: ["<= 1.3.0"] + ) + ] + end + + it "finds the lowest available non-vulnerable version" do + is_expected.to eq(Gem::Version.new("1.4.0")) + end + end + end + end + describe "#latest_version_resolvable_with_full_unlock?" do include_context "stub rubygems compact index" subject { checker.send(:latest_version_resolvable_with_full_unlock?) } @@ -394,10 +422,7 @@ end context "when the force updater raises" do - let(:gemfile_fixture_name) { "subdep_blocked_by_subdep" } - let(:lockfile_fixture_name) do - "subdep_blocked_by_subdep.lock" - end + let(:dependency_files) { bundler_project_dependency_files("subdep_blocked_by_subdep") } let(:target_version) { "2.0.0" } let(:dependency_name) { "dummy-pkg-a" } let(:requirements) do @@ -413,8 +438,7 @@ end context "when the force updater succeeds" do - let(:gemfile_fixture_name) { "version_conflict" } - let(:lockfile_fixture_name) { "version_conflict.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_conflict") } let(:target_version) { "3.6.0" } let(:dependency_name) { "rspec-mocks" } let(:requirements) do @@ -438,8 +462,7 @@ end context "when the force updater succeeds" do - let(:gemfile_fixture_name) { "version_conflict" } - let(:lockfile_fixture_name) { "version_conflict.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_conflict") } let(:target_version) { "3.6.0" } let(:dependency_name) { "rspec-mocks" } let(:requirements) do @@ -483,20 +506,7 @@ end context "with a gem.rb and gems.locked setup" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb", - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked", - directory: directory - ) - end + let(:dependency_files) { bundler_project_dependency_files("version_conflict_gems_rb") } let(:requirements) do [{ @@ -542,6 +552,53 @@ end end + describe "#conflicting_dependencies" do + include_context "stub rubygems compact index" + include_context "stub rubygems versions api" + + subject { checker.conflicting_dependencies } + + let(:dependency_files) { bundler_project_dependency_files("subdep_blocked_by_subdep") } + let(:target_version) { "2.0.0" } + let(:dependency_name) { "dummy-pkg-a" } + let(:requirements) do + [{ + file: "Gemfile", + requirement: "~> 1.0.0", + groups: [], + source: nil + }] + end + + let(:requirements) { [] } + let(:security_advisories) do + [ + Dependabot::SecurityAdvisory.new( + dependency_name: dependency_name, + package_manager: "bundler", + vulnerable_versions: ["< 2.0.0"] + ) + ] + end + + before do + allow(checker). + to receive(:lowest_security_fix_version). + and_return(target_version) + end + + it do + is_expected.to eq( + [{ + "explanation" => "dummy-pkg-b (1.0.0) requires dummy-pkg-a (< 2.0.0)", + "name" => "dummy-pkg-b", + "version" => "1.0.0", + "requirement" => "< 2.0.0" + }] + ) + end + end + describe "#latest_resolvable_version" do include_context "stub rubygems compact index" include_context "stub rubygems versions api" @@ -550,8 +607,7 @@ context "given a gem from rubygems" do context "that only appears in the lockfile" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -560,8 +616,7 @@ end context "with no version specified" do - let(:gemfile_fixture_name) { "version_not_specified" } - let(:lockfile_fixture_name) { "version_not_specified.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_not_specified") } let(:requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end @@ -575,8 +630,7 @@ end context "with a greater than or equal to matcher" do - let(:gemfile_fixture_name) { "gte_matcher" } - let(:lockfile_fixture_name) { "gte_matcher.lock" } + let(:dependency_files) { bundler_project_dependency_files("gte_matcher") } let(:requirements) do [{ file: "Gemfile", @@ -590,7 +644,7 @@ end context "with multiple requirements" do - let(:gemfile_fixture_name) { "version_between_bounds" } + let(:dependency_files) { bundler_project_dependency_files("version_between_bounds_gemfile") } let(:requirements) do [{ file: "Gemfile", @@ -604,24 +658,8 @@ end context "with a gem.rb and gems.locked setup" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb", - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked", - directory: directory - ) - end - context "that only appears in the lockfile" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency_gems_rb") } let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -630,7 +668,7 @@ end context "with a range requirement" do - let(:gemfile_fixture_name) { "version_between_bounds" } + let(:dependency_files) { bundler_project_dependency_files("version_between_bounds_gems_rb") } let(:requirements) do [{ file: "gems.rb", @@ -646,19 +684,8 @@ end context "given a gem with a path source" do - let(:gemfile_fixture_name) { "path_source" } - let(:lockfile_fixture_name) { "path_source.lock" } - context "with a downloaded gemspec" do - let(:dependency_files) { [gemfile, lockfile, gemspec] } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "plugins/example/example.gemspec", - support_file: true - ) - end - let(:gemspec_fixture_name) { "no_overlap" } + let(:dependency_files) { bundler_project_dependency_files("path_source_no_overlap") } it { is_expected.to eq(Gem::Version.new("1.13.0")) } @@ -668,7 +695,8 @@ end context "that requires other files" do - let(:gemspec_fixture_name) { "no_overlap_with_require" } + let(:dependency_files) { bundler_project_dependency_files("path_source_no_overlap_with_require") } + it { is_expected.to eq(Gem::Version.new("1.13.0")) } end @@ -679,16 +707,7 @@ end context "that has a .specification" do - let(:dependency_files) { [gemfile, lockfile, specification] } - let(:gemfile_fixture_name) { "path_source_statesman" } - let(:lockfile_fixture_name) { "path_source_statesman.lock" } - let(:specification) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "specifications", "statesman"), - name: "vendor/gems/statesman-4.1.1/.specification", - support_file: true - ) - end + let(:dependency_files) { bundler_project_dependency_files("path_source_statesman") } it { is_expected.to eq(Gem::Version.new("1.13.0")) } end @@ -696,8 +715,7 @@ end context "given a gem with a git source" do - let(:lockfile_fixture_name) { "git_source_no_ref.lock" } - let(:gemfile_fixture_name) { "git_source_no_ref" } + let(:dependency_files) { bundler_project_dependency_files("git_source_no_ref") } context "that is the gem we're checking" do let(:dependency_name) { "business" } @@ -709,7 +727,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "master" } @@ -721,7 +739,7 @@ allow_any_instance_of(Dependabot::GitCommitChecker). to receive(:branch_or_ref_in_release?). and_return(false) - git_url = "https://github.com/gocardless/business.git" + git_url = "https://github.com/dependabot-fixtures/business.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -740,10 +758,11 @@ end context "and the Gemfile doesn't specify a git source" do + let(:dependency_files) { bundler_project_dependency_files("git_source_mismatched") } + # If the dependency has a git version in the Gemfile.lock but not in # the Gemfile (i.e., because they're out-of-sync) we leave that # problem to the user. - let(:gemfile_fixture_name) { "Gemfile" } it { is_expected.to be_nil } end end @@ -759,9 +778,7 @@ end context "when the dependency has never been released" do - let(:lockfile_fixture_name) { "git_source.lock" } - let(:gemfile_fixture_name) { "git_source" } - let(:dependency_name) { "prius" } + let(:dependency_files) { bundler_project_dependency_files("git_source") } let(:current_version) { "cff701b3bfb182afc99a85657d7c9f3d6c1ccce2" } let(:requirements) do [{ @@ -770,7 +787,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/prius", + url: "https://github.com/dependabot-fixtures/prius", branch: "master", ref: "master" } @@ -781,7 +798,7 @@ allow_any_instance_of(Dependabot::GitCommitChecker). to receive(:branch_or_ref_in_release?). and_return(false) - git_url = "https://github.com/gocardless/prius.git" + git_url = "https://github.com/dependabot-fixtures/prius.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -801,10 +818,9 @@ end context "when the gem's tag is pinned" do + let(:dependency_files) { bundler_project_dependency_files("git_source") } let(:dependency_name) { "business" } let(:current_version) { "a1b78a929dac93a52f08db4f2847d76d6cfe39bd" } - let(:lockfile_fixture_name) { "git_source.lock" } - let(:gemfile_fixture_name) { "git_source" } let(:requirements) do [{ @@ -813,7 +829,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "a1b78a9" } @@ -853,7 +869,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "v1.0.0" } @@ -863,7 +879,7 @@ before do stub_request(:get, rubygems_url + "versions/business.json"). to_return(status: 404, body: "This rubygem could not be found.") - url = "https://github.com/gocardless/business.git" + url = "https://github.com/dependabot-fixtures/business.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -883,8 +899,7 @@ end context "but this dependency has never been released" do - let(:lockfile_fixture_name) { "git_source_unreleased.lock" } - let(:gemfile_fixture_name) { "git_source_unreleased" } + let(:dependency_files) { bundler_project_dependency_files("git_source_unreleased") } let(:dependency_name) { "dummy-git-dependency" } let(:current_version) do "20151f9b67c8a04461fa0ee28385b6187b86587b" @@ -897,7 +912,7 @@ groups: [], source: { type: "git", - url: "https://github.com/dependabot-fixtures/"\ + url: "https://github.com/dependabot-fixtures/" \ "ruby-dummy-git-dependency", branch: nil, ref: "v1.0.0" @@ -909,7 +924,7 @@ stub_request( :get, rubygems_url + "versions/dummy-git-dependency.json" ).to_return(status: 404) - url = "https://github.com/dependabot-fixtures/"\ + url = "https://github.com/dependabot-fixtures/" \ "ruby-dummy-git-dependency.git" git_header = { "content-type" => @@ -939,10 +954,7 @@ end context "when updating the gem results in a conflict" do - let(:gemfile_fixture_name) { "git_source_with_tag_conflict" } - let(:lockfile_fixture_name) do - "git_source_with_tag_conflict.lock" - end + let(:dependency_files) { bundler_project_dependency_files("git_source_with_tag_conflict") } before do allow_any_instance_of(Dependabot::GitCommitChecker). @@ -986,8 +998,8 @@ end context "when the gem has a version specified, too" do - let(:gemfile_fixture_name) { "git_source_with_version" } - let(:lockfile_fixture_name) { "git_source_with_version.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source_with_version_gemfile") } + let(:requirements) do [{ file: "Gemfile", @@ -995,8 +1007,8 @@ groups: [], source: { type: "git", - url: "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package", + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package", branch: "master", ref: "master" } @@ -1012,8 +1024,8 @@ stub_request( :get, rubygems_url + "versions/dependabot-test-ruby-package.json" ).to_return(status: 404) - git_url = "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package.git" + git_url = "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -1035,8 +1047,7 @@ end context "when the gem has a bad branch" do - let(:gemfile_fixture_name) { "bad_branch" } - let(:lockfile_fixture_name) { "bad_branch.lock" } + let(:dependency_files) { bundler_project_dependency_files("bad_branch") } around { |example| capture_stderr { example.run } } let(:dependency_name) { "prius" } @@ -1048,7 +1059,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/prius", + url: "https://github.com/dependabot-fixtures/prius", branch: "master", ref: "master" } @@ -1059,7 +1070,7 @@ allow_any_instance_of(Dependabot::GitCommitChecker). to receive(:branch_or_ref_in_release?). and_return(false) - git_url = "https://github.com/gocardless/prius.git" + git_url = "https://github.com/dependabot-fixtures/prius.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -1088,8 +1099,7 @@ end context "when updating the gem results in a conflict" do - let(:gemfile_fixture_name) { "git_source_with_conflict" } - let(:lockfile_fixture_name) { "git_source_with_conflict.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source_with_conflict") } around { |example| capture_stderr { example.run } } before do @@ -1136,16 +1146,14 @@ end context "that is not the gem we're checking" do - let(:lockfile_fixture_name) { "git_source.lock" } - let(:gemfile_fixture_name) { "git_source" } + let(:dependency_files) { bundler_project_dependency_files("git_source") } let(:dependency_name) { "statesman" } let(:current_version) { "1.2" } it { is_expected.to eq(Gem::Version.new("3.4.1")) } context "that is private" do - let(:gemfile_fixture_name) { "private_git_source" } - let(:lockfile_fixture_name) { "private_git_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("private_git_source") } let(:token) do Base64.encode64("x-access-token:#{github_token}").delete("\n") end @@ -1154,44 +1162,58 @@ before do stub_request( :get, - "https://github.com/fundingcircle/prius.git/info/refs"\ + "https://github.com/no-exist-sorry/prius.git/info/refs" \ "?service=git-upload-pack" ).with(headers: { "Authorization" => "Basic #{token}" }). to_return(status: 401) end - it "raises a helpful error" do + it "raises a helpful error on bundler v1", :bundler_v1_only do expect { checker.latest_resolvable_version }. to raise_error do |error| expect(error).to be_a(Dependabot::GitDependenciesNotReachable) expect(error.dependency_urls). - to eq(["git@github.com:fundingcircle/prius"]) + to eq(["git@github.com:no-exist-sorry/prius"]) end end + + context "bundler v2", :bundler_v2_only do + let(:dependency_files) { bundler_project_dependency_files("private_git_source") } + + it "updates the dependency" do + expect(checker.latest_resolvable_version).to eq(Gem::Version.new("3.4.1")) + end + end end context "that has a bad reference" do - let(:gemfile_fixture_name) { "bad_ref" } - let(:lockfile_fixture_name) { "bad_ref.lock" } + let(:dependency_files) { bundler_project_dependency_files("bad_ref") } around { |example| capture_stderr { example.run } } before do - stub_request(:get, "https://github.com/gocardless/prius"). + stub_request(:get, "https://github.com/dependabot-fixtures/prius"). to_return(status: 200) end - it "raises a helpful error" do + it "raises a helpful error", :bundler_v1_only do expect { checker.latest_resolvable_version }. to raise_error do |error| expect(error).to be_a Dependabot::GitDependencyReferenceNotFound expect(error.dependency).to eq("prius") end end + + context "bundler v2", :bundler_v2_only do + let(:dependency_files) { bundler_project_dependency_files("bad_ref") } + + it "updates the dependency" do + expect(checker.latest_resolvable_version).to eq(Gem::Version.new("3.4.1")) + end + end end context "that has a bad branch" do - let(:gemfile_fixture_name) { "bad_branch" } - let(:lockfile_fixture_name) { "bad_branch.lock" } + let(:dependency_files) { bundler_project_dependency_files("bad_branch") } it { is_expected.to eq(Gem::Version.new("3.4.1")) } end @@ -1199,7 +1221,7 @@ end context "given a Gemfile that specifies a Ruby version" do - let(:gemfile_fixture_name) { "explicit_ruby" } + let(:dependency_files) { bundler_project_dependency_files("explicit_ruby") } let(:dependency_name) { "statesman" } let(:requirements) do [{ file: "Gemfile", requirement: "~> 1.2.0", groups: [], source: nil }] @@ -1208,16 +1230,14 @@ it { is_expected.to eq(Gem::Version.new("3.4.1")) } context "that is old" do - let(:gemfile_fixture_name) { "explicit_ruby_old" } + let(:dependency_files) { bundler_project_dependency_files("explicit_ruby_old") } - it { is_expected.to eq(Gem::Version.new("2.0.1")) } + xit { is_expected.to eq(Gem::Version.new("2.0.1")) } end end context "with a gemspec and a Gemfile" do - let(:dependency_files) { [gemfile, gemspec] } - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_small_example_no_lockfile") } let(:requirements) do [{ file: "Gemfile", @@ -1238,13 +1258,7 @@ end context "when the gemspec has a path" do - let(:gemfile_fixture_name) { "imports_gemspec_from_path" } - let(:gemspec) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemspecs", gemspec_fixture_name), - name: "subdir/example.gemspec" - ) - end + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_from_path") } let(:requirements) do [{ file: "Gemfile", @@ -1266,7 +1280,7 @@ end context "when an old required ruby is specified in the gemspec" do - let(:gemspec_fixture_name) { "old_required_ruby" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_old_required_ruby_no_lockfile") } let(:dependency_name) { "statesman" } it "takes the minimum ruby version into account" do @@ -1276,7 +1290,7 @@ end context "when the Gemfile doesn't import the gemspec" do - let(:gemfile_fixture_name) { "only_statesman" } + let(:dependency_files) { bundler_project_dependency_files("gemspec_not_imported_no_lockfile") } it "falls back to latest_version" do expect(checker.latest_resolvable_version). @@ -1286,8 +1300,7 @@ end context "with only a gemspec" do - let(:dependency_files) { [gemspec] } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("gemspec_small_example_no_lockfile") } it "falls back to latest_version" do dummy_version_resolver = @@ -1304,8 +1317,7 @@ end context "with only a Gemfile" do - let(:dependency_files) { [gemfile] } - let(:gemfile_fixture_name) { "Gemfile" } + let(:dependency_files) { bundler_project_dependency_files("no_lockfile") } it "doesn't just fall back to latest_version" do expect(checker.latest_resolvable_version). @@ -1313,7 +1325,7 @@ end context "given a gem with a private git source" do - let(:gemfile_fixture_name) { "private_git_source" } + let(:dependency_files) { bundler_project_dependency_files("private_git_source_no_lockfile") } let(:token) do Base64.encode64("x-access-token:#{github_token}").delete("\n") end @@ -1322,7 +1334,7 @@ before do stub_request( :get, - "https://github.com/fundingcircle/prius.git/info/refs"\ + "https://github.com/dependabot-fixtures/does-not-exist.git/info/refs" \ "?service=git-upload-pack" ).with(headers: { "Authorization" => "Basic #{token}" }). to_return(status: 401) @@ -1333,13 +1345,13 @@ to raise_error do |error| expect(error).to be_a(Dependabot::GitDependenciesNotReachable) expect(error.dependency_urls). - to eq(["git@github.com:fundingcircle/prius"]) + to eq(["git@github.com:dependabot-fixtures/does-not-exist"]) end end end context "given a gem with a private github source" do - let(:gemfile_fixture_name) { "private_github_source" } + let(:dependency_files) { bundler_project_dependency_files("private_github_source_no_lockfile") } let(:token) do Base64.encode64("x-access-token:#{github_token}").delete("\n") end @@ -1348,24 +1360,24 @@ before do stub_request( :get, - "https://github.com/fundingcircle/prius.git/info/refs"\ + "https://github.com/dependabot-fixtures/does-not-exist.git/info/refs" \ "?service=git-upload-pack" ).with(headers: { "Authorization" => "Basic #{token}" }). to_return(status: 401) end - it "raises a helpful error" do + it "raises a helpful error", :bundler_v2_only do expect { checker.latest_resolvable_version }. to raise_error do |error| expect(error).to be_a(Dependabot::GitDependenciesNotReachable) expect(error.dependency_urls). - to eq(["git://github.com/fundingcircle/prius.git"]) + to eq(["https://github.com/dependabot-fixtures/does-not-exist.git"]) end end end context "when the git request raises a timeout" do - let(:gemfile_fixture_name) { "private_git_source" } + let(:dependency_files) { bundler_project_dependency_files("private_git_source_no_lockfile") } let(:token) do Base64.encode64("x-access-token:#{github_token}").delete("\n") end @@ -1374,7 +1386,7 @@ before do stub_request( :get, - "https://github.com/fundingcircle/prius.git/info/refs"\ + "https://github.com/dependabot-fixtures/does-not-exist.git/info/refs" \ "?service=git-upload-pack" ).with(headers: { "Authorization" => "Basic #{token}" }). to_raise(Excon::Error::Timeout) @@ -1385,11 +1397,28 @@ to raise_error do |error| expect(error).to be_a(Dependabot::GitDependenciesNotReachable) expect(error.dependency_urls). - to eq(["git@github.com:fundingcircle/prius"]) + to eq(["git@github.com:dependabot-fixtures/does-not-exist"]) end end end end + + context "with a gem that depends on bundler" do + let(:dependency_files) { bundler_project_dependency_files("guard_bundler") } + let(:requirements) do + [{ file: "Gemfile", requirement: "~> 2.2.1, <= 3.0.0", groups: [], source: nil }] + end + let(:dependency_name) { "guard-bundler" } + let(:current_version) { "2.2.1" } + + context "using bundler v1", :bundler_v1_only do + it { is_expected.to eq(Gem::Version.new("2.2.1")) } + end + + context "using bundler v2", :bundler_v2_only do + it { is_expected.to eq(Gem::Version.new("3.0.0")) } + end + end end describe "#preferred_resolvable_version" do @@ -1425,8 +1454,7 @@ it { is_expected.to eq(Gem::Version.new("1.4.0")) } context "with a version conflict at the latest version" do - let(:gemfile_fixture_name) { "version_conflict_no_req_change" } - let(:lockfile_fixture_name) { "version_conflict_no_req_change.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_conflict_no_req_change") } let(:dependency_name) { "ibandit" } let(:current_version) { "0.1.0" } let(:requirements) do @@ -1440,8 +1468,7 @@ end context "with a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -1464,7 +1491,7 @@ end context "with a Gemfile and a Gemfile.lock" do - let(:dependency_files) { [gemfile, lockfile] } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } let(:dependency_name) { "business" } let(:current_version) { "1.4.0" } @@ -1518,8 +1545,7 @@ end context "with a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -1528,20 +1554,7 @@ end context "with a gems.rb and gems.locked" do - let(:gemfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "gemfiles", gemfile_fixture_name), - name: "gems.rb", - directory: directory - ) - end - let(:lockfile) do - Dependabot::DependencyFile.new( - content: fixture("ruby", "lockfiles", lockfile_fixture_name), - name: "gems.locked", - directory: directory - ) - end + let(:dependency_files) { bundler_project_dependency_files("gems_rb") } let(:requirements) do [{ @@ -1569,9 +1582,7 @@ end context "for a gem with a git source" do - let(:gemfile_fixture_name) { "git_source_with_version" } - let(:lockfile_fixture_name) { "git_source_with_version.lock" } - + let(:dependency_files) { bundler_project_dependency_files("git_source_with_version_gemfile") } let(:dependency_name) { "dependabot-test-ruby-package" } let(:current_version) { "81073f9462f228c6894e3e384d0718def310d99f" } let(:requirements) do @@ -1581,8 +1592,8 @@ groups: [:default], source: { type: "git", - url: "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package", + url: "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package", branch: "master", ref: "master" } @@ -1596,8 +1607,8 @@ stub_request( :get, rubygems_url + "versions/dependabot-test-ruby-package.json" ).to_return(status: 404) - git_url = "https://github.com/dependabot-fixtures/"\ - "dependabot-test-ruby-package.git" + git_url = "https://github.com/dependabot-fixtures/" \ + "dependabot-test-ruby-package.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -1627,8 +1638,7 @@ end context "that is pinned" do - let(:gemfile_fixture_name) { "git_source" } - let(:lockfile_fixture_name) { "git_source.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source") } let(:dependency_name) { "business" } let(:current_version) { "a1b78a929dac93a52f08db4f2847d76d6cfe39bd" } @@ -1639,7 +1649,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "a1b78a9" } @@ -1677,7 +1687,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "v1.0.0" } @@ -1685,7 +1695,7 @@ end before do - git_url = "https://github.com/gocardless/business.git" + git_url = "https://github.com/dependabot-fixtures/business.git" git_header = { "content-type" => "application/x-git-upload-pack-advertisement" } @@ -1699,7 +1709,7 @@ end it "delegates to Bundler::RequirementsUpdater" do - # Note: the v1.13.0 for the source is because we stub the lookup + # NOTE: the v1.13.0 for the source is because we stub the lookup # for the updated source expect(requirements_updater). to receive(:new).with( @@ -1709,7 +1719,7 @@ latest_resolvable_version: "1.13.0", updated_source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "v1.13.0" } @@ -1749,10 +1759,7 @@ end context "with a Gemfile, a Gemfile.lock and a gemspec" do - let(:dependency_files) { [gemfile, gemspec, lockfile] } - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:lockfile_fixture_name) { "imports_gemspec.lock" } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec") } let(:dependency_name) { "business" } let(:current_version) { "1.4.0" } @@ -1787,9 +1794,7 @@ end context "with a Gemfile and a gemspec" do - let(:dependency_files) { [gemfile, gemspec] } - let(:gemfile_fixture_name) { "imports_gemspec" } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("imports_gemspec_small_example_no_lockfile") } let(:dependency_name) { "business" } let(:current_version) { nil } @@ -1824,7 +1829,7 @@ end context "with a Gemfile only" do - let(:dependency_files) { [gemfile] } + let(:dependency_files) { bundler_project_dependency_files("no_lockfile") } let(:dependency_name) { "business" } let(:current_version) { nil } let(:requirements) do @@ -1852,8 +1857,7 @@ end context "with a gemspec only" do - let(:dependency_files) { [gemspec] } - let(:gemspec_fixture_name) { "small_example" } + let(:dependency_files) { bundler_project_dependency_files("gemspec_no_lockfile") } let(:dependency_name) { "business" } let(:current_version) { nil } let(:requirements) do @@ -1885,8 +1889,7 @@ subject { checker.requirements_unlocked_or_can_be? } context "with a Gemfile dependency that is already unlocked" do - let(:gemfile_fixture_name) { "version_not_specified" } - let(:lockfile_fixture_name) { "version_not_specified.lock" } + let(:dependency_files) { bundler_project_dependency_files("version_not_specified") } let(:requirements) do [{ file: "Gemfile", requirement: ">= 0", groups: [], source: nil }] end @@ -1895,8 +1898,7 @@ end context "with a sub-dependency" do - let(:gemfile_fixture_name) { "subdependency" } - let(:lockfile_fixture_name) { "subdependency.lock" } + let(:dependency_files) { bundler_project_dependency_files("subdependency") } let(:requirements) { [] } let(:dependency_name) { "i18n" } let(:current_version) { "0.7.0.beta1" } @@ -1905,8 +1907,7 @@ end context "with a Gemfile dependency that can be unlocked" do - let(:gemfile_fixture_name) { "Gemfile" } - let(:lockfile_fixture_name) { "Gemfile.lock" } + let(:dependency_files) { bundler_project_dependency_files("gemfile") } let(:requirements) do [{ file: "Gemfile", requirement: req, groups: [], source: nil }] end @@ -1915,7 +1916,7 @@ it { is_expected.to eq(true) } context "with multiple requirements" do - let(:gemfile_fixture_name) { "version_between_bounds" } + let(:dependency_files) { bundler_project_dependency_files("version_between_bounds_gemfile") } let(:req) { "> 1.0.0, < 1.5.0" } it { is_expected.to eq(true) } @@ -1924,8 +1925,7 @@ # For now we always let git dependencies through context "with a Gemfile dependency that is a git dependency" do - let(:gemfile_fixture_name) { "git_source_no_ref" } - let(:lockfile_fixture_name) { "git_source_no_ref.lock" } + let(:dependency_files) { bundler_project_dependency_files("git_source_no_ref") } let(:requirements) do [{ file: "Gemfile", @@ -1933,7 +1933,7 @@ groups: [], source: { type: "git", - url: "https://github.com/gocardless/business", + url: "https://github.com/dependabot-fixtures/business", branch: "master", ref: "master" } @@ -1944,7 +1944,7 @@ end context "with a Gemfile with a function version" do - let(:gemfile_fixture_name) { "function_version" } + let(:dependency_files) { bundler_project_dependency_files("function_version_gemfile") } let(:requirements) do [{ file: "Gemfile", requirement: "1.0.0", groups: [], source: nil }] end diff --git a/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile b/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile new file mode 100644 index 00000000000..b6cf85ff122 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius", branch: "bad" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile.lock new file mode 100644 index 00000000000..973b58c891b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_branch/Gemfile.lock @@ -0,0 +1,23 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + branch: bad + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.14.6 diff --git a/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile b/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile new file mode 100644 index 00000000000..59ef4eb67a9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", git: "https://github.com/dependabot-fixtures/business", branch: "bad" +gem "statesman", "~> 1.2.0" +gem "prius", "~> 1.0.0" diff --git a/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile.lock new file mode 100644 index 00000000000..9b3fecdea72 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_branch_business/Gemfile.lock @@ -0,0 +1,23 @@ +GIT + remote: https://github.com/dependabot-fixtures/business + revision: d41e445215b5af70c1604715d97dd953e868380e + branch: bad_branch + specs: + business (1.10.0) + +GEM + remote: https://rubygems.org/ + specs: + prius (1.0.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business! + prius (~> 1.0.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile b/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile new file mode 100644 index 00000000000..d77611ce290 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile.lock new file mode 100644 index 00000000000..96ad9f03e0d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bad_ref/Gemfile.lock @@ -0,0 +1,22 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce1 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/ruby/gemfiles/block_source_rubygems b/bundler/spec/fixtures/projects/bundler1/block_source_rubygems/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/block_source_rubygems rename to bundler/spec/fixtures/projects/bundler1/block_source_rubygems/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/block_source_rubygems.lock b/bundler/spec/fixtures/projects/bundler1/block_source_rubygems/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/block_source_rubygems.lock rename to bundler/spec/fixtures/projects/bundler1/block_source_rubygems/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/blocked_by_subdep b/bundler/spec/fixtures/projects/bundler1/blocked_by_subdep/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/blocked_by_subdep rename to bundler/spec/fixtures/projects/bundler1/blocked_by_subdep/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/blocked_by_subdep.lock b/bundler/spec/fixtures/projects/bundler1/blocked_by_subdep/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/blocked_by_subdep.lock rename to bundler/spec/fixtures/projects/bundler1/blocked_by_subdep/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/bundler_specified b/bundler/spec/fixtures/projects/bundler1/bundler_specified/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/bundler_specified rename to bundler/spec/fixtures/projects/bundler1/bundler_specified/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/bundler_specified.lock b/bundler/spec/fixtures/projects/bundler1/bundler_specified/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/bundler_specified.lock rename to bundler/spec/fixtures/projects/bundler1/bundler_specified/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/bundler_specified_in_source b/bundler/spec/fixtures/projects/bundler1/bundler_specified_in_source_bundler_specified/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/bundler_specified_in_source rename to bundler/spec/fixtures/projects/bundler1/bundler_specified_in_source_bundler_specified/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/bundler_specified_in_source_bundler_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/bundler_specified_in_source_bundler_specified/Gemfile.lock new file mode 100644 index 00000000000..7e5129246ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/bundler_specified_in_source_bundler_specified/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 1.15.0) + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.4 diff --git a/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile b/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile new file mode 100644 index 00000000000..3fcd714d947 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.6.0" +gem "i18n", git: "https://github.com/dependabot-fixtures/i18n" diff --git a/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile.lock new file mode 100644 index 00000000000..85a8667a8ff --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/cant_unlock_subdep/Gemfile.lock @@ -0,0 +1,21 @@ +GIT + remote: https://github.com/dependabot-fixtures/i18n + revision: d049c7115f59689efb123d61430c078c6feb7537 + specs: + i18n (0.7.0) + +GEM + remote: https://rubygems.org/ + specs: + ibandit (0.6.6) + i18n (~> 0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + i18n! + ibandit (~> 0.6.0) + +BUNDLED WITH + 1.16.3 diff --git a/bundler/spec/fixtures/projects/bundler1/comment_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/comment_gemfile/Gemfile new file mode 100644 index 00000000000..fb635a712c1 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/comment_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", git: "git_url" # My gem diff --git a/bundler/spec/fixtures/ruby/lockfiles/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/comment_gemfile/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/Gemfile.lock rename to bundler/spec/fixtures/projects/bundler1/comment_gemfile/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/comments b/bundler/spec/fixtures/projects/bundler1/comments_no_lockfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/comments rename to bundler/spec/fixtures/projects/bundler1/comments_no_lockfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile b/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile new file mode 100644 index 00000000000..b672cd73c87 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" + +if ENV["STATESMAN_NEXT"] == "1" + gem "statesman", "~> 7.2.0" +else + gem "statesman", "~> 1.2.0" # rubocop:disable Bundler/DuplicatedGem +end diff --git a/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/conditional/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-7.2.0.gem b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-7.2.0.gem new file mode 100644 index 00000000000..94abbab8bbb Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/conditional/vendor/cache/statesman-7.2.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile new file mode 100644 index 00000000000..44c20033953 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", github: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/custom_tag_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/default_gem_specified b/bundler/spec/fixtures/projects/bundler1/default_gem_specified/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/default_gem_specified rename to bundler/spec/fixtures/projects/bundler1/default_gem_specified/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/default_gem_specified.lock b/bundler/spec/fixtures/projects/bundler1/default_gem_specified/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/default_gem_specified.lock rename to bundler/spec/fixtures/projects/bundler1/default_gem_specified/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/development_dependencies b/bundler/spec/fixtures/projects/bundler1/development_dependencies/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/development_dependencies rename to bundler/spec/fixtures/projects/bundler1/development_dependencies/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/development_dependencies.lock b/bundler/spec/fixtures/projects/bundler1/development_dependencies/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/development_dependencies.lock rename to bundler/spec/fixtures/projects/bundler1/development_dependencies/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/eval_gemfile_absolute b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/eval_gemfile_absolute rename to bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/only_statesman b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/backend/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/only_statesman rename to bundler/spec/fixtures/projects/bundler1/eval_gemfile_absolute/backend/Gemfile diff --git a/bundler/spec/fixtures/ruby/gemfiles/eval_gemfile b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/eval_gemfile rename to bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/backend/Gemfile b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_gemfile/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile new file mode 100644 index 00000000000..5febdf9583f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +eval_gemfile('backend/Gemfile') + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/backend/Gemfile b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_nested/nested/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/eval_gemfile_variable b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/eval_gemfile_variable rename to bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/backend/Gemfile b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/eval_gemfile_variable/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/exec_error b/bundler/spec/fixtures/projects/bundler1/exec_error_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/exec_error rename to bundler/spec/fixtures/projects/bundler1/exec_error_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/exec_error_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/exec_error_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/exec_error_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/exec_error_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/exec_error_no_lockfile/Gemfile new file mode 100644 index 00000000000..d438c188756 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/exec_error_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +exec "curl https://example.com" + +source "https://rubygems.org" + +gem "business", "~> 1.0.0" +gem "uk_phone_numbers", "~> 0.1.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/explicit_ruby b/bundler/spec/fixtures/projects/bundler1/explicit_ruby/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/explicit_ruby rename to bundler/spec/fixtures/projects/bundler1/explicit_ruby/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/explicit_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/explicit_ruby/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/explicit_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile new file mode 100644 index 00000000000..19cbfcc4b7f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile @@ -0,0 +1,5 @@ +ruby "2.2.0" +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile.lock new file mode 100644 index 00000000000..7be0c623b86 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_in_lockfile/Gemfile.lock @@ -0,0 +1,18 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +RUBY VERSION + ruby 2.2.0p0 + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/explicit_ruby_old b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_old/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/explicit_ruby_old rename to bundler/spec/fixtures/projects/bundler1/explicit_ruby_old/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/explicit_ruby_old/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_old/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/explicit_ruby_old/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/function_version b/bundler/spec/fixtures/projects/bundler1/function_version_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/function_version rename to bundler/spec/fixtures/projects/bundler1/function_version_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/function_version_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/function_version_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/function_version_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/gem_with_number b/bundler/spec/fixtures/projects/bundler1/gem_with_number/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/gem_with_number rename to bundler/spec/fixtures/projects/bundler1/gem_with_number/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/gem_with_number.lock b/bundler/spec/fixtures/projects/bundler1/gem_with_number/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/gem_with_number.lock rename to bundler/spec/fixtures/projects/bundler1/gem_with_number/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/Gemfile rename to bundler/spec/fixtures/projects/bundler1/gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/composer/spec/fixtures/composer_files/unparseable b/bundler/spec/fixtures/projects/bundler1/gemfile_exact/Gemfile similarity index 100% rename from composer/spec/fixtures/composer_files/unparseable rename to bundler/spec/fixtures/projects/bundler1/gemfile_exact/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_exact/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_exact/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_exact/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/exact b/bundler/spec/fixtures/projects/bundler1/gemfile_exact/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/exact rename to bundler/spec/fixtures/projects/bundler1/gemfile_exact/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_example/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/example b/bundler/spec/fixtures/projects/bundler1/gemfile_example/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/example rename to bundler/spec/fixtures/projects/bundler1/gemfile_example/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/function_name b/bundler/spec/fixtures/projects/bundler1/gemfile_function_name/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/function_name rename to bundler/spec/fixtures/projects/bundler1/gemfile_function_name/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/with_require b/bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/with_require rename to bundler/spec/fixtures/projects/bundler1/gemfile_gemspec_with_require/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/impossible_ruby b/bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/impossible_ruby rename to bundler/spec/fixtures/projects/bundler1/gemfile_impossible_ruby/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile new file mode 100644 index 00000000000..de75a07e91e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile @@ -0,0 +1 @@ +gem "business", ">= 1", "< 3", require: true diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_git_requirements/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile new file mode 100644 index 00000000000..de75a07e91e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile @@ -0,0 +1 @@ +gem "business", ">= 1", "< 3", require: true diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile new file mode 100644 index 00000000000..65e6a4ac20e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile @@ -0,0 +1 @@ +gem "business", [">= 1", "<3"], require: true diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_array/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/example.gemspec new file mode 100644 index 00000000000..6b7414313e3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_multiple_requirements_parenthesis/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency("business", ">= 1", "< 3") diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/no_required_ruby b/bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/no_required_ruby rename to bundler/spec/fixtures/projects/bundler1/gemfile_no_required_ruby/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/old_required_ruby b/bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/old_required_ruby rename to bundler/spec/fixtures/projects/bundler1/gemfile_old_required_ruby/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/example.gemspec new file mode 100644 index 00000000000..07f1eb62379 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 3.0.1" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/example.gemspec new file mode 100644 index 00000000000..76e2d25bc8d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_require_ruby_3_1/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 3.1.1" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/small_example b/bundler/spec/fixtures/projects/bundler1/gemfile_small_example/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/small_example rename to bundler/spec/fixtures/projects/bundler1/gemfile_small_example/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/unevaluatable_ruby b/bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/unevaluatable_ruby rename to bundler/spec/fixtures/projects/bundler1/gemfile_unevaluatable_ruby/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemspecs/with_nested_block b/bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/with_nested_block rename to bundler/spec/fixtures/projects/bundler1/gemfile_with_nested_block/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/example.gemspec new file mode 100644 index 00000000000..da77199c39d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemfile_with_require/example.gemspec @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.locked new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.rb new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gems_rb/gems.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/another.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/another.gemspec new file mode 100644 index 00000000000..997bd60a94c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/another.gemspec @@ -0,0 +1,23 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' + spec.add_dependency 'statesman', '= 1.0.0' + spec.add_development_dependency 'rake' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/example.gemspec new file mode 100644 index 00000000000..bec8987c977 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/example.gemspec @@ -0,0 +1,30 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + another_gemspec = Bundler.load_gemspec_uncached("another.gemspec") + + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_development_dependency "webmock", "~> 2.3.1" + + another_gemspec.development_dependencies.each do |dep| + spec.add_development_dependency dep.name, *dep.requirement.as_list + end +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile new file mode 100644 index 00000000000..de75a07e91e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile @@ -0,0 +1 @@ +gem "business", ">= 1", "< 3", require: true diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/example.gemspec new file mode 100644 index 00000000000..48ad347d63a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency "business", ">= 1", "< 3" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/example.gemspec new file mode 100644 index 00000000000..360854054f2 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_multiple_requirements_array/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency "business", [">= 1", "<3"] diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_no_gemfile/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_no_lockfile/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_no_lockfile/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/example.gemspec new file mode 100644 index 00000000000..da77199c39d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported/example.gemspec @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_not_imported_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/example.gemspec new file mode 100644 index 00000000000..90e236e18cb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.2, < 4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/example.gemspec new file mode 100644 index 00000000000..57312f3847e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_range_array/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = [">= 2.2", "< 4.0"] + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/Gemfile b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/example.gemspec new file mode 100644 index 00000000000..a07f63f0345 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_required_ruby_version_requirement_class/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = Gem::Requirement.new(">= 2.1.8", "< 4.0.0") + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_small_example_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_small_example_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_small_example_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/gemspec_with_require_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/gemspec_with_require_no_lockfile/example.gemspec new file mode 100644 index 00000000000..705e935a3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/gemspec_with_require_no_lockfile/example.gemspec @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "find" + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "example/version" + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile new file mode 100644 index 00000000000..46b167a6d0d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "statesman", "~> 1.2.0" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile.lock new file mode 100644 index 00000000000..5821309de29 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_circular b/bundler/spec/fixtures/projects/bundler1/git_source_circular/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/git_source_circular rename to bundler/spec/fixtures/projects/bundler1/git_source_circular/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_circular.lock b/bundler/spec/fixtures/projects/bundler1/git_source_circular/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/git_source_circular.lock rename to bundler/spec/fixtures/projects/bundler1/git_source_circular/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile new file mode 100644 index 00000000000..46b167a6d0d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "statesman", "~> 1.2.0" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile new file mode 100644 index 00000000000..754a6acd9f8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "parallel", git: "git@github.com:dependabot-fixtures/parallel", ref: "v1.12.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile.lock new file mode 100644 index 00000000000..9867e9c869c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_internal/Gemfile.lock @@ -0,0 +1,21 @@ +GIT + remote: git@github.com:dependabot-fixtures/parallel + revision: 5fa4406bcf0b3109f645550ca799fc7570501870 + ref: v1.12.0 + specs: + parallel (1.12.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + parallel! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile new file mode 100644 index 00000000000..f9aaffb1fbf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile.lock new file mode 100644 index 00000000000..5821309de29 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_mismatched/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile new file mode 100644 index 00000000000..54834ed2d50 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", git: "git@github.com:dependabot-fixtures/business" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile.lock new file mode 100644 index 00000000000..948f0399faa --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_no_ref/Gemfile.lock @@ -0,0 +1,18 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + specs: + business (1.6.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile.lock new file mode 100644 index 00000000000..24c7f0fc894 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_outdated/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile.lock new file mode 100644 index 00000000000..24c7f0fc894 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_reordered/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile new file mode 100644 index 00000000000..7bf79835354 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile @@ -0,0 +1,7 @@ +source "http://rubygems.org" + +git "https://github.com/dependabot-fixtures/kaminari" do + gem "kaminari-core" +end + +gem 'kaminari-actionview' diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile.lock new file mode 100644 index 00000000000..4cd98f534f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_undeclared/Gemfile.lock @@ -0,0 +1,54 @@ +GIT + remote: https://github.com/dependabot-fixtures/kaminari + revision: 62ec743dcee69e02186e5f1a309b08e59d83f647 + specs: + kaminari-actionview (1.1.1) + actionview + kaminari-core (= 1.1.1) + kaminari-core (1.1.1) + +GEM + remote: http://rubygems.org/ + specs: + actionview (5.1.6) + activesupport (= 5.1.6) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activesupport (5.1.6) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + builder (3.2.3) + concurrent-ruby (1.0.5) + crass (1.0.3) + erubi (1.7.1) + i18n (1.0.0) + concurrent-ruby (~> 1.0) + loofah (2.2.2) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mini_portile2 (2.3.0) + minitest (5.11.3) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + kaminari-actionview + kaminari-core! + +BUNDLED WITH + 1.16.1 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile new file mode 100644 index 00000000000..fcae7c722cf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +def git_gem(name, **options) + gem name, git: "git@github.com:dependabot-fixtures/business" +end + +git_gem 'business' + +gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile.lock new file mode 100644 index 00000000000..b5a8cfa05c3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/Gemfile.lock @@ -0,0 +1,25 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: 1378a2b0b446d991b7567efbc7eeeed2720e4d8f + specs: + business (1.16.0) + +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + business! + example! + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/example.gemspec b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_unparseable/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_unreleased b/bundler/spec/fixtures/projects/bundler1/git_source_unreleased/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/git_source_unreleased rename to bundler/spec/fixtures/projects/bundler1/git_source_unreleased/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_unreleased.lock b/bundler/spec/fixtures/projects/bundler1/git_source_unreleased/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/git_source_unreleased.lock rename to bundler/spec/fixtures/projects/bundler1/git_source_unreleased/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile new file mode 100644 index 00000000000..899ac4d6a52 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "rest-client", "~> 1.8" +gem "onfido", git: "https://github.com/dependabot-fixtures/onfido" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile.lock new file mode 100644 index 00000000000..af51d877878 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_conflict/Gemfile.lock @@ -0,0 +1,34 @@ +GIT + remote: https://github.com/dependabot-fixtures/onfido + revision: 7b36eac82a7e42049052a58af0a7943fe0363714 + ref: v0.4.0 + specs: + onfido (0.4.0) + rest-client (~> 1.8.0) + +GEM + remote: https://rubygems.org/ + specs: + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + mime-types (2.99.3) + netrc (0.11.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) + +PLATFORMS + ruby + +DEPENDENCIES + onfido! + rest-client (~> 1.8) + +BUNDLED WITH + 1.16.0.pre.3 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile new file mode 100644 index 00000000000..9ff8d43fd46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "elasticsearch-dsl", + github: "dependabot-fixtures/elasticsearch-ruby", + branch: "5.x", + require: "elasticsearch/dsl" +gem "elasticsearch-model", github: "dependabot-fixtures/elasticsearch-rails", branch: "5.x" +gem "elasticsearch-rails", github: "dependabot-fixtures/elasticsearch-rails", branch: "5.x" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile.lock new file mode 100644 index 00000000000..bb068bb4775 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_multiple_deps/Gemfile.lock @@ -0,0 +1,57 @@ +GIT + remote: https://github.com/dependabot-fixtures/elasticsearch-rails.git + revision: 212b37a1e927015f2a095e0f841c897d377ad1c7 + branch: 5.x + specs: + elasticsearch-model (5.1.0) + activesupport (> 3) + elasticsearch (~> 5) + hashie + elasticsearch-rails (5.1.0) + +GIT + remote: https://github.com/dependabot-fixtures/elasticsearch-ruby.git + revision: 43f48b229a975b77c5339644d512c88389fefafa + branch: 5.x + specs: + elasticsearch (5.0.4) + elasticsearch-api (= 5.0.4) + elasticsearch-transport (= 5.0.4) + elasticsearch-api (5.0.4) + multi_json + elasticsearch-dsl (0.1.4) + elasticsearch-transport (5.0.4) + faraday + multi_json + +GEM + remote: https://rubygems.org/ + specs: + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + concurrent-ruby (1.0.5) + faraday (0.15.2) + multipart-post (>= 1.2, < 3) + hashie (3.5.7) + i18n (1.0.1) + concurrent-ruby (~> 1.0) + minitest (5.11.3) + multi_json (1.13.1) + multipart-post (2.0.0) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + elasticsearch-dsl! + elasticsearch-model! + elasticsearch-rails! + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile new file mode 100644 index 00000000000..64283612f00 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "rest-client", "~> 1.8" +gem "onfido", git: "https://github.com/dependabot-fixtures/onfido", ref: "v0.4.0" diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile.lock new file mode 100644 index 00000000000..af51d877878 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_tag_conflict/Gemfile.lock @@ -0,0 +1,34 @@ +GIT + remote: https://github.com/dependabot-fixtures/onfido + revision: 7b36eac82a7e42049052a58af0a7943fe0363714 + ref: v0.4.0 + specs: + onfido (0.4.0) + rest-client (~> 1.8.0) + +GEM + remote: https://rubygems.org/ + specs: + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + mime-types (2.99.3) + netrc (0.11.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) + +PLATFORMS + ruby + +DEPENDENCIES + onfido! + rest-client (~> 1.8) + +BUNDLED WITH + 1.16.0.pre.3 diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_version b/bundler/spec/fixtures/projects/bundler1/git_source_with_version_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/git_source_with_version rename to bundler/spec/fixtures/projects/bundler1/git_source_with_version_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/git_source_with_version_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_source_with_version_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_source_with_version_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile new file mode 100644 index 00000000000..c876180cc40 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile @@ -0,0 +1,2 @@ +gem "prius", "1.0.0", require: false, +git: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/git_tags_on_newline_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile b/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile new file mode 100644 index 00000000000..d296c477b65 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", github: "dependabot-fixtures/business" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile.lock new file mode 100644 index 00000000000..4fff9268c73 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/github_source/Gemfile.lock @@ -0,0 +1,20 @@ +GIT + remote: https://github.com/dependabot-fixtures/business.git + revision: d31e445215b5af70c1604715d97dd953e868380e + specs: + business (1.10.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.16.0.pre.3 diff --git a/bundler/spec/fixtures/ruby/gemfiles/gte_matcher b/bundler/spec/fixtures/projects/bundler1/gte_matcher/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/gte_matcher rename to bundler/spec/fixtures/projects/bundler1/gte_matcher/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/gte_matcher.lock b/bundler/spec/fixtures/projects/bundler1/gte_matcher/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/gte_matcher.lock rename to bundler/spec/fixtures/projects/bundler1/gte_matcher/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile b/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile new file mode 100644 index 00000000000..686cbd2c37d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "guard-bundler", "~> 2.2.1" diff --git a/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile.lock new file mode 100644 index 00000000000..694632ca429 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/guard_bundler/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + ffi (1.14.2) + formatador (0.2.5) + guard (2.16.2) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.2.1) + bundler (>= 1.3.0, < 3) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + listen (3.4.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.8) + method_source (1.0.0) + nenv (0.3.0) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.0) + coderay (~> 1.1) + method_source (~> 1.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + shellany (0.0.1) + thor (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-bundler (= 2.2.1) + +BUNDLED WITH + 1.7.3 diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/imports_gemspec rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/imports_gemspec.lock rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_from_path b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_from_path rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_from_path.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_from_path.lock rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/subdir/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/subdir/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_nested_path/nested/subdir/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile new file mode 100644 index 00000000000..c735e46b5d7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec path: 'subdir' + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile.lock new file mode 100644 index 00000000000..17163f01421 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: subdir + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.3 diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/subdir/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/subdir/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_from_path/subdir/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/Gemfile new file mode 100644 index 00000000000..b433ef5f481 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0", git: "https://github.com/dependabot-fixtures/business" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_git_override_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_large.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_large.lock rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_imports_gemspec_large/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_no_default_source b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_default_source_no_lockfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_no_default_source rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_default_source_no_lockfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_default_source_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_default_source_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_default_source_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/Gemfile new file mode 100644 index 00000000000..49322c66178 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_lockfile/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile.lock new file mode 100644 index 00000000000..f58baefbb9f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.3 diff --git a/bundler/spec/fixtures/ruby/gemspecs/no_overlap b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/no_overlap rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_no_overlap/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a1543e7694d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 1.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_small_example_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile.lock new file mode 100644 index 00000000000..f58baefbb9f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.3 diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/example.gemspec new file mode 100644 index 00000000000..c605f05bca6 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_unevaluatable/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "1.0.0" + spec.summary = bad_code # <----- The bad code is here + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_as_float/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_as_float/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_as_float/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemspecs/version_as_float b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_as_float/version_as_float.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/version_as_float rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_as_float/version_as_float.gemspec diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_version_clash b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_clash_old_required_ruby_no_lockfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_version_clash rename to bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_clash_old_required_ruby_no_lockfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a1543e7694d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 1.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile.lock new file mode 100644 index 00000000000..40c784e5ae6 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/Gemfile.lock @@ -0,0 +1,96 @@ +PATH + remote: . + specs: + example (0.9.3) + bundler (>= 1.12.0) + excon (~> 0.55) + gemnasium-parser (~> 0.1) + gems (~> 1.0) + gitlab (~> 4.1) + octokit (~> 4.6) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + ast (2.3.0) + business (1.4.0) + crack (0.4.3) + safe_yaml (~> 1.0.0) + diff-lcs (1.3) + excon (0.58.0) + faraday (0.12.2) + multipart-post (>= 1.2, < 3) + gemnasium-parser (0.1.9) + gems (1.0.0) + json + gitlab (4.2.0) + httparty + terminal-table + hashdiff (0.3.5) + httparty (0.15.6) + multi_xml (>= 0.5.2) + json (2.1.0) + multi_xml (0.6.0) + multipart-post (2.0.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + parser (2.4.0.0) + ast (~> 2.2) + powerpack (0.1.1) + public_suffix (2.0.5) + rainbow (2.2.2) + rake + rake (12.0.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.4) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + statesman (1.2.5) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.3.0) + webmock (2.3.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + rake + rspec (~> 3.5.0) + rspec-its (~> 1.2.0) + rubocop (~> 0.48.0) + statesman (~> 1.2.0) + webmock (~> 2.3.1) + +BUNDLED WITH + 1.15.3 diff --git a/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/example.gemspec new file mode 100644 index 00000000000..705e935a3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_gemspec_with_require/example.gemspec @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "find" + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "example/version" + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_two_gemspecs b/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/imports_two_gemspecs rename to bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/imports_two_gemspecs.lock b/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/imports_two_gemspecs.lock rename to bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/example.gemspec b/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/ruby/gemspecs/small_example2 b/bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/example2.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/small_example2 rename to bundler/spec/fixtures/projects/bundler1/imports_two_gemspecs/example2.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile new file mode 100644 index 00000000000..ff8bd34cc60 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "../some_other_file" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/some_other_file.rb b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/some_other_file.rb new file mode 100644 index 00000000000..9e3706a079f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_gemfile/some_other_file.rb @@ -0,0 +1 @@ +SOME_CONSTANT = 5 \ No newline at end of file diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile new file mode 100644 index 00000000000..cb5e001ec6f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "./nested/some_other_file" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/nested/some_other_file.rb b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/nested/some_other_file.rb new file mode 100644 index 00000000000..9e3706a079f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_require_relative_nested/nested/some_other_file.rb @@ -0,0 +1 @@ +SOME_CONSTANT = 5 \ No newline at end of file diff --git a/bundler/spec/fixtures/ruby/gemfiles/includes_requires b/bundler/spec/fixtures/projects/bundler1/includes_requires_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/includes_requires rename to bundler/spec/fixtures/projects/bundler1/includes_requires_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/includes_requires_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/includes_requires_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/includes_requires_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/interpolated_version b/bundler/spec/fixtures/projects/bundler1/interpolated_version_no_lockfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/interpolated_version rename to bundler/spec/fixtures/projects/bundler1/interpolated_version_no_lockfile/Gemfile diff --git a/bundler/spec/fixtures/ruby/gemfiles/invalid_ruby b/bundler/spec/fixtures/projects/bundler1/invalid_ruby/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/invalid_ruby rename to bundler/spec/fixtures/projects/bundler1/invalid_ruby/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/jfrog_source/Gemfile b/bundler/spec/fixtures/projects/bundler1/jfrog_source/Gemfile new file mode 100644 index 00000000000..ad50e194e10 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/jfrog_source/Gemfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" + +source "https://test.jfrog.io/test/api/gems" do + gem "statesman", "~> 1.2.0" +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/jruby b/bundler/spec/fixtures/projects/bundler1/jruby/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/jruby rename to bundler/spec/fixtures/projects/bundler1/jruby/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/jruby.lock b/bundler/spec/fixtures/projects/bundler1/jruby/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/jruby.lock rename to bundler/spec/fixtures/projects/bundler1/jruby/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/legacy_ruby b/bundler/spec/fixtures/projects/bundler1/legacy_ruby/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/legacy_ruby rename to bundler/spec/fixtures/projects/bundler1/legacy_ruby/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/legacy_ruby.lock b/bundler/spec/fixtures/projects/bundler1/legacy_ruby/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/legacy_ruby.lock rename to bundler/spec/fixtures/projects/bundler1/legacy_ruby/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/lockfile_only/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/lockfile_only/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/lockfile_only/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/minor_version_specified b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/minor_version_specified rename to bundler/spec/fixtures/projects/bundler1/minor_version_specified_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/minor_version_specified_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/minor_version_specified_yanked_gem/Gemfile b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_yanked_gem/Gemfile new file mode 100644 index 00000000000..937f204c571 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_yanked_gem/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +# The Gemfile.lock for this project has `business` at 1.4.1, which has been +# yanked +gem "business", "~> 1.4" +gem "statesman", "~> 1.2" diff --git a/bundler/spec/fixtures/ruby/lockfiles/yanked_gem.lock b/bundler/spec/fixtures/projects/bundler1/minor_version_specified_yanked_gem/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/yanked_gem.lock rename to bundler/spec/fixtures/projects/bundler1/minor_version_specified_yanked_gem/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile b/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile new file mode 100644 index 00000000000..eb7111e1ad4 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gem "activesupport", "5.0.0" +gem "actionview", "5.0.0" +gem "actionmailer", "5.0.0" diff --git a/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile.lock new file mode 100644 index 00000000000..4d9431f430d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/multiple_blocking/Gemfile.lock @@ -0,0 +1,70 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (5.0.0) + actionpack (= 5.0.0) + actionview (= 5.0.0) + activejob (= 5.0.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.0.0) + actionview (= 5.0.0) + activesupport (= 5.0.0) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.0.0) + activesupport (= 5.0.0) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + activejob (5.0.0) + activesupport (= 5.0.0) + globalid (>= 0.3.6) + activesupport (5.0.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + builder (3.2.4) + concurrent-ruby (1.1.7) + crass (1.0.6) + erubis (2.7.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + loofah (2.7.0) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.14.2) + nokogiri (1.10.10) + mini_portile2 (~> 2.4.0) + rack (2.2.3) + rack-test (0.6.3) + rack (>= 1.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + thread_safe (0.3.6) + tzinfo (1.2.7) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + actionmailer (= 5.0.0) + actionview (= 5.0.0) + activesupport (= 5.0.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile new file mode 100644 index 00000000000..7029d36a5b7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +eval_gemfile("backend/Gemfile") + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemfile/backend/Gemfile b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/backend/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemfile/backend/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_not_specified b/bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_not_specified rename to bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_not_specified.lock b/bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/version_not_specified.lock rename to bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/nested/Gemfile b/bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/nested/Gemfile new file mode 100644 index 00000000000..3a258a2ac67 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemfile_version_not_specified/nested/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business" +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/nested_gemspec/some/example.gemspec b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/some/example.gemspec new file mode 100644 index 00000000000..2a65bafba92 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_gemspec/some/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "business", "~> 1.0" +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/path_source b/bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/path_source rename to bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/path_source.lock b/bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/path_source.lock rename to bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/example/example.gemspec b/bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/example/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/nested_path_source/nested/example/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler1/no_bundled_with/Gemfile b/bundler/spec/fixtures/projects/bundler1/no_bundled_with/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/no_bundled_with/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/lockfiles/no_bundled_with.lock b/bundler/spec/fixtures/projects/bundler1/no_bundled_with/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/no_bundled_with.lock rename to bundler/spec/fixtures/projects/bundler1/no_bundled_with/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/no_lockfile/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile new file mode 100644 index 00000000000..f481e70aa4f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", git: "git_url", require: false diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_end_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile new file mode 100644 index 00000000000..40050f9da15 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", require: false, git: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_at_start_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile new file mode 100644 index 00000000000..0e182d6e47e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile @@ -0,0 +1,2 @@ +gem "prius", "1.0.0", git: "git_url", +require: false diff --git a/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/non_git_tags_on_newline_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile.lock new file mode 100644 index 00000000000..77ac72f9f30 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.1 diff --git a/bundler/spec/fixtures/projects/bundler1/path_source/plugins/example/example.gemspec b/bundler/spec/fixtures/projects/bundler1/path_source/plugins/example/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source/plugins/example/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_eval/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source_eval/Gemfile new file mode 100644 index 00000000000..b492381b43d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_eval/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", path: File.join(File.dirname(__FILE__), 'plugins/example') +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_if/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source_if/Gemfile new file mode 100644 index 00000000000..9a218608c35 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_if/Gemfile @@ -0,0 +1,11 @@ +source "https://rubygems.org" + +if ENV['something'] + gem "example", path: "plugins/example" +else + gem "example" +end + +gem "statesman", "~> 1.2.0" +gem "business", "~> 1.4.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile.lock new file mode 100644 index 00000000000..77ac72f9f30 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.1 diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/plugins/example/example.gemspec b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/plugins/example/example.gemspec new file mode 100644 index 00000000000..330c138fd5c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap/plugins/example/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'json', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile.lock new file mode 100644 index 00000000000..77ac72f9f30 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.1 diff --git a/bundler/spec/fixtures/ruby/gemspecs/no_overlap_with_require b/bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/plugins/example/example.gemspec similarity index 100% rename from bundler/spec/fixtures/ruby/gemspecs/no_overlap_with_require rename to bundler/spec/fixtures/projects/bundler1/path_source_no_overlap_with_require/plugins/example/example.gemspec diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile b/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile.lock new file mode 100644 index 00000000000..77ac72f9f30 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/path_source_not_reachable/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.1 diff --git a/bundler/spec/fixtures/ruby/gemfiles/path_source_statesman b/bundler/spec/fixtures/projects/bundler1/path_source_statesman/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/path_source_statesman rename to bundler/spec/fixtures/projects/bundler1/path_source_statesman/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/path_source_statesman.lock b/bundler/spec/fixtures/projects/bundler1/path_source_statesman/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/path_source_statesman.lock rename to bundler/spec/fixtures/projects/bundler1/path_source_statesman/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/specifications/statesman b/bundler/spec/fixtures/projects/bundler1/path_source_statesman/vendor/gems/statesman-4.1.1/.specification similarity index 100% rename from bundler/spec/fixtures/ruby/specifications/statesman rename to bundler/spec/fixtures/projects/bundler1/path_source_statesman/vendor/gems/statesman-4.1.1/.specification diff --git a/bundler/spec/fixtures/ruby/gemfiles/platform_windows b/bundler/spec/fixtures/projects/bundler1/platform_windows/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/platform_windows rename to bundler/spec/fixtures/projects/bundler1/platform_windows/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/platform_windows.lock b/bundler/spec/fixtures/projects/bundler1/platform_windows/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/platform_windows.lock rename to bundler/spec/fixtures/projects/bundler1/platform_windows/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/platform_windows_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/platform_windows_no_lockfile/Gemfile new file mode 100644 index 00000000000..74ccddd4b96 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/platform_windows_no_lockfile/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0", platform: [:mswin] diff --git a/bundler/spec/fixtures/ruby/gemfiles/prerelease_specified b/bundler/spec/fixtures/projects/bundler1/prerelease_specified/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/prerelease_specified rename to bundler/spec/fixtures/projects/bundler1/prerelease_specified/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/prerelease_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/prerelease_specified/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/prerelease_specified/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/prerelease_with_dash b/bundler/spec/fixtures/projects/bundler1/prerelease_with_dash_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/prerelease_with_dash rename to bundler/spec/fixtures/projects/bundler1/prerelease_with_dash_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/prerelease_with_dash_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/prerelease_with_dash_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/prerelease_with_dash_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile b/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile new file mode 100644 index 00000000000..25fa890728d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "git@github.com:no-exist-sorry/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile.lock new file mode 100644 index 00000000000..59f2428c155 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/private_git_source/Gemfile.lock @@ -0,0 +1,22 @@ +GIT + remote: git@github.com:no-exist-sorry/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/private_git_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/private_git_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..4eea7618548 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/private_git_source_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "git@github.com:dependabot-fixtures/does-not-exist" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/private_github_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/private_github_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..69fce447abb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/private_github_source_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "prius", github: "dependabot-fixtures/does-not-exist" diff --git a/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile b/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile new file mode 100644 index 00000000000..686cbd2c37d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "guard-bundler", "~> 2.2.1" diff --git a/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile.lock new file mode 100644 index 00000000000..af7181d4aba --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/requires_bundler/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + ffi (1.14.2) + formatador (0.2.5) + guard (2.16.2) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.2.1) + bundler (>= 1.3.0, < 3) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + listen (3.4.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.8) + method_source (1.0.0) + nenv (0.3.0) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.0) + coderay (~> 1.1) + method_source (~> 1.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + shellany (0.0.1) + thor (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-bundler (~> 2.2.1) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/ruby_version_file/.ruby-version b/bundler/spec/fixtures/projects/bundler1/ruby_version_file/.ruby-version new file mode 100644 index 00000000000..ccbccc3dc62 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/ruby_version_file/.ruby-version @@ -0,0 +1 @@ +2.2.0 diff --git a/bundler/spec/fixtures/ruby/gemfiles/ruby_version_file b/bundler/spec/fixtures/projects/bundler1/ruby_version_file/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/ruby_version_file rename to bundler/spec/fixtures/projects/bundler1/ruby_version_file/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/ruby_version_file/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/ruby_version_file/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/ruby_version_file/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/sidekiq_pro/Gemfile b/bundler/spec/fixtures/projects/bundler1/sidekiq_pro/Gemfile new file mode 100644 index 00000000000..5e5d48e7a7a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/sidekiq_pro/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +source "https://username:password@gems.contribsys.com/" do + gem 'sidekiq-pro' +end diff --git a/bundler/spec/fixtures/ruby/lockfiles/sidekiq_pro.lock b/bundler/spec/fixtures/projects/bundler1/sidekiq_pro/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/sidekiq_pro.lock rename to bundler/spec/fixtures/projects/bundler1/sidekiq_pro/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile new file mode 100644 index 00000000000..0b7e64ec2fa --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile @@ -0,0 +1,3 @@ +source 'https://example.com' do + gem "business", "~> 1.0", require: true +end diff --git a/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/source_block_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/specified_default_source b/bundler/spec/fixtures/projects/bundler1/specified_default_source/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/specified_default_source rename to bundler/spec/fixtures/projects/bundler1/specified_default_source/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/specified_default_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/specified_default_source/Gemfile.lock new file mode 100644 index 00000000000..226fd95669c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/specified_default_source/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + remote: https://SECRET_CODES@repo.fury.io/greysteil/ + specs: + business (1.5.0) + statesman (2.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman + +BUNDLED WITH + 1.14.6 diff --git a/bundler/spec/fixtures/projects/bundler1/specified_default_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/specified_default_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..bf594703404 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/specified_default_source_no_lockfile/Gemfile @@ -0,0 +1,3 @@ +source 'https://SECRET_CODES@repo.fury.io/greysteil/' + +gem 'business' diff --git a/bundler/spec/fixtures/ruby/gemfiles/specified_plugin_source b/bundler/spec/fixtures/projects/bundler1/specified_plugin_source/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/specified_plugin_source rename to bundler/spec/fixtures/projects/bundler1/specified_plugin_source/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/specified_plugin_source.lock b/bundler/spec/fixtures/projects/bundler1/specified_plugin_source/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/specified_plugin_source.lock rename to bundler/spec/fixtures/projects/bundler1/specified_plugin_source/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/specified_source b/bundler/spec/fixtures/projects/bundler1/specified_source/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/specified_source rename to bundler/spec/fixtures/projects/bundler1/specified_source/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/specified_source.lock b/bundler/spec/fixtures/projects/bundler1/specified_source/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/specified_source.lock rename to bundler/spec/fixtures/projects/bundler1/specified_source/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/specified_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/specified_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..f933b8d77be --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/specified_source_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'statesman' + +source 'https://SECRET_CODES@repo.fury.io/greysteil/' do + gem 'business' +end diff --git a/bundler/spec/fixtures/ruby/gemfiles/subdep_blocked_by_subdep b/bundler/spec/fixtures/projects/bundler1/subdep_blocked_by_subdep/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/subdep_blocked_by_subdep rename to bundler/spec/fixtures/projects/bundler1/subdep_blocked_by_subdep/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/subdep_blocked_by_subdep.lock b/bundler/spec/fixtures/projects/bundler1/subdep_blocked_by_subdep/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/subdep_blocked_by_subdep.lock rename to bundler/spec/fixtures/projects/bundler1/subdep_blocked_by_subdep/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/subdependency b/bundler/spec/fixtures/projects/bundler1/subdependency/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/subdependency rename to bundler/spec/fixtures/projects/bundler1/subdependency/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/subdependency.lock b/bundler/spec/fixtures/projects/bundler1/subdependency/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/subdependency.lock rename to bundler/spec/fixtures/projects/bundler1/subdependency/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.locked new file mode 100644 index 00000000000..6a66ce5411a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.7.0.beta1) + ibandit (0.7.0) + i18n (~> 0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + ibandit (~> 0.7.0) + +BUNDLED WITH + 1.16.1 diff --git a/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.rb new file mode 100644 index 00000000000..cb30b03aaee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/subdependency_gems_rb/gems.rb @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.7.0" diff --git a/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile b/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile new file mode 100644 index 00000000000..eba56af1600 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'rails', '5.2.0' diff --git a/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile.lock new file mode 100644 index 00000000000..1459e11cefa --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/transitive_blocking/Gemfile.lock @@ -0,0 +1,119 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.2.0) + actionpack (= 5.2.0) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.0) + actionpack (= 5.2.0) + actionview (= 5.2.0) + activejob (= 5.2.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.2.0) + actionview (= 5.2.0) + activesupport (= 5.2.0) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.2.0) + activesupport (= 5.2.0) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.2.0) + activesupport (= 5.2.0) + globalid (>= 0.3.6) + activemodel (5.2.0) + activesupport (= 5.2.0) + activerecord (5.2.0) + activemodel (= 5.2.0) + activesupport (= 5.2.0) + arel (>= 9.0) + activestorage (5.2.0) + actionpack (= 5.2.0) + activerecord (= 5.2.0) + marcel (~> 0.3.1) + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + arel (9.0.0) + builder (3.2.4) + concurrent-ruby (1.1.7) + crass (1.0.6) + erubi (1.9.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (1.8.5) + concurrent-ruby (~> 1.0) + loofah (2.7.0) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) + method_source (1.0.0) + mimemagic (0.3.5) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.14.2) + nio4r (2.5.4) + nokogiri (1.10.10) + mini_portile2 (~> 2.4.0) + rack (2.2.3) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.0) + actioncable (= 5.2.0) + actionmailer (= 5.2.0) + actionpack (= 5.2.0) + actionview (= 5.2.0) + activejob (= 5.2.0) + activemodel (= 5.2.0) + activerecord (= 5.2.0) + activestorage (= 5.2.0) + activesupport (= 5.2.0) + bundler (>= 1.3.0) + railties (= 5.2.0) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + railties (5.2.0) + actionpack (= 5.2.0) + activesupport (= 5.2.0) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (13.0.1) + sprockets (4.0.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.2) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (1.0.1) + thread_safe (0.3.6) + tzinfo (1.2.8) + thread_safe (~> 0.1) + websocket-driver (0.7.3) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + +PLATFORMS + ruby + +DEPENDENCIES + rails (= 5.2.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/ruby/gemfiles/unavailable_gem b/bundler/spec/fixtures/projects/bundler1/unavailable_gem_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/unavailable_gem rename to bundler/spec/fixtures/projects/bundler1/unavailable_gem_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/unavailable_gem_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/unavailable_gem_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/unavailable_gem_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/unevaluatable_japanese b/bundler/spec/fixtures/projects/bundler1/unevaluatable_japanese_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/unevaluatable_japanese rename to bundler/spec/fixtures/projects/bundler1/unevaluatable_japanese_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/unevaluatable_japanese_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/unevaluatable_japanese_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/unevaluatable_japanese_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile new file mode 100644 index 00000000000..09c43d7ce76 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile.lock new file mode 100644 index 00000000000..cc7fe84e151 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/example.gemspec b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/example.gemspec new file mode 100644 index 00000000000..a95f2b2d1f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/unsatisfied_required_ruby_version/example.gemspec @@ -0,0 +1,18 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 99.0.0" +end diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile b/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_gems/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_gems/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_git/Gemfile b/bundler/spec/fixtures/projects/bundler1/vendored_git/Gemfile new file mode 100644 index 00000000000..7c42cfb2bd3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_git/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "dependabot-test-ruby-package", "~> 1.0.0", git: "https://github.com/dependabot-fixtures/dependabot-test-ruby-package" diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_version.lock b/bundler/spec/fixtures/projects/bundler1/vendored_git/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/git_source_with_version.lock rename to bundler/spec/fixtures/projects/bundler1/vendored_git/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/.bundlecache b/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/.bundlecache new file mode 100644 index 00000000000..e69de29bb2d diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md b/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md new file mode 100644 index 00000000000..f71de17053d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md @@ -0,0 +1,3 @@ +## dependabot-test-ruby-package v1.0.0 + +A dummy Ruby package for testing Dependabot. diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec b/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec new file mode 100644 index 00000000000..771f333f493 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec @@ -0,0 +1,19 @@ +# -*- encoding: utf-8 -*- +# stub: dependabot-test-ruby-package 1.0.0 ruby lib + +Gem::Specification.new do |s| + s.name = "dependabot-test-ruby-package".freeze + s.version = "1.0.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Dependabot".freeze] + s.date = "2020-08-25" + s.email = "noreply@github.com".freeze + s.homepage = "http://github.com/dependabot-fixtures/dependabot-test-ruby-package".freeze + s.licenses = ["MIT".freeze] + s.rubygems_version = "3.1.2".freeze + s.summary = "A dummy package for testing Dependabot".freeze + + s.installed_by_version = "3.1.2" if s.respond_to? :installed_by_version +end diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile new file mode 100644 index 00000000000..ca720aaf40e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "config/bundler_persistent_gems" +Bundler.settings.temporary(persistent_gems_after_clean: BUNDLER_PERSISTENT_GEMS_AFTER_CLEAN) + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/config/bundler_persistent_gems.rb b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/config/bundler_persistent_gems.rb new file mode 100644 index 00000000000..e2d94a4d1d3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/config/bundler_persistent_gems.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +BUNDLER_PERSISTENT_GEMS_AFTER_CLEAN = %w(business) diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler1/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_between_bounds b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_between_bounds rename to bundler/spec/fixtures/projects/bundler1/version_between_bounds_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.locked new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.rb new file mode 100644 index 00000000000..773a6199856 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_between_bounds_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "> 1.0.0", "< 1.5.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_conflict b/bundler/spec/fixtures/projects/bundler1/version_conflict/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_conflict rename to bundler/spec/fixtures/projects/bundler1/version_conflict/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/version_conflict/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/version_conflict/Gemfile.lock new file mode 100644 index 00000000000..de968b2b14e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_conflict/Gemfile.lock @@ -0,0 +1,19 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.2.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + +PLATFORMS + ruby + +DEPENDENCIES + diff-lcs (= 1.2.0) + rspec-mocks (= 3.5.0) + rspec-support (= 3.5.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.locked new file mode 100644 index 00000000000..de968b2b14e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.locked @@ -0,0 +1,19 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.2.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + +PLATFORMS + ruby + +DEPENDENCIES + diff-lcs (= 1.2.0) + rspec-mocks (= 3.5.0) + rspec-support (= 3.5.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.rb new file mode 100644 index 00000000000..99b4eeedc6d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_conflict_gems_rb/gems.rb @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "rspec-mocks", "3.5.0" +gem "rspec-support", "3.5.0" + +gem "diff-lcs", "1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_conflict_mutual_sub b/bundler/spec/fixtures/projects/bundler1/version_conflict_mutual_sub/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_conflict_mutual_sub rename to bundler/spec/fixtures/projects/bundler1/version_conflict_mutual_sub/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_conflict_mutual_sub.lock b/bundler/spec/fixtures/projects/bundler1/version_conflict_mutual_sub/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/version_conflict_mutual_sub.lock rename to bundler/spec/fixtures/projects/bundler1/version_conflict_mutual_sub/Gemfile.lock diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_conflict_no_req_change b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_conflict_no_req_change rename to bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_conflict_no_req_change.lock b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/version_conflict_no_req_change.lock rename to bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.locked new file mode 100644 index 00000000000..e7b685091b0 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.6.11) + ibandit (0.1.1) + +PLATFORMS + ruby + +DEPENDENCIES + i18n (~> 0.6) + ibandit (~> 0.1) + +BUNDLED WITH + 1.14.6 diff --git a/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.rb new file mode 100644 index 00000000000..49ba196f091 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_conflict_no_req_change_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.1" +gem "i18n", "~> 0.6" diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_conflict_with_listed_subdep b/bundler/spec/fixtures/projects/bundler1/version_conflict_with_listed_subdep/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_conflict_with_listed_subdep rename to bundler/spec/fixtures/projects/bundler1/version_conflict_with_listed_subdep/Gemfile diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_conflict_with_listed_subdep.lock b/bundler/spec/fixtures/projects/bundler1/version_conflict_with_listed_subdep/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/version_conflict_with_listed_subdep.lock rename to bundler/spec/fixtures/projects/bundler1/version_conflict_with_listed_subdep/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile b/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile new file mode 100644 index 00000000000..3a258a2ac67 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business" +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile.lock new file mode 100644 index 00000000000..69318fc3b62 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_not_specified/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business + statesman + +BUNDLED WITH + 1.14.6 diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_specified b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile/Gemfile similarity index 100% rename from bundler/spec/fixtures/ruby/gemfiles/version_specified rename to bundler/spec/fixtures/projects/bundler1/version_specified_gemfile/Gemfile diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile/Gemfile.lock new file mode 100644 index 00000000000..65d23b6c746 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.10.6 diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile new file mode 100644 index 00000000000..5809430d1b8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile.lock b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile.lock new file mode 100644 index 00000000000..77ac72f9f30 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 1.15.1 diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/plugins/example/.specification b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/plugins/example/.specification new file mode 100644 index 00000000000..46f47914a0b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gemfile_specification/plugins/example/.specification @@ -0,0 +1,245 @@ +--- !ruby/object:Gem::Specification +name: statesman +version: !ruby/object:Gem::Version + version: 4.1.1 +platform: ruby +authors: +- GoCardless +autorequire: +bindir: bin +cert_chain: [] +date: 2019-07-06 00:00:00.000000000 Z +dependencies: +- !ruby/object:Gem::Dependency + name: ammeter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: bundler + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' +- !ruby/object:Gem::Dependency + name: gc_ruboconfig + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 +- !ruby/object:Gem::Dependency + name: mysql2 + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' +- !ruby/object:Gem::Dependency + name: pg + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' +- !ruby/object:Gem::Dependency + name: pry + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +- !ruby/object:Gem::Dependency + name: rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' +- !ruby/object:Gem::Dependency + name: rake + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 +- !ruby/object:Gem::Dependency + name: rspec + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec-its + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: rspec-rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec_junit_formatter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 +- !ruby/object:Gem::Dependency + name: sqlite3 + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 +- !ruby/object:Gem::Dependency + name: timecop + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 +description: A statesman-like state machine library +email: +- developers@gocardless.com +executables: [] +extensions: [] +extra_rdoc_files: [] +files: [] +homepage: https://github.com/gocardless/statesman +licenses: +- MIT +metadata: {} +post_install_message: +rdoc_options: [] +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '2.2' +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +requirements: [] +rubygems_version: 3.0.3 +signing_key: +specification_version: 4 +summary: A statesman-like state machine library +test_files: [] diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.locked new file mode 100644 index 00000000000..ff0f2870012 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 1.17.3 diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.rb new file mode 100644 index 00000000000..381ba235a88 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler1/version_specified_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler1/version_specified_no_lockfile/Gemfile new file mode 100644 index 00000000000..381ba235a88 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler1/version_specified_no_lockfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile b/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile new file mode 100644 index 00000000000..3645ce79c20 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius", branch: "bad" diff --git a/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile.lock new file mode 100644 index 00000000000..60b1b5a2a9c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_branch/Gemfile.lock @@ -0,0 +1,23 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + branch: bad + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile b/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile new file mode 100644 index 00000000000..59ef4eb67a9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", git: "https://github.com/dependabot-fixtures/business", branch: "bad" +gem "statesman", "~> 1.2.0" +gem "prius", "~> 1.0.0" diff --git a/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile.lock new file mode 100644 index 00000000000..9b2da9eadda --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_branch_business/Gemfile.lock @@ -0,0 +1,23 @@ +GIT + remote: https://github.com/dependabot-fixtures/business + revision: d41e445215b5af70c1604715d97dd953e868380e + branch: bad_branch + specs: + business (1.10.0) + +GEM + remote: https://rubygems.org/ + specs: + prius (1.0.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business! + prius (~> 1.0.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile b/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile new file mode 100644 index 00000000000..d77611ce290 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile.lock new file mode 100644 index 00000000000..8de8a81d8a8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bad_ref/Gemfile.lock @@ -0,0 +1,22 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce1 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile b/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile new file mode 100644 index 00000000000..316161ee364 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' do + gem 'statesman' + gem 'business' +end diff --git a/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile.lock new file mode 100644 index 00000000000..9ccf348adf1 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/block_source_rubygems/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.10.0) + statesman (3.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile b/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile new file mode 100644 index 00000000000..31ab2eb1cff --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "dummy-pkg-a" +gem "dummy-pkg-b" diff --git a/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile.lock new file mode 100644 index 00000000000..75ec0976f52 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/blocked_by_subdep/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + specs: + dummy-pkg-a (1.0.1) + dummy-pkg-b (1.0.0) + dummy-pkg-a (< 2.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + dummy-pkg-a (= 1.0.1) + dummy-pkg-b (= 1.0.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile new file mode 100644 index 00000000000..66c7b50a633 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "bundler", "~> 2.3.0" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile.lock new file mode 100644 index 00000000000..229e13d1fca --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bundler_specified/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 2.2.0) + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile new file mode 100644 index 00000000000..d9fd43ddf89 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" do + gem "bundler", "~> 1.15.0" + + gem "business", "~> 1.4.0" + gem "statesman", "~> 1.2.0" +end diff --git a/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile.lock new file mode 100644 index 00000000000..1c69f792cf4 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/bundler_specified_in_source_bundler_specified/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 1.15.0) + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile b/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile new file mode 100644 index 00000000000..3fcd714d947 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.6.0" +gem "i18n", git: "https://github.com/dependabot-fixtures/i18n" diff --git a/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile.lock new file mode 100644 index 00000000000..3fba86ae1d5 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/cant_unlock_subdep/Gemfile.lock @@ -0,0 +1,21 @@ +GIT + remote: https://github.com/dependabot-fixtures/i18n + revision: d049c7115f59689efb123d61430c078c6feb7537 + specs: + i18n (0.7.0) + +GEM + remote: https://rubygems.org/ + specs: + ibandit (0.6.6) + i18n (~> 0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + i18n! + ibandit (~> 0.6.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile new file mode 100644 index 00000000000..fb635a712c1 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", git: "git_url" # My gem diff --git a/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/comment_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/comments_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/comments_no_lockfile/Gemfile new file mode 100644 index 00000000000..41c480ffbea --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/comments_no_lockfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" # Business time +gem "statesman", "~> 1.2.0" # State machine diff --git a/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile b/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile new file mode 100644 index 00000000000..b672cd73c87 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" + +if ENV["STATESMAN_NEXT"] == "1" + gem "statesman", "~> 7.2.0" +else + gem "statesman", "~> 1.2.0" # rubocop:disable Bundler/DuplicatedGem +end diff --git a/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/conditional/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-7.2.0.gem b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-7.2.0.gem new file mode 100644 index 00000000000..94abbab8bbb Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/conditional/vendor/cache/statesman-7.2.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile new file mode 100644 index 00000000000..44c20033953 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", github: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/custom_tag_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile new file mode 100644 index 00000000000..bdb3dbdcbc2 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "openssl", "~> 2.1.2" + +gem "business", "~> 1.4" +gem "statesman", "~> 1.2" diff --git a/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile.lock new file mode 100644 index 00000000000..82b31a5cbb0 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/default_gem_specified/Gemfile.lock @@ -0,0 +1,17 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.18.0) + openssl (2.1.2) + statesman (1.3.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4) + openssl (~> 2.1.2) + statesman (~> 1.2) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile b/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile new file mode 100644 index 00000000000..f04c68bc2bf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" + +group :development, :test do + gem "business", "~> 1.4.0" +end diff --git a/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile.lock new file mode 100644 index 00000000000..d274ee3b6fa --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/development_dependencies/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile new file mode 100644 index 00000000000..e08aed36a11 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +eval_gemfile File.expand_path('backend/Gemfile', File.dirname(__FILE__)) + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/backend/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_absolute/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile new file mode 100644 index 00000000000..5febdf9583f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +eval_gemfile('backend/Gemfile') + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/backend/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_gemfile/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile new file mode 100644 index 00000000000..5febdf9583f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +eval_gemfile('backend/Gemfile') + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/backend/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_nested/nested/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile new file mode 100644 index 00000000000..25064841bbd --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +local_gemfile = File.dirname(__FILE__), 'backend/Gemfile' +eval_gemfile File.join(local_gemfile) + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/backend/Gemfile b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/backend/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/eval_gemfile_variable/backend/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile new file mode 100644 index 00000000000..d438c188756 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile @@ -0,0 +1,6 @@ +exec "curl https://example.com" + +source "https://rubygems.org" + +gem "business", "~> 1.0.0" +gem "uk_phone_numbers", "~> 0.1.0" diff --git a/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/exec_error_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/exec_error_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/exec_error_no_lockfile/Gemfile new file mode 100644 index 00000000000..d438c188756 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/exec_error_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +exec "curl https://example.com" + +source "https://rubygems.org" + +gem "business", "~> 1.0.0" +gem "uk_phone_numbers", "~> 0.1.0" diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile new file mode 100644 index 00000000000..19cbfcc4b7f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile @@ -0,0 +1,5 @@ +ruby "2.2.0" +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile new file mode 100644 index 00000000000..19cbfcc4b7f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile @@ -0,0 +1,5 @@ +ruby "2.2.0" +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile.lock new file mode 100644 index 00000000000..a7d6f0d441c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_in_lockfile/Gemfile.lock @@ -0,0 +1,18 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +RUBY VERSION + ruby 2.2.0p0 + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile new file mode 100644 index 00000000000..2b0ebe4feb7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile @@ -0,0 +1,5 @@ +ruby "1.9.3" +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/explicit_ruby_old/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile new file mode 100644 index 00000000000..43ddcac6fcf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +version = ENV['BUSINESS_VERSION'] || '1.0.0' + +gem "business", version diff --git a/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/function_version_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile b/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile new file mode 100644 index 00000000000..80d3f33fcc6 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "i18n", "~> 0.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile.lock new file mode 100644 index 00000000000..f3120963c79 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gem_with_number/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.4.2) + +PLATFORMS + ruby + +DEPENDENCIES + i18n (~> 0.4.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_exact/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/example.gemspec new file mode 100644 index 00000000000..79ab4231bea --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_exact/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '1.0.0' + spec.add_dependency 'statesman', '= 1.0.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_example/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_example/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_example/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/example.gemspec new file mode 100644 index 00000000000..142de29de15 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_function_name/example.gemspec @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +function_name = "unlucky" + +Gem::Specification.new do |spec| + spec.name = function_name + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/example.gemspec new file mode 100644 index 00000000000..da77199c39d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_gemspec_with_require/example.gemspec @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/example.gemspec new file mode 100644 index 00000000000..00d9cbc8425 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_impossible_ruby/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 15.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile new file mode 100644 index 00000000000..de75a07e91e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile @@ -0,0 +1 @@ +gem "business", ">= 1", "< 3", require: true diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile new file mode 100644 index 00000000000..65e6a4ac20e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile @@ -0,0 +1 @@ +gem "business", [">= 1", "<3"], require: true diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_array/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/example.gemspec new file mode 100644 index 00000000000..6b7414313e3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_multiple_requirements_parenthesis/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency("business", ">= 1", "< 3") diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/example.gemspec new file mode 100644 index 00000000000..3288570e1cf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_no_required_ruby/example.gemspec @@ -0,0 +1,20 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/example.gemspec new file mode 100644 index 00000000000..a1543e7694d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_old_required_ruby/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 1.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/example.gemspec new file mode 100644 index 00000000000..07f1eb62379 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 3.0.1" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile.lock new file mode 100644 index 00000000000..3be6957c210 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.3.7 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/example.gemspec new file mode 100644 index 00000000000..76e2d25bc8d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_require_ruby_3_1/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 3.1.1" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_small_example/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/example.gemspec new file mode 100644 index 00000000000..56f7e3e9501 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_unevaluatable_ruby/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = Some::Constant + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/example.gemspec new file mode 100644 index 00000000000..186c9ecee3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_nested_block/example.gemspec @@ -0,0 +1,7 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.files = `git ls-files`.split($/) + dev_files = %w(.gitignore bin/setup.sh bin/test.sh) + dev_files.each {|f| s.files.delete f } +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/example.gemspec new file mode 100644 index 00000000000..da77199c39d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemfile_with_require/example.gemspec @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.locked new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.rb new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gems_rb/gems.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/another.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/another.gemspec new file mode 100644 index 00000000000..997bd60a94c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/another.gemspec @@ -0,0 +1,23 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' + spec.add_dependency 'statesman', '= 1.0.0' + spec.add_development_dependency 'rake' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/example.gemspec new file mode 100644 index 00000000000..bec8987c977 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/example.gemspec @@ -0,0 +1,30 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + another_gemspec = Bundler.load_gemspec_uncached("another.gemspec") + + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_development_dependency "webmock", "~> 2.3.1" + + another_gemspec.development_dependencies.each do |dep| + spec.add_development_dependency dep.name, *dep.requirement.as_list + end +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile new file mode 100644 index 00000000000..de75a07e91e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile @@ -0,0 +1 @@ +gem "business", ">= 1", "< 3", require: true diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/example.gemspec new file mode 100644 index 00000000000..48ad347d63a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency "business", ">= 1", "< 3" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/example.gemspec new file mode 100644 index 00000000000..360854054f2 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_multiple_requirements_array/example.gemspec @@ -0,0 +1 @@ +spec.add_dependency "business", [">= 1", "<3"] diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_no_gemfile/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_no_lockfile/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_no_lockfile/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/example.gemspec new file mode 100644 index 00000000000..da77199c39d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported/example.gemspec @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_not_imported_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/example.gemspec new file mode 100644 index 00000000000..90e236e18cb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.2, < 4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/example.gemspec new file mode 100644 index 00000000000..57312f3847e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_range_array/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = [">= 2.2", "< 4.0"] + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/Gemfile b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/Gemfile new file mode 100644 index 00000000000..be0f45dc3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/example.gemspec new file mode 100644 index 00000000000..a07f63f0345 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_required_ruby_version_requirement_class/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = Gem::Requirement.new(">= 2.1.8", "< 4.0.0") + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_small_example_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_small_example_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_small_example_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/gemspec_with_require_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/gemspec_with_require_no_lockfile/example.gemspec new file mode 100644 index 00000000000..705e935a3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gemspec_with_require_no_lockfile/example.gemspec @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "find" + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "example/version" + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile.lock new file mode 100644 index 00000000000..ddbf9340f9b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile new file mode 100644 index 00000000000..0aa8c132feb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "rubygems-circular-dependency", git: "https://github.com/dependabot-fixtures/rubygems-circular-dependency" +gem "business" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile.lock new file mode 100644 index 00000000000..761a46d7b8b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_circular/Gemfile.lock @@ -0,0 +1,20 @@ +GIT + remote: https://github.com/dependabot-fixtures/rubygems-circular-dependency + revision: 3c85f0bd8d6977b4dfda6a12acf93a282c4f5bf1 + specs: + rubygems-circular-dependency (0.0.1) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + business + rubygems-circular-dependency! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile new file mode 100644 index 00000000000..754a6acd9f8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "parallel", git: "git@github.com:dependabot-fixtures/parallel", ref: "v1.12.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile.lock new file mode 100644 index 00000000000..fc5db567cd8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_internal/Gemfile.lock @@ -0,0 +1,21 @@ +GIT + remote: git@github.com:dependabot-fixtures/parallel + revision: 5fa4406bcf0b3109f645550ca799fc7570501870 + ref: v1.12.0 + specs: + parallel (1.12.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + parallel! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_invalid_github/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_invalid_github/Gemfile new file mode 100644 index 00000000000..4d3cb290414 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_invalid_github/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +# this user meant: github: "dependabot-fixtures/business" +gem "business", git: "dependabot-fixtures/business" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile new file mode 100644 index 00000000000..f9aaffb1fbf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile.lock new file mode 100644 index 00000000000..f4743087cf9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_mismatched/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile new file mode 100644 index 00000000000..54834ed2d50 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", git: "git@github.com:dependabot-fixtures/business" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile.lock new file mode 100644 index 00000000000..d526e47e592 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_no_ref/Gemfile.lock @@ -0,0 +1,18 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + specs: + business (1.6.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile.lock new file mode 100644 index 00000000000..3c88ec6a514 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_outdated/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile new file mode 100644 index 00000000000..01d79ac8e46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.6.0", + git: "git@github.com:dependabot-fixtures/business", + ref: "a1b78a9" +gem "statesman", "~> 1.2.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "que", git: "git@github.com:dependabot-fixtures/que", tag: "v0.11.6" +gem "uk_phone_numbers", git: "http://github.com/dependabot-fixtures/uk_phone_numbers" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile.lock new file mode 100644 index 00000000000..3c88ec6a514 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_reordered/Gemfile.lock @@ -0,0 +1,43 @@ +GIT + remote: http://github.com/dependabot-fixtures/uk_phone_numbers + revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 + specs: + uk_phone_numbers (0.1.1) + +GIT + remote: git@github.com:dependabot-fixtures/business + revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd + ref: a1b78a9 + specs: + business (1.6.0) + +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GIT + remote: git@github.com:dependabot-fixtures/que + revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 + tag: v0.11.6 + specs: + que (0.11.6) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.6.0)! + prius! + que! + statesman (~> 1.2.0) + uk_phone_numbers! + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile new file mode 100644 index 00000000000..7bf79835354 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile @@ -0,0 +1,7 @@ +source "http://rubygems.org" + +git "https://github.com/dependabot-fixtures/kaminari" do + gem "kaminari-core" +end + +gem 'kaminari-actionview' diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile.lock new file mode 100644 index 00000000000..c9f7efbed13 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_undeclared/Gemfile.lock @@ -0,0 +1,54 @@ +GIT + remote: https://github.com/dependabot-fixtures/kaminari + revision: 62ec743dcee69e02186e5f1a309b08e59d83f647 + specs: + kaminari-actionview (1.1.1) + actionview + kaminari-core (= 1.1.1) + kaminari-core (1.1.1) + +GEM + remote: http://rubygems.org/ + specs: + actionview (5.1.6) + activesupport (= 5.1.6) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activesupport (5.1.6) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + builder (3.2.3) + concurrent-ruby (1.0.5) + crass (1.0.3) + erubi (1.7.1) + i18n (1.0.0) + concurrent-ruby (~> 1.0) + loofah (2.2.2) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mini_portile2 (2.3.0) + minitest (5.11.3) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + kaminari-actionview + kaminari-core! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile new file mode 100644 index 00000000000..fcae7c722cf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +def git_gem(name, **options) + gem name, git: "git@github.com:dependabot-fixtures/business" +end + +git_gem 'business' + +gemspec diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile.lock new file mode 100644 index 00000000000..94a2e5e93fc --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/Gemfile.lock @@ -0,0 +1,25 @@ +GIT + remote: git@github.com:dependabot-fixtures/business + revision: 1378a2b0b446d991b7567efbc7eeeed2720e4d8f + specs: + business (1.16.0) + +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + business! + example! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/example.gemspec b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_unparseable/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile new file mode 100644 index 00000000000..fbdc6ef59cf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "dummy-git-dependency", + git: "git@github.com:dependabot-fixtures/ruby-dummy-git-dependency", + ref: "v1.0.0" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile.lock new file mode 100644 index 00000000000..1adc4704daf --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_unreleased/Gemfile.lock @@ -0,0 +1,19 @@ +GIT + remote: git@github.com:dependabot-fixtures/ruby-dummy-git-dependency + revision: 20151f9b67c8a04461fa0ee28385b6187b86587b + ref: v1.0.0 + specs: + dummy-git-dependency (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + dummy-git-dependency! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile new file mode 100644 index 00000000000..899ac4d6a52 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "rest-client", "~> 1.8" +gem "onfido", git: "https://github.com/dependabot-fixtures/onfido" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile.lock new file mode 100644 index 00000000000..1468fcc3abb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_conflict/Gemfile.lock @@ -0,0 +1,34 @@ +GIT + remote: https://github.com/dependabot-fixtures/onfido + revision: 7b36eac82a7e42049052a58af0a7943fe0363714 + ref: v0.4.0 + specs: + onfido (0.4.0) + rest-client (~> 1.8.0) + +GEM + remote: https://rubygems.org/ + specs: + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + mime-types (2.99.3) + netrc (0.11.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) + +PLATFORMS + ruby + +DEPENDENCIES + onfido! + rest-client (~> 1.8) + +BUNDLED WITH + 2.2.0.pre.3 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile new file mode 100644 index 00000000000..c4e970e3a04 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "elasticsearch-dsl", + github: "dependabot-fixtures/elasticsearch-ruby", + branch: "5.x", + require: "dependabot-fixtures/dsl" +gem "elasticsearch-model", github: "dependabot-fixtures/elasticsearch-rails", branch: "5.x" +gem "elasticsearch-rails", github: "dependabot-fixtures/elasticsearch-rails", branch: "5.x" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile.lock new file mode 100644 index 00000000000..241ddb967ef --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_multiple_deps/Gemfile.lock @@ -0,0 +1,57 @@ +GIT + remote: https://github.com/dependabot-fixtures/elasticsearch-rails.git + revision: 212b37a1e927015f2a095e0f841c897d377ad1c7 + branch: 5.x + specs: + elasticsearch-model (5.1.0) + activesupport (> 3) + elasticsearch (~> 5) + hashie + elasticsearch-rails (5.1.0) + +GIT + remote: https://github.com/dependabot-fixtures/elasticsearch-ruby.git + revision: 43f48b229a975b77c5339644d512c88389fefafa + branch: 5.x + specs: + elasticsearch (5.0.4) + elasticsearch-api (= 5.0.4) + elasticsearch-transport (= 5.0.4) + elasticsearch-api (5.0.4) + multi_json + elasticsearch-dsl (0.1.4) + elasticsearch-transport (5.0.4) + faraday + multi_json + +GEM + remote: https://rubygems.org/ + specs: + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + concurrent-ruby (1.0.5) + faraday (0.15.2) + multipart-post (>= 1.2, < 3) + hashie (3.5.7) + i18n (1.0.1) + concurrent-ruby (~> 1.0) + minitest (5.11.3) + multi_json (1.13.1) + multipart-post (2.0.0) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + elasticsearch-dsl! + elasticsearch-model! + elasticsearch-rails! + +BUNDLED WITH + 2.2.11 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile new file mode 100644 index 00000000000..64283612f00 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "rest-client", "~> 1.8" +gem "onfido", git: "https://github.com/dependabot-fixtures/onfido", ref: "v0.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile.lock new file mode 100644 index 00000000000..1468fcc3abb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_tag_conflict/Gemfile.lock @@ -0,0 +1,34 @@ +GIT + remote: https://github.com/dependabot-fixtures/onfido + revision: 7b36eac82a7e42049052a58af0a7943fe0363714 + ref: v0.4.0 + specs: + onfido (0.4.0) + rest-client (~> 1.8.0) + +GEM + remote: https://rubygems.org/ + specs: + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + mime-types (2.99.3) + netrc (0.11.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) + +PLATFORMS + ruby + +DEPENDENCIES + onfido! + rest-client (~> 1.8) + +BUNDLED WITH + 2.2.0.pre.3 diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile new file mode 100644 index 00000000000..7c42cfb2bd3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "dependabot-test-ruby-package", "~> 1.0.0", git: "https://github.com/dependabot-fixtures/dependabot-test-ruby-package" diff --git a/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_source_with_version_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile new file mode 100644 index 00000000000..c876180cc40 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile @@ -0,0 +1,2 @@ +gem "prius", "1.0.0", require: false, +git: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/git_tags_on_newline_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile new file mode 100644 index 00000000000..d296c477b65 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", github: "dependabot-fixtures/business" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile.lock new file mode 100644 index 00000000000..6d74477794c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/github_source/Gemfile.lock @@ -0,0 +1,20 @@ +GIT + remote: https://github.com/dependabot-fixtures/business.git + revision: d31e445215b5af70c1604715d97dd953e868380e + specs: + business (1.10.0) + +GEM + remote: https://rubygems.org/ + specs: + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile b/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile new file mode 100644 index 00000000000..f44683ee945 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", ">= 1.4.0" +gem "statesman", ">= 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile.lock new file mode 100644 index 00000000000..1a5b0efd681 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/gte_matcher/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (>= 1.4.0) + statesman (>= 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile b/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile new file mode 100644 index 00000000000..686cbd2c37d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "guard-bundler", "~> 2.2.1" diff --git a/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile.lock new file mode 100644 index 00000000000..c0464de4383 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/guard_bundler/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + ffi (1.14.2) + formatador (0.2.5) + guard (2.16.2) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.2.1) + bundler (>= 1.3.0, < 3) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + listen (3.4.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.8) + method_source (1.0.0) + nenv (0.3.0) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.0) + coderay (~> 1.1) + method_source (~> 1.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + shellany (0.0.1) + thor (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-bundler (= 2.2.1) + +BUNDLED WITH + 2.1.4 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile.lock new file mode 100644 index 00000000000..6723e39f3cd --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile new file mode 100644 index 00000000000..c735e46b5d7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec path: 'subdir' + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile.lock new file mode 100644 index 00000000000..40d1e774d8a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: subdir + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/subdir/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/subdir/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_nested_path/nested/subdir/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile new file mode 100644 index 00000000000..c735e46b5d7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec path: 'subdir' + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile.lock new file mode 100644 index 00000000000..40d1e774d8a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: subdir + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/subdir/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/subdir/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_from_path/subdir/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/Gemfile new file mode 100644 index 00000000000..b433ef5f481 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0", git: "https://github.com/dependabot-fixtures/business" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_git_override_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile.lock new file mode 100644 index 00000000000..4a6140f69a3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/Gemfile.lock @@ -0,0 +1,96 @@ +PATH + remote: . + specs: + example (0.9.3) + bundler (>= 1.12.0) + excon (~> 0.55) + gemnasium-parser (~> 0.1) + gems (~> 1.0) + gitlab (~> 4.1) + octokit (~> 4.6) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + ast (2.3.0) + business (1.4.0) + crack (0.4.3) + safe_yaml (~> 1.0.0) + diff-lcs (1.3) + excon (0.58.0) + faraday (0.12.2) + multipart-post (>= 1.2, < 3) + gemnasium-parser (0.1.9) + gems (1.0.0) + json + gitlab (4.2.0) + httparty + terminal-table + hashdiff (0.3.5) + httparty (0.15.6) + multi_xml (>= 0.5.2) + json (2.1.0) + multi_xml (0.6.0) + multipart-post (2.0.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + parser (2.4.0.0) + ast (~> 2.2) + powerpack (0.1.1) + public_suffix (2.0.5) + rainbow (2.2.2) + rake + rake (12.0.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.4) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + statesman (1.2.5) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.3.0) + webmock (2.3.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + rake + rspec (~> 3.5.0) + rspec-its (~> 1.2.0) + rubocop (~> 0.48.0) + statesman (~> 1.2.0) + webmock (~> 2.3.1) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/example.gemspec new file mode 100644 index 00000000000..bcc3ef45101 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_imports_gemspec_large/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency 'gems', '~> 1.0' + spec.add_dependency "octokit", "~> 4.6" + spec.add_dependency "gitlab", "~> 4.1" + + spec.add_development_dependency "webmock", "~> 2.3.1" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "rake" +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..ea5e86dc468 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" do + gem "business", "~> 1.4.0" + gem "statesman", "~> 1.2.0" +end + +gemspec diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_default_source_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/Gemfile new file mode 100644 index 00000000000..49322c66178 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_lockfile/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile.lock new file mode 100644 index 00000000000..6723e39f3cd --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/example.gemspec new file mode 100644 index 00000000000..330c138fd5c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_no_overlap/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'json', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a1543e7694d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_old_required_ruby_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 1.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_small_example_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile.lock new file mode 100644 index 00000000000..6723e39f3cd --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/Gemfile.lock @@ -0,0 +1,22 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/example.gemspec new file mode 100644 index 00000000000..c605f05bca6 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_unevaluatable/example.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "1.0.0" + spec.summary = bad_code # <----- The bad code is here + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/version_as_float.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/version_as_float.gemspec new file mode 100644 index 00000000000..5a3c734e27a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_as_float/version_as_float.gemspec @@ -0,0 +1,16 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "version_as_float" + spec.version = 1.0 + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/Gemfile new file mode 100644 index 00000000000..dfe874a7f8d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 3.0.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec new file mode 100644 index 00000000000..a1543e7694d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_version_clash_old_required_ruby_no_lockfile/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 1.9.3" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile new file mode 100644 index 00000000000..e1d94d6b902 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile.lock new file mode 100644 index 00000000000..4a6140f69a3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/Gemfile.lock @@ -0,0 +1,96 @@ +PATH + remote: . + specs: + example (0.9.3) + bundler (>= 1.12.0) + excon (~> 0.55) + gemnasium-parser (~> 0.1) + gems (~> 1.0) + gitlab (~> 4.1) + octokit (~> 4.6) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + ast (2.3.0) + business (1.4.0) + crack (0.4.3) + safe_yaml (~> 1.0.0) + diff-lcs (1.3) + excon (0.58.0) + faraday (0.12.2) + multipart-post (>= 1.2, < 3) + gemnasium-parser (0.1.9) + gems (1.0.0) + json + gitlab (4.2.0) + httparty + terminal-table + hashdiff (0.3.5) + httparty (0.15.6) + multi_xml (>= 0.5.2) + json (2.1.0) + multi_xml (0.6.0) + multipart-post (2.0.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + parser (2.4.0.0) + ast (~> 2.2) + powerpack (0.1.1) + public_suffix (2.0.5) + rainbow (2.2.2) + rake + rake (12.0.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.4) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + statesman (1.2.5) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.3.0) + webmock (2.3.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example! + rake + rspec (~> 3.5.0) + rspec-its (~> 1.2.0) + rubocop (~> 0.48.0) + statesman (~> 1.2.0) + webmock (~> 2.3.1) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/example.gemspec new file mode 100644 index 00000000000..705e935a3ac --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_gemspec_with_require/example.gemspec @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "find" + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "example/version" + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + Find.find("lib", "helpers") do |path| + if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } + Find.prune + else + spec.files << path unless File.directory?(path) + end + end + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", "~> 0.55" + spec.add_dependency "gemnasium-parser", "~> 0.1" + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile new file mode 100644 index 00000000000..163bfebc906 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gemspec name: 'example' +gemspec name: 'example2' diff --git a/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile.lock new file mode 100644 index 00000000000..dfecdc3c421 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/Gemfile.lock @@ -0,0 +1,23 @@ +PATH + remote: . + specs: + example (0.9.3) + business (~> 1.0) + example2 (0.9.3) + statesman (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.13.0) + statesman (1.3.1) + +PLATFORMS + ruby + +DEPENDENCIES + example! + example2! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example.gemspec new file mode 100644 index 00000000000..f1d7674d9f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'business', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example2.gemspec b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example2.gemspec new file mode 100644 index 00000000000..a768fc19063 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/imports_two_gemspecs/example2.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example2" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'statesman', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile new file mode 100644 index 00000000000..ff8bd34cc60 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "../some_other_file" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/some_other_file.rb b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/some_other_file.rb new file mode 100644 index 00000000000..9e3706a079f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_gemfile/some_other_file.rb @@ -0,0 +1 @@ +SOME_CONSTANT = 5 \ No newline at end of file diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile new file mode 100644 index 00000000000..cb5e001ec6f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "./nested/some_other_file" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/nested/some_other_file.rb b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/nested/some_other_file.rb new file mode 100644 index 00000000000..9e3706a079f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_require_relative_nested/nested/some_other_file.rb @@ -0,0 +1 @@ +SOME_CONSTANT = 5 \ No newline at end of file diff --git a/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile new file mode 100644 index 00000000000..dd85c46017c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile @@ -0,0 +1,5 @@ +source 'http://rubygems.org' + +%w[cli dependency].each do |path| + require File.expand_path("../lib/backup/#{path}", __FILE__) +end diff --git a/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/includes_requires_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/interpolated_version_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/interpolated_version_no_lockfile/Gemfile new file mode 100644 index 00000000000..b95313d3203 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/interpolated_version_no_lockfile/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +version = ENV['BUSINESS_VERSION'] || '1.0.0' + +gem "business", "~> #{version}" diff --git a/bundler/spec/fixtures/projects/bundler2/invalid_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/invalid_ruby/Gemfile new file mode 100644 index 00000000000..759c9ed2e5f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/invalid_ruby/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' do + ruby -rubygems -e 'require "jekyll-import"; + end diff --git a/bundler/spec/fixtures/projects/bundler2/jfrog_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/jfrog_source/Gemfile new file mode 100644 index 00000000000..ad50e194e10 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/jfrog_source/Gemfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" + +source "https://test.jfrog.io/test/api/gems" do + gem "statesman", "~> 1.2.0" +end diff --git a/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile new file mode 100644 index 00000000000..a832448206a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source 'https://rubygems.org' + +gem "json" diff --git a/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile.lock new file mode 100644 index 00000000000..d8977027710 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/jruby/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + json (1.4.3-java) + +PLATFORMS + java + +DEPENDENCIES + json + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile b/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile new file mode 100644 index 00000000000..4a72378eab4 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile @@ -0,0 +1,4 @@ +ruby "1.9.3" +source "https://rubygems.org" + +gem "public_suffix" diff --git a/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile.lock new file mode 100644 index 00000000000..dce186224da --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/legacy_ruby/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + specs: + public_suffix (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + public_suffix + +RUBY VERSION + ruby 1.9.3p551 + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/lockfile_only/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/lockfile_only/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/lockfile_only/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile new file mode 100644 index 00000000000..52e3efa5920 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4" +gem "statesman", "~> 1.2" diff --git a/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile new file mode 100644 index 00000000000..937f204c571 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +# The Gemfile.lock for this project has `business` at 1.4.1, which has been +# yanked +gem "business", "~> 1.4" +gem "statesman", "~> 1.2" diff --git a/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile.lock new file mode 100644 index 00000000000..963ece61633 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/minor_version_specified_yanked_gem/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.1) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile b/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile new file mode 100644 index 00000000000..eb7111e1ad4 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gem "activesupport", "5.0.0" +gem "actionview", "5.0.0" +gem "actionmailer", "5.0.0" diff --git a/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile.lock new file mode 100644 index 00000000000..34376487dc0 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/multiple_blocking/Gemfile.lock @@ -0,0 +1,70 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (5.0.0) + actionpack (= 5.0.0) + actionview (= 5.0.0) + activejob (= 5.0.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.0.0) + actionview (= 5.0.0) + activesupport (= 5.0.0) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.0.0) + activesupport (= 5.0.0) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + activejob (5.0.0) + activesupport (= 5.0.0) + globalid (>= 0.3.6) + activesupport (5.0.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + builder (3.2.4) + concurrent-ruby (1.1.7) + crass (1.0.6) + erubis (2.7.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + loofah (2.7.0) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.14.2) + nokogiri (1.10.10) + mini_portile2 (~> 2.4.0) + rack (2.2.3) + rack-test (0.6.3) + rack (>= 1.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + thread_safe (0.3.6) + tzinfo (1.2.7) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + actionmailer (= 5.0.0) + actionview (= 5.0.0) + activesupport (= 5.0.0) + +BUNDLED WITH + 2.2.20 diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile new file mode 100644 index 00000000000..7029d36a5b7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +eval_gemfile("backend/Gemfile") + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile/backend/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/backend/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile/backend/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile new file mode 100644 index 00000000000..3a258a2ac67 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business" +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile.lock new file mode 100644 index 00000000000..d911b61093a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business + statesman + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/nested/Gemfile new file mode 100644 index 00000000000..3a258a2ac67 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemfile_version_not_specified/nested/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business" +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/nested_gemspec/some/example.gemspec b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/some/example.gemspec new file mode 100644 index 00000000000..2a65bafba92 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_gemspec/some/example.gemspec @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency "business", "~> 1.0" +end diff --git a/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile new file mode 100644 index 00000000000..b2d90817699 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/gocardless/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile.lock new file mode 100644 index 00000000000..8337756462e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/gocardless/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/example/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/nested_path_source/nested/example/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile b/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile.lock new file mode 100644 index 00000000000..74780ed56cc --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/no_bundled_with/Gemfile.lock @@ -0,0 +1,12 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) diff --git a/bundler/spec/fixtures/projects/bundler2/no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/no_lockfile/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile new file mode 100644 index 00000000000..f481e70aa4f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", git: "git_url", require: false diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_end_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile new file mode 100644 index 00000000000..40050f9da15 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile @@ -0,0 +1 @@ +gem "prius", "1.0.0", require: false, git: "git_url" diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_at_start_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile new file mode 100644 index 00000000000..0e182d6e47e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile @@ -0,0 +1,2 @@ +gem "prius", "1.0.0", git: "git_url", +require: false diff --git a/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/non_git_tags_on_newline_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile.lock new file mode 100644 index 00000000000..8aedabb2b3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source/plugins/example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/path_source/plugins/example/example.gemspec new file mode 100644 index 00000000000..a39e98a0f46 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source/plugins/example/example.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = "2019-08-01" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = Dir["lib"] + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_runtime_dependency "bundler", ">= 1.12.0" + spec.add_dependency "excon", ["~> 0.55"] + spec.add_dependency("gemnasium-parser", "~> 0.1") + spec.add_dependency "gems", "~> 1.0" + spec.add_dependency "gitlab", "~> 4.1" + spec.add_dependency "octokit", "~> 4.6" + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec", "~> 3.5.0" + spec.add_development_dependency "rspec-its", "~> 1.2.0" + spec.add_development_dependency "rubocop", "~> 0.48.0" + spec.add_development_dependency "webmock", "~> 2.3.1" +end diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_eval/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_eval/Gemfile new file mode 100644 index 00000000000..b492381b43d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_eval/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", path: File.join(File.dirname(__FILE__), 'plugins/example') +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_if/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_if/Gemfile new file mode 100644 index 00000000000..9a218608c35 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_if/Gemfile @@ -0,0 +1,11 @@ +source "https://rubygems.org" + +if ENV['something'] + gem "example", path: "plugins/example" +else + gem "example" +end + +gem "statesman", "~> 1.2.0" +gem "business", "~> 1.4.0" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile.lock new file mode 100644 index 00000000000..8aedabb2b3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/plugins/example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/plugins/example/example.gemspec new file mode 100644 index 00000000000..330c138fd5c --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap/plugins/example/example.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'json', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile.lock new file mode 100644 index 00000000000..8aedabb2b3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/plugins/example/example.gemspec b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/plugins/example/example.gemspec new file mode 100644 index 00000000000..927d8d40051 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_no_overlap_with_require/plugins/example/example.gemspec @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'example/version' + +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = Example::VERSION + spec.summary = "Automated dependency management #{Example::VERSION}" + spec.description = "Core logic for updating a GitHub repos dependencies" + spec.date = Example::DATE + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 2.4.0" + spec.required_rubygems_version = ">= 2.6.11" + + spec.add_dependency 'json', '~> 1.0' +end diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile new file mode 100644 index 00000000000..1bc6443a9ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile.lock new file mode 100644 index 00000000000..8aedabb2b3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_not_reachable/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile new file mode 100644 index 00000000000..11315070177 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "4.1.1", path: "vendor/gems/statesman-4.1.1" diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile.lock new file mode 100644 index 00000000000..76ab12b69c9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/Gemfile.lock @@ -0,0 +1,19 @@ +PATH + remote: vendor/gems/statesman-4.1.1 + specs: + statesman (4.1.1) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (= 4.1.1)! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/path_source_statesman/vendor/gems/statesman-4.1.1/.specification b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/vendor/gems/statesman-4.1.1/.specification new file mode 100644 index 00000000000..9749eedb490 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/path_source_statesman/vendor/gems/statesman-4.1.1/.specification @@ -0,0 +1,246 @@ +--- !ruby/object:Gem::Specification +name: statesman +version: !ruby/object:Gem::Version + version: 4.1.1 +platform: ruby +authors: +- GoCardless +autorequire: +bindir: bin +cert_chain: [] +date: 2019-07-06 00:00:00.000000000 Z +dependencies: +- !ruby/object:Gem::Dependency + name: ammeter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: bundler + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' +- !ruby/object:Gem::Dependency + name: gc_ruboconfig + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 +- !ruby/object:Gem::Dependency + name: mysql2 + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' +- !ruby/object:Gem::Dependency + name: pg + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' +- !ruby/object:Gem::Dependency + name: pry + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +- !ruby/object:Gem::Dependency + name: rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' +- !ruby/object:Gem::Dependency + name: rake + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 +- !ruby/object:Gem::Dependency + name: rspec + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec-its + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: rspec-rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec_junit_formatter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 +- !ruby/object:Gem::Dependency + name: sqlite3 + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 +- !ruby/object:Gem::Dependency + name: timecop + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 +description: A statesman-like state machine library +email: +- developers@gocardless.com +executables: [] +extensions: [] +extra_rdoc_files: [] +files: [] +homepage: https://github.com/gocardless/statesman +licenses: +- MIT +metadata: {} +post_install_message: +rdoc_options: [] +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '2.2' +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +requirements: [] +rubygems_version: 3.0.3 +signing_key: +specification_version: 4 +summary: A statesman-like state machine library +test_files: [] + diff --git a/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile b/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile new file mode 100644 index 00000000000..74ccddd4b96 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0", platform: [:mswin] diff --git a/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile.lock new file mode 100644 index 00000000000..ad144fa723f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/platform_windows/Gemfile.lock @@ -0,0 +1,14 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/platform_windows_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/platform_windows_no_lockfile/Gemfile new file mode 100644 index 00000000000..74ccddd4b96 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/platform_windows_no_lockfile/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0", platform: [:mswin] diff --git a/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile new file mode 100644 index 00000000000..11347d18efc --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0.rc1" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/prerelease_specified/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile new file mode 100644 index 00000000000..6904ab782d4 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0-rc1" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/prerelease_with_dash_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile new file mode 100644 index 00000000000..25fa890728d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "git@github.com:no-exist-sorry/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile.lock new file mode 100644 index 00000000000..3fe67a28680 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/private_git_source/Gemfile.lock @@ -0,0 +1,22 @@ +GIT + remote: git@github.com:no-exist-sorry/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/private_git_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/private_git_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..4eea7618548 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/private_git_source_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "prius", git: "git@github.com:dependabot-fixtures/does-not-exist" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/private_github_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/private_github_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..69fce447abb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/private_github_source_no_lockfile/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" +gem "prius", github: "dependabot-fixtures/does-not-exist" diff --git a/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile b/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile new file mode 100644 index 00000000000..686cbd2c37d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "guard-bundler", "~> 2.2.1" diff --git a/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile.lock new file mode 100644 index 00000000000..10347278c5b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/requires_bundler/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + ffi (1.14.2) + formatador (0.2.5) + guard (2.16.2) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-bundler (2.2.1) + bundler (>= 1.3.0, < 3) + guard (~> 2.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + listen (3.4.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.8) + method_source (1.0.0) + nenv (0.3.0) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.0) + coderay (~> 1.1) + method_source (~> 1.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + shellany (0.0.1) + thor (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-bundler (~> 2.2.1) + +BUNDLED WITH + 2.2.14 diff --git a/bundler/spec/fixtures/projects/bundler2/ruby_version_file/.ruby-version b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/.ruby-version new file mode 100644 index 00000000000..ccbccc3dc62 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/.ruby-version @@ -0,0 +1 @@ +2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile new file mode 100644 index 00000000000..d44cabeca5f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +ruby File.open('.ruby-version', 'rb') { |f| f.read.chomp } + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/ruby_version_file/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile b/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile new file mode 100644 index 00000000000..5e5d48e7a7a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +source "https://username:password@gems.contribsys.com/" do + gem 'sidekiq-pro' +end diff --git a/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile.lock new file mode 100644 index 00000000000..0908ad45fd7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/sidekiq_pro/Gemfile.lock @@ -0,0 +1,26 @@ +GEM + remote: https://rubygems.org/ + remote: https://username:password@gems.contribsys.com/ + specs: + concurrent-ruby (1.0.5) + connection_pool (2.2.1) + rack (1.4.7) + rack-protection (1.5.3) + rack + redis (3.3.3) + sidekiq (4.2.9) + concurrent-ruby (~> 1.0) + connection_pool (~> 2.2, >= 2.2.0) + rack-protection (>= 1.5.0) + redis (~> 3.2, >= 3.2.1) + sidekiq-pro (3.4.4) + sidekiq (>= 4.1.5) + +PLATFORMS + ruby + +DEPENDENCIES + sidekiq-pro! + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile new file mode 100644 index 00000000000..0b7e64ec2fa --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile @@ -0,0 +1,3 @@ +source 'https://example.com' do + gem "business", "~> 1.0", require: true +end diff --git a/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/source_block_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile new file mode 100644 index 00000000000..bf594703404 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile @@ -0,0 +1,3 @@ +source 'https://SECRET_CODES@repo.fury.io/greysteil/' + +gem 'business' diff --git a/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile.lock new file mode 100644 index 00000000000..2dbc06dae75 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_default_source/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + remote: https://SECRET_CODES@repo.fury.io/greysteil/ + specs: + business (1.5.0) + statesman (2.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/specified_default_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/specified_default_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..bf594703404 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_default_source_no_lockfile/Gemfile @@ -0,0 +1,3 @@ +source 'https://SECRET_CODES@repo.fury.io/greysteil/' + +gem 'business' diff --git a/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile new file mode 100644 index 00000000000..6002285734f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'statesman' + +source 's3://my-gems', type: 'aws-s3' do + gem 'business' +end diff --git a/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile.lock new file mode 100644 index 00000000000..0c8fff32d02 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_plugin_source/Gemfile.lock @@ -0,0 +1,16 @@ +PLUGIN SOURCE + remote: s3://my-gems + type: aws-s3 + specs: + business (1.5.0) + statesman (2.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile b/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile new file mode 100644 index 00000000000..f933b8d77be --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'statesman' + +source 'https://SECRET_CODES@repo.fury.io/greysteil/' do + gem 'business' +end diff --git a/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile.lock new file mode 100644 index 00000000000..7edef465331 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_source/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: https://rubygems.org/ + remote: https://wxuokzLuQTRgMGtEYMPJ@repo.fury.io/greysteil/ + specs: + business (1.5.0) + statesman (2.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + business! + statesman + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/specified_source_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/specified_source_no_lockfile/Gemfile new file mode 100644 index 00000000000..f933b8d77be --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/specified_source_no_lockfile/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'statesman' + +source 'https://SECRET_CODES@repo.fury.io/greysteil/' do + gem 'business' +end diff --git a/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile b/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile new file mode 100644 index 00000000000..38e1bdd40ee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "dummy-pkg-b", "1.0.0" diff --git a/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile.lock new file mode 100644 index 00000000000..ddf7533aca2 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdep_blocked_by_subdep/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + dummy-pkg-a (1.0.1) + dummy-pkg-b (1.0.0) + dummy-pkg-a (< 2.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + dummy-pkg-b (= 1.0.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile b/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile new file mode 100644 index 00000000000..cb30b03aaee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.7.0" diff --git a/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile.lock new file mode 100644 index 00000000000..45e0ab053eb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdependency/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.7.0.beta1) + ibandit (0.7.0) + i18n (~> 0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + ibandit (~> 0.7.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.locked new file mode 100644 index 00000000000..45e0ab053eb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.7.0.beta1) + ibandit (0.7.0) + i18n (~> 0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + ibandit (~> 0.7.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.rb new file mode 100644 index 00000000000..cb30b03aaee --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/subdependency_gems_rb/gems.rb @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.7.0" diff --git a/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile b/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile new file mode 100644 index 00000000000..eba56af1600 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'rails', '5.2.0' diff --git a/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile.lock new file mode 100644 index 00000000000..2ad8677707e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/transitive_blocking/Gemfile.lock @@ -0,0 +1,119 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.2.0) + actionpack (= 5.2.0) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.0) + actionpack (= 5.2.0) + actionview (= 5.2.0) + activejob (= 5.2.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.2.0) + actionview (= 5.2.0) + activesupport (= 5.2.0) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.2.0) + activesupport (= 5.2.0) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.2.0) + activesupport (= 5.2.0) + globalid (>= 0.3.6) + activemodel (5.2.0) + activesupport (= 5.2.0) + activerecord (5.2.0) + activemodel (= 5.2.0) + activesupport (= 5.2.0) + arel (>= 9.0) + activestorage (5.2.0) + actionpack (= 5.2.0) + activerecord (= 5.2.0) + marcel (~> 0.3.1) + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + arel (9.0.0) + builder (3.2.4) + concurrent-ruby (1.1.7) + crass (1.0.6) + erubi (1.9.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (1.8.5) + concurrent-ruby (~> 1.0) + loofah (2.7.0) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) + method_source (1.0.0) + mimemagic (0.3.5) + mini_mime (1.0.2) + mini_portile2 (2.4.0) + minitest (5.14.2) + nio4r (2.5.4) + nokogiri (1.10.10) + mini_portile2 (~> 2.4.0) + rack (2.2.3) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.0) + actioncable (= 5.2.0) + actionmailer (= 5.2.0) + actionpack (= 5.2.0) + actionview (= 5.2.0) + activejob (= 5.2.0) + activemodel (= 5.2.0) + activerecord (= 5.2.0) + activestorage (= 5.2.0) + activesupport (= 5.2.0) + bundler (>= 1.3.0) + railties (= 5.2.0) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + railties (5.2.0) + actionpack (= 5.2.0) + activesupport (= 5.2.0) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (13.0.1) + sprockets (4.0.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.2) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (1.0.1) + thread_safe (0.3.6) + tzinfo (1.2.8) + thread_safe (~> 0.1) + websocket-driver (0.7.3) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + +PLATFORMS + ruby + +DEPENDENCIES + rails (= 5.2.0) + +BUNDLED WITH + 2.2.20 diff --git a/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile new file mode 100644 index 00000000000..762a55865e9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4" +gem "statesman", "~> 1.2" +gem "unresolvable_gem_name" diff --git a/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unavailable_gem_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile new file mode 100644 index 00000000000..bf38558ca62 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +# というč­Ļ告がでるため。 +bad_codes_man + +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unevaluatable_japanese_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile new file mode 100644 index 00000000000..09c43d7ce76 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gemspec + +gem "business", "~> 1.4.0" diff --git a/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile.lock new file mode 100644 index 00000000000..ef69a787fd1 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + +BUNDLED WITH + 2.2.10 diff --git a/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/example.gemspec b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/example.gemspec new file mode 100644 index 00000000000..a95f2b2d1f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/unsatisfied_required_ruby_version/example.gemspec @@ -0,0 +1,18 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "example" + spec.version = "0.9.3" + spec.summary = "Automated dependency management" + spec.description = "Core logic for updating a GitHub repos dependencies" + + spec.author = "Dependabot" + spec.email = "support@dependabot.com" + spec.homepage = "https://github.com/hmarr/example" + spec.license = "MIT" + + spec.require_path = "lib" + spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", + "lib/**/*", "helpers/**/*"] + + spec.required_ruby_version = ">= 99.0.0" +end diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile b/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_gems/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_gems/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile new file mode 100644 index 00000000000..bb897e7e7bb --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_gems_with_subdir/acceptance/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile b/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile new file mode 100644 index 00000000000..7c42cfb2bd3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile @@ -0,0 +1,4 @@ +# frozen_string_literal: true +source "https://rubygems.org" + +gem "dependabot-test-ruby-package", "~> 1.0.0", git: "https://github.com/dependabot-fixtures/dependabot-test-ruby-package" diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile.lock new file mode 100644 index 00000000000..c1ac1685df7 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_git/Gemfile.lock @@ -0,0 +1,18 @@ +GIT + remote: https://github.com/dependabot-fixtures/dependabot-test-ruby-package + revision: 81073f9462f228c6894e3e384d0718def310d99f + specs: + business (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + dependabot-test-ruby-package (~> 1.0.0)! + +BUNDLED WITH + 2.2.0.pre.2 diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/.bundlecache b/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/.bundlecache new file mode 100644 index 00000000000..e69de29bb2d diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md b/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md new file mode 100644 index 00000000000..f71de17053d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/README.md @@ -0,0 +1,3 @@ +## dependabot-test-ruby-package v1.0.0 + +A dummy Ruby package for testing Dependabot. diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec b/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec new file mode 100644 index 00000000000..771f333f493 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_git/vendor/cache/dependabot-test-ruby-package-81073f9462f2/test-ruby-package.gemspec @@ -0,0 +1,19 @@ +# -*- encoding: utf-8 -*- +# stub: dependabot-test-ruby-package 1.0.0 ruby lib + +Gem::Specification.new do |s| + s.name = "dependabot-test-ruby-package".freeze + s.version = "1.0.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Dependabot".freeze] + s.date = "2020-08-25" + s.email = "noreply@github.com".freeze + s.homepage = "http://github.com/dependabot-fixtures/dependabot-test-ruby-package".freeze + s.licenses = ["MIT".freeze] + s.rubygems_version = "3.1.2".freeze + s.summary = "A dummy package for testing Dependabot".freeze + + s.installed_by_version = "3.1.2" if s.respond_to? :installed_by_version +end diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile new file mode 100644 index 00000000000..ca720aaf40e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +require_relative "config/bundler_persistent_gems" +Bundler.settings.temporary(persistent_gems_after_clean: BUNDLER_PERSISTENT_GEMS_AFTER_CLEAN) + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/config/bundler_persistent_gems.rb b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/config/bundler_persistent_gems.rb new file mode 100644 index 00000000000..e2d94a4d1d3 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/config/bundler_persistent_gems.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +BUNDLER_PERSISTENT_GEMS_AFTER_CLEAN = %w(business) diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/business-1.4.0.gem b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/business-1.4.0.gem new file mode 100644 index 00000000000..2878bcd0ae6 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/business-1.4.0.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/projects/bundler2/vendored_persistent_gems/vendor/cache/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile new file mode 100644 index 00000000000..773a6199856 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "> 1.0.0", "< 1.5.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.locked new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.rb new file mode 100644 index 00000000000..773a6199856 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_between_bounds_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "> 1.0.0", "< 1.5.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_conflict/Gemfile new file mode 100644 index 00000000000..99b4eeedc6d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "rspec-mocks", "3.5.0" +gem "rspec-support", "3.5.0" + +gem "diff-lcs", "1.2.0" diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_conflict.lock b/bundler/spec/fixtures/projects/bundler2/version_conflict/Gemfile.lock similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/version_conflict.lock rename to bundler/spec/fixtures/projects/bundler2/version_conflict/Gemfile.lock diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.locked new file mode 100644 index 00000000000..f08280b7559 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.locked @@ -0,0 +1,19 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.2.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + +PLATFORMS + ruby + +DEPENDENCIES + diff-lcs (= 1.2.0) + rspec-mocks (= 3.5.0) + rspec-support (= 3.5.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.rb new file mode 100644 index 00000000000..99b4eeedc6d --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_gems_rb/gems.rb @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "rspec-mocks", "3.5.0" +gem "rspec-support", "3.5.0" + +gem "diff-lcs", "1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile new file mode 100644 index 00000000000..7d275fdc37f --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'rspec-expectations', '~> 3.5.0' +gem 'rspec-mocks', '~> 3.5.0' diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile.lock new file mode 100644 index 00000000000..0af10be6318 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_mutual_sub/Gemfile.lock @@ -0,0 +1,21 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.3) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) + +PLATFORMS + ruby + +DEPENDENCIES + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile new file mode 100644 index 00000000000..49ba196f091 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.1" +gem "i18n", "~> 0.6" diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile.lock new file mode 100644 index 00000000000..87f044389f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.6.11) + ibandit (0.1.1) + +PLATFORMS + ruby + +DEPENDENCIES + i18n (~> 0.6) + ibandit (~> 0.1) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.locked b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.locked new file mode 100644 index 00000000000..87f044389f9 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.locked @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + i18n (0.6.11) + ibandit (0.1.1) + +PLATFORMS + ruby + +DEPENDENCIES + i18n (~> 0.6) + ibandit (~> 0.1) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.rb new file mode 100644 index 00000000000..49ba196f091 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_no_req_change_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "ibandit", "~> 0.1" +gem "i18n", "~> 0.6" diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile new file mode 100644 index 00000000000..2cf229a0fa0 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "rspec-mocks" +gem "rspec-support" diff --git a/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile.lock new file mode 100644 index 00000000000..e0713511c82 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_conflict_with_listed_subdep/Gemfile.lock @@ -0,0 +1,18 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.3) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + +PLATFORMS + ruby + +DEPENDENCIES + rspec-mocks + rspec-support + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile new file mode 100644 index 00000000000..3a258a2ac67 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business" +gem "statesman" diff --git a/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile.lock new file mode 100644 index 00000000000..d911b61093a --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_not_specified/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business + statesman + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile new file mode 100644 index 00000000000..381ba235a88 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile.lock new file mode 100644 index 00000000000..3fa0fb21893 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile/Gemfile.lock @@ -0,0 +1,15 @@ +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + statesman (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile new file mode 100644 index 00000000000..5809430d1b8 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "example", ">= 0.9.0", path: "plugins/example" +gem "prius", git: "https://github.com/dependabot-fixtures/prius" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile.lock b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile.lock new file mode 100644 index 00000000000..8aedabb2b3e --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/Gemfile.lock @@ -0,0 +1,30 @@ +GIT + remote: https://github.com/dependabot-fixtures/prius + revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + specs: + prius (1.0.0) + +PATH + remote: plugins/example + specs: + example (0.9.3) + i18n (>= 0.3.3) + +GEM + remote: https://rubygems.org/ + specs: + business (1.4.0) + i18n (0.8.4) + statesman (1.2.5) + +PLATFORMS + ruby + +DEPENDENCIES + business (~> 1.4.0) + example (>= 0.9.0)! + prius! + statesman (~> 1.2.0) + +BUNDLED WITH + 2.2.0 diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/plugins/example/.specification b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/plugins/example/.specification new file mode 100644 index 00000000000..46f47914a0b --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gemfile_specification/plugins/example/.specification @@ -0,0 +1,245 @@ +--- !ruby/object:Gem::Specification +name: statesman +version: !ruby/object:Gem::Version + version: 4.1.1 +platform: ruby +authors: +- GoCardless +autorequire: +bindir: bin +cert_chain: [] +date: 2019-07-06 00:00:00.000000000 Z +dependencies: +- !ruby/object:Gem::Dependency + name: ammeter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: bundler + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.3' +- !ruby/object:Gem::Dependency + name: gc_ruboconfig + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 2.3.9 +- !ruby/object:Gem::Dependency + name: mysql2 + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0.4' + - - "<" + - !ruby/object:Gem::Version + version: '0.6' +- !ruby/object:Gem::Dependency + name: pg + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '0.18' +- !ruby/object:Gem::Dependency + name: pry + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +- !ruby/object:Gem::Dependency + name: rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '3.2' +- !ruby/object:Gem::Dependency + name: rake + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 12.3.0 +- !ruby/object:Gem::Dependency + name: rspec + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec-its + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '1.1' +- !ruby/object:Gem::Dependency + name: rspec-rails + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.1' +- !ruby/object:Gem::Dependency + name: rspec_junit_formatter + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.4.0 +- !ruby/object:Gem::Dependency + name: sqlite3 + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 1.3.6 +- !ruby/object:Gem::Dependency + name: timecop + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: 0.9.1 +description: A statesman-like state machine library +email: +- developers@gocardless.com +executables: [] +extensions: [] +extra_rdoc_files: [] +files: [] +homepage: https://github.com/gocardless/statesman +licenses: +- MIT +metadata: {} +post_install_message: +rdoc_options: [] +require_paths: +- lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '2.2' +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + version: '0' +requirements: [] +rubygems_version: 3.0.3 +signing_key: +specification_version: 4 +summary: A statesman-like state machine library +test_files: [] diff --git a/bundler/spec/fixtures/ruby/lockfiles/bundler_2.lock b/bundler/spec/fixtures/projects/bundler2/version_specified_gems_rb/gems.locked similarity index 100% rename from bundler/spec/fixtures/ruby/lockfiles/bundler_2.lock rename to bundler/spec/fixtures/projects/bundler2/version_specified_gems_rb/gems.locked diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_gems_rb/gems.rb b/bundler/spec/fixtures/projects/bundler2/version_specified_gems_rb/gems.rb new file mode 100644 index 00000000000..381ba235a88 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_gems_rb/gems.rb @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/projects/bundler2/version_specified_no_lockfile/Gemfile b/bundler/spec/fixtures/projects/bundler2/version_specified_no_lockfile/Gemfile new file mode 100644 index 00000000000..381ba235a88 --- /dev/null +++ b/bundler/spec/fixtures/projects/bundler2/version_specified_no_lockfile/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "business", "~> 1.4.0" +gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/bad_branch b/bundler/spec/fixtures/ruby/gemfiles/bad_branch deleted file mode 100644 index 7648045ff71..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/bad_branch +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" -gem "prius", git: "https://github.com/gocardless/prius", branch: "bad" diff --git a/bundler/spec/fixtures/ruby/gemfiles/bad_branch_business b/bundler/spec/fixtures/ruby/gemfiles/bad_branch_business deleted file mode 100644 index d9d4752c401..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/bad_branch_business +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", git: "https://github.com/gocardless/business", branch: "bad" -gem "statesman", "~> 1.2.0" -gem "prius", "~> 1.0.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/bad_ref b/bundler/spec/fixtures/ruby/gemfiles/bad_ref deleted file mode 100644 index f6ead9f7786..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/bad_ref +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" -gem "prius", git: "https://github.com/gocardless/prius" diff --git a/bundler/spec/fixtures/ruby/gemfiles/bundler_specified_and_required b/bundler/spec/fixtures/ruby/gemfiles/bundler_specified_and_required deleted file mode 100644 index 94e83830248..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/bundler_specified_and_required +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -gem "bundler", "~> 1.15.0" - -gem "appraisal" -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/cant_unlock_subdep b/bundler/spec/fixtures/ruby/gemfiles/cant_unlock_subdep deleted file mode 100644 index 213a505e935..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/cant_unlock_subdep +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -gem "ibandit", "~> 0.6.0" -gem "i18n", git: "https://github.com/svenfuchs/i18n" diff --git a/bundler/spec/fixtures/ruby/gemfiles/config_variable_source b/bundler/spec/fixtures/ruby/gemfiles/config_variable_source deleted file mode 100644 index 2ccffe6dece..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/config_variable_source +++ /dev/null @@ -1,5 +0,0 @@ -source "https://rubygems.org" - -source "https://gem.fury.io/greysteil/" do - gem "dependabot-core", "~> 0.20.0" -end diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source b/bundler/spec/fixtures/ruby/gemfiles/git_source deleted file mode 100644 index 8d92f734766..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.6.0", - git: "git@github.com:gocardless/business", - ref: "a1b78a9" -gem "statesman", "~> 1.2.0" -gem "prius", git: "https://github.com/gocardless/prius" -gem "que", git: "git@github.com:chanks/que", tag: "v0.11.6" -gem "uk_phone_numbers", git: "http://github.com/gocardless/uk_phone_numbers" diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_internal b/bundler/spec/fixtures/ruby/gemfiles/git_source_internal deleted file mode 100644 index 9e2cbffc95b..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_internal +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "parallel", git: "git@github.com:grosser/parallel", ref: "v1.12.0" -gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_no_ref b/bundler/spec/fixtures/ruby/gemfiles/git_source_no_ref deleted file mode 100644 index 758f5e3136a..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_no_ref +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.6.0", git: "git@github.com:gocardless/business" diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_undeclared b/bundler/spec/fixtures/ruby/gemfiles/git_source_undeclared deleted file mode 100644 index 7b842cb416b..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_undeclared +++ /dev/null @@ -1,7 +0,0 @@ -source "http://rubygems.org" - -git "https://github.com/kaminari/kaminari" do - gem "kaminari-core" -end - -gem 'kaminari-actionview' diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_unparseable b/bundler/spec/fixtures/ruby/gemfiles/git_source_unparseable deleted file mode 100644 index 652b04b1711..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_unparseable +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -def git_gem(name, **options) - gem name, git: "git@github.com:gocardless/business" -end - -git_gem 'business' - -gemspec diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_conflict b/bundler/spec/fixtures/ruby/gemfiles/git_source_with_conflict deleted file mode 100644 index 67d0b6182bc..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_conflict +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "rest-client", "~> 1.8" -gem "onfido", git: "https://github.com/hvssle/onfido" diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_multiple_deps b/bundler/spec/fixtures/ruby/gemfiles/git_source_with_multiple_deps deleted file mode 100644 index 2090bcb3dd1..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_multiple_deps +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem 'elasticsearch-model', github: 'elastic/elasticsearch-rails', branch: '5.x' -gem 'elasticsearch-rails', github: 'elastic/elasticsearch-rails', branch: '5.x' -gem 'elasticsearch-dsl', - github: 'elasticsearch/elasticsearch-ruby', - branch: '5.x', - require: 'elasticsearch/dsl' diff --git a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_tag_conflict b/bundler/spec/fixtures/ruby/gemfiles/git_source_with_tag_conflict deleted file mode 100644 index 54c342560de..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/git_source_with_tag_conflict +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "rest-client", "~> 1.8" -gem "onfido", git: "https://github.com/hvssle/onfido", ref: "v0.4.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/github_source b/bundler/spec/fixtures/ruby/gemfiles/github_source deleted file mode 100644 index f32db852603..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/github_source +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", github: "gocardless/business" -gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_git_override b/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_git_override deleted file mode 100644 index d7064f047f3..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_git_override +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gemspec - -gem "business", "~> 1.4.0", git: "https://github.com/gocardless/business" diff --git a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_implicit_pre b/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_implicit_pre deleted file mode 100644 index 3c474b5fb9d..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/imports_gemspec_implicit_pre +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gemspec - -gem "activerecord", "6.0.0.beta1" diff --git a/bundler/spec/fixtures/ruby/gemfiles/includes_require_relative b/bundler/spec/fixtures/ruby/gemfiles/includes_require_relative deleted file mode 100644 index 88f22b6b28c..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/includes_require_relative +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -require_relative "../some_other_file" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/less_than_matcher b/bundler/spec/fixtures/ruby/gemfiles/less_than_matcher deleted file mode 100644 index 579370c45fe..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/less_than_matcher +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -gem "business", "< 1.4.0" -gem "statesman", "< 1.2.0" diff --git a/bundler/spec/fixtures/ruby/gemfiles/path_source_eval b/bundler/spec/fixtures/ruby/gemfiles/path_source_eval deleted file mode 100644 index 2cda2d90d6b..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/path_source_eval +++ /dev/null @@ -1,6 +0,0 @@ -source "https://rubygems.org" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" -gem "example", path: File.join(File.dirname(__FILE__), 'plugins/example') -gem "prius", git: "https://github.com/gocardless/prius" diff --git a/bundler/spec/fixtures/ruby/gemfiles/path_source_if b/bundler/spec/fixtures/ruby/gemfiles/path_source_if deleted file mode 100644 index cee9a2c981a..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/path_source_if +++ /dev/null @@ -1,11 +0,0 @@ -source "https://rubygems.org" - -if ENV['something'] - gem "example", path: "plugins/example" -else - gem "example" -end - -gem "statesman", "~> 1.2.0" -gem "business", "~> 1.4.0" -gem "prius", git: "https://github.com/gocardless/prius" diff --git a/bundler/spec/fixtures/ruby/gemfiles/private_git_source b/bundler/spec/fixtures/ruby/gemfiles/private_git_source deleted file mode 100644 index 797bc79af0c..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/private_git_source +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" -gem "prius", git: "git@github.com:fundingcircle/prius" diff --git a/bundler/spec/fixtures/ruby/gemfiles/private_github_source b/bundler/spec/fixtures/ruby/gemfiles/private_github_source deleted file mode 100644 index 04b34e1a198..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/private_github_source +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -source "https://rubygems.org" - -gem "business", "~> 1.4.0" -gem "statesman", "~> 1.2.0" -gem "prius", github: "fundingcircle/prius" diff --git a/bundler/spec/fixtures/ruby/gemfiles/sidekiq_pro b/bundler/spec/fixtures/ruby/gemfiles/sidekiq_pro deleted file mode 100644 index 54a9c88647c..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/sidekiq_pro +++ /dev/null @@ -1,5 +0,0 @@ -source 'https://rubygems.org' - -source "https://username:password@gems.contribsys.com/" do - gem 'sidekiq-pro' -end \ No newline at end of file diff --git a/bundler/spec/fixtures/ruby/gemfiles/subdependency_change b/bundler/spec/fixtures/ruby/gemfiles/subdependency_change deleted file mode 100644 index d899078dbac..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/subdependency_change +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -gem "roar", "1.0.0.beta2" diff --git a/bundler/spec/fixtures/ruby/gemfiles/version_conflict_partial b/bundler/spec/fixtures/ruby/gemfiles/version_conflict_partial deleted file mode 100644 index b003dc3d901..00000000000 --- a/bundler/spec/fixtures/ruby/gemfiles/version_conflict_partial +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -gem "ibandit", "~> 0.1.0" -gem "i18n", "~> 0.6.0" diff --git a/bundler/spec/fixtures/ruby/gems/business-1.5.0.gem b/bundler/spec/fixtures/ruby/gems/business-1.5.0.gem new file mode 100644 index 00000000000..dbd35c023a4 Binary files /dev/null and b/bundler/spec/fixtures/ruby/gems/business-1.5.0.gem differ diff --git a/bundler/spec/fixtures/ruby/gems/statesman-1.2.1.gem b/bundler/spec/fixtures/ruby/gems/statesman-1.2.1.gem new file mode 100644 index 00000000000..f9b34cd6dc2 Binary files /dev/null and b/bundler/spec/fixtures/ruby/gems/statesman-1.2.1.gem differ diff --git a/bundler/spec/fixtures/ruby/gemspecs/implicit_pre b/bundler/spec/fixtures/ruby/gemspecs/implicit_pre deleted file mode 100644 index 9f315f47f5b..00000000000 --- a/bundler/spec/fixtures/ruby/gemspecs/implicit_pre +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -Gem::Specification.new do |spec| - spec.name = "example" - spec.version = "0.9.3" - spec.summary = "Automated dependency management" - spec.description = "Core logic for updating a GitHub repos dependencies" - - spec.author = "Dependabot" - spec.email = "support@dependabot.com" - spec.homepage = "https://github.com/hmarr/example" - spec.license = "MIT" - - spec.require_path = "lib" - spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", - "lib/**/*", "helpers/**/*"] - - spec.required_ruby_version = ">= 2.6.0" - spec.required_rubygems_version = ">= 2.6.11" - - spec.add_dependency 'activesupport', '>= 6.0' -end diff --git a/bundler/spec/fixtures/ruby/gemspecs/tricky_ruby b/bundler/spec/fixtures/ruby/gemspecs/tricky_ruby deleted file mode 100644 index 8643f073bba..00000000000 --- a/bundler/spec/fixtures/ruby/gemspecs/tricky_ruby +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -Gem::Specification.new do |spec| - spec.name = "example" - spec.version = "0.9.3" - spec.summary = "Automated dependency management" - spec.description = "Core logic for updating a GitHub repos dependencies" - - spec.author = "Dependabot" - spec.email = "support@dependabot.com" - spec.homepage = "https://github.com/hmarr/example" - spec.license = "MIT" - - spec.require_path = "lib" - spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", - "lib/**/*", "helpers/**/*"] - - spec.required_ruby_version = [">= 2.4.0", "<= 2.5.3"] - spec.required_rubygems_version = ">= 2.6.11" - - spec.add_dependency 'business', '~> 1.0' -end diff --git a/bundler/spec/fixtures/ruby/gemspecs/unevaluatable b/bundler/spec/fixtures/ruby/gemspecs/unevaluatable deleted file mode 100644 index 4f47df3c62b..00000000000 --- a/bundler/spec/fixtures/ruby/gemspecs/unevaluatable +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -Gem::Specification.new do |spec| - spec.name = "example" - spec.version = "1.0.0" - spec.summary = bad_code # <----- The bad code is here - spec.description = "Core logic for updating a GitHub repos dependencies" - - spec.author = "Dependabot" - spec.email = "support@dependabot.com" - spec.homepage = "https://github.com/hmarr/example" - spec.license = "MIT" - - spec.require_path = "lib" - spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", - "lib/**/*", "helpers/**/*"] - - spec.required_ruby_version = ">= 2.4.0" - spec.required_rubygems_version = ">= 2.6.11" - - spec.add_dependency "bundler", ">= 1.12.0" - spec.add_dependency "excon", "~> 0.55" - spec.add_dependency "gemnasium-parser", "~> 0.1" - spec.add_dependency "gems", "~> 1.0" - spec.add_dependency "octokit", "~> 4.6" - spec.add_dependency "gitlab", "~> 4.1" - - spec.add_development_dependency "webmock", "~> 2.3.1" - spec.add_development_dependency "rspec", "~> 3.5.0" - spec.add_development_dependency "rspec-its", "~> 1.2.0" - spec.add_development_dependency "rubocop", "~> 0.48.0" - spec.add_development_dependency "rake" -end diff --git a/bundler/spec/fixtures/ruby/lockfiles/bad_branch.lock b/bundler/spec/fixtures/ruby/lockfiles/bad_branch.lock deleted file mode 100644 index 4c6711f7948..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/bad_branch.lock +++ /dev/null @@ -1,23 +0,0 @@ -GIT - remote: https://github.com/gocardless/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 - branch: bad - specs: - prius (1.0.0) - -GEM - remote: https://rubygems.org/ - specs: - business (1.4.0) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.4.0) - prius! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.14.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/bad_branch_business.lock b/bundler/spec/fixtures/ruby/lockfiles/bad_branch_business.lock deleted file mode 100644 index 971ddbf1546..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/bad_branch_business.lock +++ /dev/null @@ -1,23 +0,0 @@ -GIT - remote: https://github.com/gocardless/business - revision: d41e445215b5af70c1604715d97dd953e868380e - branch: bad_branch - specs: - business (1.10.0) - -GEM - remote: https://rubygems.org/ - specs: - prius (1.0.0) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business! - prius (~> 1.0.0) - statesman (~> 1.2.0) - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/bad_ref.lock b/bundler/spec/fixtures/ruby/lockfiles/bad_ref.lock deleted file mode 100644 index b472d874111..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/bad_ref.lock +++ /dev/null @@ -1,22 +0,0 @@ -GIT - remote: https://github.com/gocardless/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce1 - specs: - prius (1.0.0) - -GEM - remote: https://rubygems.org/ - specs: - business (1.4.0) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.4.0) - prius! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.14.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/bundler_specified_and_required.lock b/bundler/spec/fixtures/ruby/lockfiles/bundler_specified_and_required.lock deleted file mode 100644 index 796dac5741f..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/bundler_specified_and_required.lock +++ /dev/null @@ -1,23 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - appraisal (2.2.0) - bundler - rake - thor (>= 0.14.0) - business (1.4.0) - rake (12.3.2) - statesman (1.2.5) - thor (0.20.3) - -PLATFORMS - ruby - -DEPENDENCIES - appraisal - bundler (~> 1.15.0) - business (~> 1.4.0) - statesman (~> 1.2.0) - -BUNDLED WITH - 1.17.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/cant_unlock_subdep.lock b/bundler/spec/fixtures/ruby/lockfiles/cant_unlock_subdep.lock deleted file mode 100644 index 0a305d071ab..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/cant_unlock_subdep.lock +++ /dev/null @@ -1,21 +0,0 @@ -GIT - remote: https://github.com/svenfuchs/i18n - revision: d049c7115f59689efb123d61430c078c6feb7537 - specs: - i18n (0.7.0) - -GEM - remote: https://rubygems.org/ - specs: - ibandit (0.6.6) - i18n (~> 0.7.0) - -PLATFORMS - ruby - -DEPENDENCIES - i18n! - ibandit (~> 0.6.0) - -BUNDLED WITH - 1.16.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/config_variable_source.lock b/bundler/spec/fixtures/ruby/lockfiles/config_variable_source.lock deleted file mode 100644 index 4fa068af426..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/config_variable_source.lock +++ /dev/null @@ -1,49 +0,0 @@ -GEM - remote: https://rubygems.org/ - remote: https://gem.fury.io/greysteil/ - specs: - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - ast (2.3.0) - dependabot-core (0.20.15) - bundler (>= 1.16.0.pre) - excon (~> 0.55) - gems (~> 1.0) - gitlab (~> 4.1) - octokit (~> 4.6) - parseconfig (~> 1.0.8) - parser (~> 2.4.0) - excon (0.59.0) - faraday (0.13.1) - multipart-post (>= 1.2, < 3) - gems (1.0.0) - json - gitlab (4.2.0) - httparty - terminal-table - httparty (0.15.6) - multi_xml (>= 0.5.2) - json (2.1.0) - multi_xml (0.6.0) - multipart-post (2.0.0) - octokit (4.7.0) - sawyer (~> 0.8.0, >= 0.5.3) - parseconfig (1.0.8) - parser (2.4.0.0) - ast (~> 2.2) - public_suffix (3.0.0) - sawyer (0.8.1) - addressable (>= 2.3.5, < 2.6) - faraday (~> 0.8, < 1.0) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.3.0) - -PLATFORMS - ruby - -DEPENDENCIES - dependabot-core (~> 0.20.0)! - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/explicit_ruby.lock b/bundler/spec/fixtures/ruby/lockfiles/explicit_ruby.lock deleted file mode 100644 index 8b6fab50cf2..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/explicit_ruby.lock +++ /dev/null @@ -1,18 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - business (1.4.0) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.4.0) - statesman (~> 1.2.0) - -RUBY VERSION - ruby 2.2.0p0 - -BUNDLED WITH - 1.14.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source.lock deleted file mode 100644 index 36f89da06f4..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source.lock +++ /dev/null @@ -1,43 +0,0 @@ -GIT - remote: git@github.com:gocardless/business - revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd - ref: a1b78a9 - specs: - business (1.6.0) - -GIT - remote: git@github.com:chanks/que - revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 - tag: v0.11.6 - specs: - que (0.11.6) - -GIT - remote: http://github.com/gocardless/uk_phone_numbers - revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 - specs: - uk_phone_numbers (0.1.1) - -GIT - remote: https://github.com/gocardless/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 - specs: - prius (1.0.0) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.6.0)! - prius! - que! - statesman (~> 1.2.0) - uk_phone_numbers! - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_internal.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_internal.lock deleted file mode 100644 index f4c475444b3..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_internal.lock +++ /dev/null @@ -1,21 +0,0 @@ -GIT - remote: git@github.com:grosser/parallel - revision: 5fa4406bcf0b3109f645550ca799fc7570501870 - ref: v1.12.0 - specs: - parallel (1.12.0) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - parallel! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.17.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_no_ref.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_no_ref.lock deleted file mode 100644 index aad65e7ef52..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_no_ref.lock +++ /dev/null @@ -1,18 +0,0 @@ -GIT - remote: git@github.com:gocardless/business - revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd - specs: - business (1.6.0) - -GEM - remote: https://rubygems.org/ - specs: - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.6.0)! - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_outdated.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_outdated.lock deleted file mode 100644 index d0108612a09..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_outdated.lock +++ /dev/null @@ -1,43 +0,0 @@ -GIT - remote: http://github.com/gocardless/uk_phone_numbers - revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 - specs: - uk_phone_numbers (0.1.1) - -GIT - remote: git@github.com:gocardless/business - revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd - ref: a1b78a9 - specs: - business (1.6.0) - -GIT - remote: https://github.com/gocardless/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 - specs: - prius (1.0.0) - -GIT - remote: git@github.com:gocardless/que-is-missing - revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 - tag: v0.11.6 - specs: - que (0.11.6) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.6.0)! - prius! - que! - statesman (~> 1.2.0) - uk_phone_numbers! - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_reordered.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_reordered.lock deleted file mode 100644 index 1ab2247c7ee..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_reordered.lock +++ /dev/null @@ -1,43 +0,0 @@ -GIT - remote: http://github.com/gocardless/uk_phone_numbers - revision: 1530024bd6a68d36ac18e04836ce110e0d433c36 - specs: - uk_phone_numbers (0.1.1) - -GIT - remote: git@github.com:gocardless/business - revision: a1b78a929dac93a52f08db4f2847d76d6cfe39bd - ref: a1b78a9 - specs: - business (1.6.0) - -GIT - remote: https://github.com/gocardless/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 - specs: - prius (1.0.0) - -GIT - remote: git@github.com:chanks/que - revision: 997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 - tag: v0.11.6 - specs: - que (0.11.6) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.6.0)! - prius! - que! - statesman (~> 1.2.0) - uk_phone_numbers! - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_undeclared.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_undeclared.lock deleted file mode 100644 index cb523e93ab3..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_undeclared.lock +++ /dev/null @@ -1,54 +0,0 @@ -GIT - remote: https://github.com/kaminari/kaminari - revision: 62ec743dcee69e02186e5f1a309b08e59d83f647 - specs: - kaminari-actionview (1.1.1) - actionview - kaminari-core (= 1.1.1) - kaminari-core (1.1.1) - -GEM - remote: http://rubygems.org/ - specs: - actionview (5.1.6) - activesupport (= 5.1.6) - builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - activesupport (5.1.6) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - builder (3.2.3) - concurrent-ruby (1.0.5) - crass (1.0.3) - erubi (1.7.1) - i18n (1.0.0) - concurrent-ruby (~> 1.0) - loofah (2.2.2) - crass (~> 1.0.2) - nokogiri (>= 1.5.9) - mini_portile2 (2.3.0) - minitest (5.11.3) - nokogiri (1.8.2) - mini_portile2 (~> 2.3.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) - nokogiri (>= 1.6) - rails-html-sanitizer (1.0.4) - loofah (~> 2.2, >= 2.2.2) - thread_safe (0.3.6) - tzinfo (1.2.5) - thread_safe (~> 0.1) - -PLATFORMS - ruby - -DEPENDENCIES - kaminari-actionview - kaminari-core! - -BUNDLED WITH - 1.16.1 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_unparseable.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_unparseable.lock deleted file mode 100644 index 87d81172768..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_unparseable.lock +++ /dev/null @@ -1,25 +0,0 @@ -GIT - remote: git@github.com:gocardless/business - revision: 1378a2b0b446d991b7567efbc7eeeed2720e4d8f - specs: - business (1.16.0) - -PATH - remote: . - specs: - example (0.9.3) - business (~> 1.0) - -GEM - remote: https://rubygems.org/ - specs: - -PLATFORMS - ruby - -DEPENDENCIES - business! - example! - -BUNDLED WITH - 1.17.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_conflict.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_with_conflict.lock deleted file mode 100644 index 0d812df3ff7..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_conflict.lock +++ /dev/null @@ -1,33 +0,0 @@ -GIT - remote: https://github.com/hvssle/onfido - revision: 7b36eac82a7e42049052a58af0a7943fe0363714 - specs: - onfido (0.4.0) - rest-client (~> 1.8.0) - -GEM - remote: https://rubygems.org/ - specs: - domain_name (0.5.20170404) - unf (>= 0.0.5, < 1.0.0) - http-cookie (1.0.3) - domain_name (~> 0.5) - mime-types (2.99.3) - netrc (0.11.0) - rest-client (1.8.0) - http-cookie (>= 1.0.2, < 2.0) - mime-types (>= 1.16, < 3.0) - netrc (~> 0.7) - unf (0.1.4) - unf_ext - unf_ext (0.0.7.4) - -PLATFORMS - ruby - -DEPENDENCIES - onfido! - rest-client (~> 1.8) - -BUNDLED WITH - 1.16.0.pre.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_multiple_deps.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_with_multiple_deps.lock deleted file mode 100644 index 46df68d4182..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_multiple_deps.lock +++ /dev/null @@ -1,57 +0,0 @@ -GIT - remote: git://github.com/elastic/elasticsearch-rails.git - revision: 212b37a1e927015f2a095e0f841c897d377ad1c7 - branch: 5.x - specs: - elasticsearch-model (5.1.0) - activesupport (> 3) - elasticsearch (~> 5) - hashie - elasticsearch-rails (5.1.0) - -GIT - remote: git://github.com/elasticsearch/elasticsearch-ruby.git - revision: 43f48b229a975b77c5339644d512c88389fefafa - branch: 5.x - specs: - elasticsearch (5.0.4) - elasticsearch-api (= 5.0.4) - elasticsearch-transport (= 5.0.4) - elasticsearch-api (5.0.4) - multi_json - elasticsearch-dsl (0.1.4) - elasticsearch-transport (5.0.4) - faraday - multi_json - -GEM - remote: https://rubygems.org/ - specs: - activesupport (5.2.0) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - concurrent-ruby (1.0.5) - faraday (0.15.2) - multipart-post (>= 1.2, < 3) - hashie (3.5.7) - i18n (1.0.1) - concurrent-ruby (~> 1.0) - minitest (5.11.3) - multi_json (1.13.1) - multipart-post (2.0.0) - thread_safe (0.3.6) - tzinfo (1.2.5) - thread_safe (~> 0.1) - -PLATFORMS - ruby - -DEPENDENCIES - elasticsearch-dsl! - elasticsearch-model! - elasticsearch-rails! - -BUNDLED WITH - 1.16.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_tag_conflict.lock b/bundler/spec/fixtures/ruby/lockfiles/git_source_with_tag_conflict.lock deleted file mode 100644 index 45e04676efc..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/git_source_with_tag_conflict.lock +++ /dev/null @@ -1,34 +0,0 @@ -GIT - remote: https://github.com/hvssle/onfido - revision: 7b36eac82a7e42049052a58af0a7943fe0363714 - ref: v0.4.0 - specs: - onfido (0.4.0) - rest-client (~> 1.8.0) - -GEM - remote: https://rubygems.org/ - specs: - domain_name (0.5.20170404) - unf (>= 0.0.5, < 1.0.0) - http-cookie (1.0.3) - domain_name (~> 0.5) - mime-types (2.99.3) - netrc (0.11.0) - rest-client (1.8.0) - http-cookie (>= 1.0.2, < 2.0) - mime-types (>= 1.16, < 3.0) - netrc (~> 0.7) - unf (0.1.4) - unf_ext - unf_ext (0.0.7.4) - -PLATFORMS - ruby - -DEPENDENCIES - onfido! - rest-client (~> 1.8) - -BUNDLED WITH - 1.16.0.pre.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/github_source.lock b/bundler/spec/fixtures/ruby/lockfiles/github_source.lock deleted file mode 100644 index 572981cfb26..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/github_source.lock +++ /dev/null @@ -1,20 +0,0 @@ -GIT - remote: git://github.com/gocardless/business.git - revision: d31e445215b5af70c1604715d97dd953e868380e - specs: - business (1.10.0) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.16.0.pre.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/github_source_bundler_2.lock b/bundler/spec/fixtures/ruby/lockfiles/github_source_bundler_2.lock deleted file mode 100644 index 8e0dc4def20..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/github_source_bundler_2.lock +++ /dev/null @@ -1,20 +0,0 @@ -GIT - remote: https://github.com/gocardless/business.git - revision: d31e445215b5af70c1604715d97dd953e868380e - specs: - business (1.10.0) - -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business! - statesman (~> 1.2.0) - -BUNDLED WITH - 2.0.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_no_overlap.lock b/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_no_overlap.lock deleted file mode 100644 index 3b9b3e3161c..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/imports_gemspec_no_overlap.lock +++ /dev/null @@ -1,23 +0,0 @@ -PATH - remote: . - specs: - example (0.9.3) - json (~> 1.0) - -GEM - remote: https://rubygems.org/ - specs: - business (1.4.0) - json (1.8.6) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.4.0) - example! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.15.3 diff --git a/bundler/spec/fixtures/ruby/lockfiles/missing_business.lock b/bundler/spec/fixtures/ruby/lockfiles/missing_business.lock deleted file mode 100644 index 5e9b2886370..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/missing_business.lock +++ /dev/null @@ -1,13 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - statesman (1.2.1) - -PLATFORMS - ruby - -DEPENDENCIES - statesman (~> 1.2.0) - -BUNDLED WITH - 1.10.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/private_git_source.lock b/bundler/spec/fixtures/ruby/lockfiles/private_git_source.lock deleted file mode 100644 index 02478c06e06..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/private_git_source.lock +++ /dev/null @@ -1,22 +0,0 @@ -GIT - remote: git@github.com:fundingcircle/prius - revision: cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 - specs: - prius (1.0.0) - -GEM - remote: https://rubygems.org/ - specs: - business (1.4.0) - statesman (1.2.5) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.4.0) - prius! - statesman (~> 1.2.0) - -BUNDLED WITH - 1.14.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/subdependency_change.lock b/bundler/spec/fixtures/ruby/lockfiles/subdependency_change.lock deleted file mode 100644 index f8e654a9eb1..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/subdependency_change.lock +++ /dev/null @@ -1,23 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - mini_portile (0.6.1) - multi_json (1.9.3) - nokogiri (1.6.5) - mini_portile (~> 0.6.0) - representable (2.2.3) - multi_json - nokogiri - uber (~> 0.0.7) - roar (1.0.0.beta2) - representable (>= 2.0.1, <= 3.0.0) - uber (0.0.15) - -PLATFORMS - ruby - -DEPENDENCIES - roar (= 1.0.0.beta2) - -BUNDLED WITH - 1.17.2 diff --git a/bundler/spec/fixtures/ruby/lockfiles/up_to_date_gemfile.lock b/bundler/spec/fixtures/ruby/lockfiles/up_to_date_gemfile.lock deleted file mode 100644 index 0d250ac7e59..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/up_to_date_gemfile.lock +++ /dev/null @@ -1,15 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - business (1.5.0) - statesman (1.2.1) - -PLATFORMS - ruby - -DEPENDENCIES - business (~> 1.5.0) - statesman (~> 1.2.0) - -BUNDLED WITH - 1.10.6 diff --git a/bundler/spec/fixtures/ruby/lockfiles/version_conflict_partial.lock b/bundler/spec/fixtures/ruby/lockfiles/version_conflict_partial.lock deleted file mode 100644 index b35c4cd490e..00000000000 --- a/bundler/spec/fixtures/ruby/lockfiles/version_conflict_partial.lock +++ /dev/null @@ -1,15 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - i18n (0.6.11) - ibandit (0.1.1) - -PLATFORMS - ruby - -DEPENDENCIES - i18n (~> 0.6.0) - ibandit (~> 0.1.0) - -BUNDLED WITH - 1.14.6 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/activerecord-5.2.1.gemspec.rz b/bundler/spec/fixtures/rubygems_responses/activerecord-5.2.1.gemspec.rz similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/activerecord-5.2.1.gemspec.rz rename to bundler/spec/fixtures/rubygems_responses/activerecord-5.2.1.gemspec.rz diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/api_changelog_uri.json b/bundler/spec/fixtures/rubygems_responses/api_changelog_uri.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/api_changelog_uri.json rename to bundler/spec/fixtures/rubygems_responses/api_changelog_uri.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/business-1.0.0.gemspec.rz b/bundler/spec/fixtures/rubygems_responses/business-1.0.0.gemspec.rz similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/business-1.0.0.gemspec.rz rename to bundler/spec/fixtures/rubygems_responses/business-1.0.0.gemspec.rz diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/dependencies-bundler b/bundler/spec/fixtures/rubygems_responses/dependencies-bundler similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/dependencies-bundler rename to bundler/spec/fixtures/rubygems_responses/dependencies-bundler diff --git a/bundler/spec/fixtures/rubygems_responses/dependencies-default-gemfile b/bundler/spec/fixtures/rubygems_responses/dependencies-default-gemfile new file mode 100644 index 00000000000..d1925783b64 Binary files /dev/null and b/bundler/spec/fixtures/rubygems_responses/dependencies-default-gemfile differ diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/dependencies-public_suffix b/bundler/spec/fixtures/rubygems_responses/dependencies-public_suffix similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/dependencies-public_suffix rename to bundler/spec/fixtures/rubygems_responses/dependencies-public_suffix diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/index b/bundler/spec/fixtures/rubygems_responses/index similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/index rename to bundler/spec/fixtures/rubygems_responses/index diff --git a/bundler/spec/fixtures/rubygems_responses/info-ParseTree b/bundler/spec/fixtures/rubygems_responses/info-ParseTree new file mode 100644 index 00000000000..d769df3c149 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ParseTree @@ -0,0 +1,43 @@ +--- +3.0.1 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:44ad7b0013554346d42100fb07da561bc83074676ea3faad4d76af96df5ed20c +3.0.1-x86-mswin32-60 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:a740b0ae4f32ebb421d0f3cbe072e7f31f84a7b6f2e1eca68d4294c22313fd31 +3.0.2 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:b5bb6abf58ef4096f1ba5db185b6c7a66e1082e3812659c12602b7144a59634c +3.0.2-x86-mingw32 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:5c7f4398ae28cc90fc3ed7d92bd17870b32f660a4bf7fc8d76001e2dac4f3ee9 +3.0.2-x86-mswin32-60 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:e7ccd6399da53eeb124e2a9527263abc6cf7dc50b78cfdfbd4b6c0ae605309ea +3.0.3 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:1b93866d041c2cc6bd5df5f97db865680456815e57a8b13fa6eb2955cf8db5f9 +3.0.3-x86-mingw32 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:68993bc24acfc28b971065ab0b93c5756469ceffd3416b2ef110d1de45872093 +3.0.3-x86-mswin32-60 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:92ac6e13d9979be1b521c2c9aa542473c3fff9f93b4f3d014caa7b059149ffbc +2.2.0 hoe:>= 1.5.3,RubyInline:>= 3.6.0|checksum:c10960c14eb1cfea88d43ec5fb138237289cf86c9948e35d6ed2d360b690c69f +3.0.0 RubyInline:>= 3.7.0,SexpProcessor:>= 3.0.0|checksum:a7f6f7fa6314606675fb8a8fc8a78be66b5ff4d3998f0d5cb61257c5bbea25f3 +3.0.1-x86-mingw32 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:d8c18c6a2042ee6d2144aeea50a4a255d4028782a081e66b6eabcc62c48a8fbc +1.7.1 hoe:>= 1.2.1,RubyInline:>= 3.2.0|checksum:ca10735fffedf94a552e2aa7635f940f4d12b916d99fa31995e3e8f59a355521 +2.0.0 hoe:>= 1.2.2,RubyInline:>= 3.6.0|checksum:190b12160d0d6c6e9a6b2a6d215d11ac1b2d4ccf89380c0d96fbc4a584f74c3d +2.0.1 hoe:>= 1.3.0,RubyInline:>= 3.6.0|checksum:b81d57705e2fcebcccb4b4171ede53cc27cdd1c6a6dd5042c3956070838e18c7 +2.0.2 hoe:>= 1.3.0,RubyInline:>= 3.6.0|checksum:cbdcc3ac6ed2d9713f46ab81b13cdc704885d7f1a5329cc64cd944954712789c +2.1.0 hoe:>= 1.4.0,RubyInline:>= 3.6.0|checksum:a636238af2c557df2ee450bf68baeda5960a3f9329aeb9dc96f0c8b5e96ab109 +2.1.1 hoe:>= 1.4.0,RubyInline:>= 3.6.0|checksum:32c2b2bc7843a3c459d3800a362dd87602774ae4c98bde7f8b9a95265ee398a7 +1.3.7 RubyInline:>= 3.2.0|checksum:8b8fcbaeb199bc6899531c9cdc7ec66dd0fd71c680c389d6f9ea09c52960d2a9 +1.4.0 RubyInline:>= 3.2.0|checksum:8338d6ab0c21c6dbc2e6509a23c7e0a1310b9285cfe79c6849936cbf5e4aa947 +1.4.1 RubyInline:>= 3.2.0|checksum:b00f6b7df831a17e89e1f518c79e16bf00c330b4aa489c13bd07e7091928a632 +1.5.0 hoe:> 0.0.0,RubyInline:>= 3.2.0|checksum:ab9a27e7d7bd630a041d6952191c3c18fafcc808c661475edd453527962826e6 +1.6.0 hoe:>= 1.1.1,RubyInline:>= 3.2.0|checksum:76705c02931576bb886d9bd7160c2ba58489ccad0dd6c1c101558a18d1c60a6b +1.6.1 hoe:>= 1.1.3,RubyInline:>= 3.2.0|checksum:790861ebb7cd05752f23c1b36da093d8eb1afcc56a9506c46d1ef452511b28fb +1.6.2 hoe:>= 1.1.4,RubyInline:>= 3.2.0|checksum:970d3c9ade7256e8475917363adfd134d9887bdc00c42dc5002ed83114a5b0af +1.6.3 hoe:>= 1.1.4,RubyInline:>= 3.2.0|checksum:b8a38e1dfecf09d2662a51af032d20f49d1178509fc5f19f12514f1e09235c1a +1.6.4 hoe:>= 1.1.7,RubyInline:>= 3.2.0|checksum:0980e760ca3cb05f7726ee75357ce8e5c89fdbfe4e67bec843d31b6db71944bb +1.7.0 hoe:>= 1.2.0,RubyInline:>= 3.2.0|checksum:25dd61a38a444c07a0644b75006baeb0eb0c62d9f71129ae1ab5df3fd563207c +1.1.0 |checksum:55ec8e6d42af272b2e6fef9891c5621ffb9362ce03c018a674a4e7ef4cfd6998 +1.1.1 |checksum:3db0bd6151faeba4d1fbe4f6e25a94767b485a8fda372313118bc4a0ba718286 +1.2.0 |checksum:24c0b68017086138afab719c26b05724e0d09325bde77c617102fa922aa650a7 +1.3.0 |checksum:e18652cf82bbbdc237fbe024c62a3e617bbc0c2fc0e6d1e2566b0808c1ac7f44 +1.3.2 |checksum:6742861aa1e94cb6be5b9bf3b1a7d2a44f6340fdbab5d90979a576c7a032eb30 +1.3.3 |checksum:7849ad1531a1b507b4714ae2697553797bf959dc8870b20cf9645fad7c84f5fc +1.3.4 |checksum:050314de2f30deb0e7a8b8e534fb431325b0e030bb8cac8c7c7e4d6c9fc2c8b6 +1.3.5 RubyInline:>= 3.2.0|checksum:18a4a4f7022c867a9be4805642d272ffd15634f2981f9942bae999739a20f790 +1.3.6 RubyInline:>= 3.2.0|checksum:40023c2cfaf5e87ea337ad267c2da13cc2e329373472b52ea7028c2f69c618e6 +3.0.4 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:855855525978055a6747ab85de3d2631a517d6e760226293cf3d16d8b982f4d6 +3.0.5 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:084b6784980cebb89cb408a9e1b3cddd676695cb5f8ae627856e85cb1adaa7d0 +3.0.6 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:59ba3eb6eddca64f267a87ef8667063291cb895f969b115a6ca675ab220cdc2a +3.0.7 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:e2c6dbc6b6b2187290af9ca2506875672450e3fbf1ddd7ec3a5a8db20f79ee0a +3.0.8 RubyInline:>= 3.7.0,sexp_processor:>= 3.0.0|checksum:0172ea4b94a93ab5b475c023f1ce6b564600fe493640e886cd1ca12da9039399 +3.0.9 RubyInline:~> 3.9.0,sexp_processor:~> 3.2.0|checksum:ab9abdce14b77632abac47d066a2263de6e34cb280267afec33013af7c9e4b35 diff --git a/bundler/spec/fixtures/rubygems_responses/info-RubyInline b/bundler/spec/fixtures/rubygems_responses/info-RubyInline new file mode 100644 index 00000000000..9dfec3f4799 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-RubyInline @@ -0,0 +1,39 @@ +--- +3.6.3 hoe:>= 1.2.0|checksum:0bbbff544d765b07caa4b794cae58418b04b81b195e9c3450d80335b30c5e14d +3.6.4 hoe:>= 1.3.0|checksum:5ff7b8be7ecccf635de2c203a6485f9f92b67afcb20701f0aba4393eeda5df10 +3.6.5 hoe:>= 1.3.0|checksum:6a3958a25cb27895c4e1139b62e056cd62a78384a27506288fafa94827b846b7 +3.6.6 hoe:>= 1.4.0|checksum:e74efb71c5d2620a45c3fceae0b0b82540957cfcf4133a119174fb84c9e49b25 +3.6.7 hoe:>= 1.5.1|checksum:5265848c47f61e4f185b0d88e8b7c4bf59a612cd4313b560955c9ed320c7aab6 +3.7.0 hoe:>= 1.5.3|checksum:5ab8ef4243e7e4abd39d35e0b8f9f0e91e803a4fefd89aac8134aff3f07e76d4 +3.8.0 ZenTest:>= 0|checksum:20f1a36ddb658dbdb3232c76e2453226301f51363998cc063ab07d31285c44a3 +3.8.1 ZenTest:>= 0|checksum:54577d9ff40f7c6c53be10e49a5b87ba91fd2f6601a7e2eaf4f8dda711db3e10 +3.1.0 |checksum:19cb5ba8adc1fc0aedd2b8f54cc950fb9083146e25398bdf7c1154151c6bebe8 +3.2.0 |checksum:33a2db20c3b340d54384ab4406517c62658ddf9f6909e73f24485b630e4950b8 +3.2.1 |checksum:1079fdcdebcf261ab738515ad7788010b0bff0fd504872209ffb361844bf6a95 +3.3.0 |checksum:8450af607ba3dd1626d5958f0a1704399fd9dea166073fdc658643760f6c3241 +3.3.1 |checksum:e59defb86119c480121eac88b9da83aaff31a016b979630a0549edfffc9c2ca9 +3.3.2 |checksum:8b3b657e3e322f4687d06d44ee0098e078e814a6e7ebefaa5033d0ad3662491e +3.4.0 |checksum:7ef71fbf2edb98c17a69dc25b9248c0c2524dda0f29e0b4d365324d80008cf4c +3.5.0 |checksum:aec87c423fcdbd55ae74448fd6d301969aa5c5e1a9041196bbafc5a12d1a7401 +3.6.0 |checksum:21203dbd4fd417cdd7d89c75fb148b30d2feda7bac0636925d490d5176805519 +3.6.1 hoe:>= 1.1.1|checksum:dde72fef38465bf85c66806aaf43b7002779366daa10272d20f6f203c17826bb +3.6.2 hoe:>= 1.1.1|checksum:dbc73d87d852c2acab8efa48080450a970cc525d581b882d2c95d3094e1e6518 +3.8.2 ZenTest:>= 0|checksum:03a73a6a5471160d53390f12f91010de0dc995e692f30cdc7a246d15e0b4c34d +3.8.3 |checksum:e2b30e4321eab3de1e97e5f6a7712dbadbb3e30382b75a1a7e4daf36d6ba183e +3.8.4 ZenTest:>= 0|checksum:58a7899dd5db81070cae58f3c9e1083117abf533d7ccb4addc16d40bd5aadc7e +3.8.5 ZenTest:~> 4.3.0|checksum:dda7e04d9e2016db39451a86a75d4adf444d067ab315255d7b361e65eeeb16f4 +3.8.6 ZenTest:~> 4.3|checksum:1153411b2026b50dc6516dbad4889970766d439312d588b2ab8db1ef35f1e58e +3.9.0 ZenTest:~> 4.3|checksum:ed0910195a0d246d9ac46349c433bcfe9b346b1cdac45e1a7dec58b4249708e0 +3.10.0 ZenTest:~> 4.3|checksum:48621d14c356c0039fb99f7dcf6917d627fd3bdf9036aa6f97c2766720150bdb +3.10.1 ZenTest:~> 4.3|checksum:6116e86632ed24f99c4f760b1d01ba131e2d40b8d8b38876f5fe28d6296f627b +3.11.0 ZenTest:~> 4.3|checksum:4ddf09e7aecba9833a7339a4d0bde917c450a5a45320509b0eee6611ef47a06e +3.11.1 ZenTest:~> 4.3|checksum:960f8f7cd3176e5f97edaca0351fcaf604d162ee5dbf499ad9eb598f4709e3f4 +3.11.2 ZenTest:~> 4.3|checksum:8efd926e9d40bd92aeaecb0b2d0be00d4f3b0a9d95ed25ed5bf0ffb8c13357ec +3.11.3 ZenTest:~> 4.3|checksum:c3716cdd20082224548ee465eb5df59ed4d4556a19620f34ffe2418144d7f451 +3.11.4 ZenTest:~> 4.3|checksum:7f85e67d929574c6ca6f26b3c06cf2bcc8baaf1d55713630db1d6dcfe9342df0 +3.12.0 ZenTest:~> 4.3|checksum:4303b48b54be0678a7ec81227136377c7a6ced0ab68adffe7bc94970be0dea49 +3.12.1 ZenTest:~> 4.3|checksum:e859cea02e77d23d45f42ddce2baad2fefbd7c68e5a66fa2e3aa0a261934489d +3.12.2 ZenTest:~> 4.3|checksum:28506b5ab38faae32d8a242483996b197ed4e5cf0419652072af446c0a3fe971 +3.12.3 ZenTest:~> 4.3|checksum:c1ececb4057d22638818c1bf1998cdbe485bf6eda81c3fe52a543487c9c35ad6 +3.12.4 ZenTest:~> 4.3|checksum:205bbc14c02d3d55e1b497241ede832ab87f3d981f92f3bda98b75e8144103e0 +3.12.5 ZenTest:~> 4.3|checksum:d4559cb86b7fedd2e9b4b0a3bd99a1955186dbc09f1269920a0dd5c67639c156 diff --git a/bundler/spec/fixtures/rubygems_responses/info-SexpProcessor b/bundler/spec/fixtures/rubygems_responses/info-SexpProcessor new file mode 100644 index 00000000000..5b38c545782 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-SexpProcessor @@ -0,0 +1,2 @@ +--- +3.0.0 sexp_processor:= 3.0.0|checksum:789a493b5d513f448ec0b6ec816f6ead7d1ca84606c55f8df29fce59e123c135 diff --git a/bundler/spec/fixtures/rubygems_responses/info-ZenTest b/bundler/spec/fixtures/rubygems_responses/info-ZenTest new file mode 100644 index 00000000000..be80ce87145 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ZenTest @@ -0,0 +1,61 @@ +--- +4.1.4 |checksum:9884fce46568b46ee2d1ac61248558c025d5f36b16286c1fa4a1edfc3117232a +4.1.3 |checksum:17027e7878e7849de1c74089c4d1c5943d8068815dafc2c946a5068b8b634803 +4.1.2 |checksum:10668d6fb36436902147e9e2343e3988aa82154ea465f74f8b9023ffac86dada +4.1.1 |checksum:02cf6369b80097aa3dacd1fde02f0e7c92ba009621ce26fdaa8837ee1f3de8df +4.1.0 |checksum:aa204195286d4d0deddcc99283dd269068bd54283a6f99dee09fb5bd139ab77a +4.0.0 |checksum:ab0a7dab79126f9f03afdbf14da620500f71e2938a3cff34c3ee46a696c3f500 +3.11.1 |checksum:40802ee264ab29f5962392074f4ad0320c2d1c738d81c3f032d204d975bd6cba +3.11.0 |checksum:e703711069ce6d2bf2fa2767f6e8b64c0b7d83c3abc824c74717359ec51dc8e1 +3.10.0 hoe:>= 1.5.3|checksum:6ec8015053093ed90019382e08ebb91e0993fa99e55abd66d4ec0eb9a05a762e +3.9.3 hoe:>= 1.5.3|checksum:da26598a329a2041a3dc6a29cae4e2d5b94ca199b3065c44c522f698facd13c1 +3.9.2 hoe:>= 1.5.1|checksum:c9bb8814e12849703f6956c6a98d8777dedfa144ae87a2657c2d8803bc7434e2 +3.9.1 hoe:>= 1.5.0|checksum:5827c230cddd5b21d6901027773ccc2da7ff0801d3302269f771ad631ab1b1fd +3.9.0 hoe:>= 1.5.0|checksum:b648b5f666915faa78b9d34328a64ab6389fd1cc671157cd53fc9c73e8b043be +3.8.0 hoe:>= 1.4.0|checksum:746bbc370c5465fca0bff58b6bb80be143e19b758a1b70e0df6b9a2f0300fb85 +3.7.2 hoe:>= 1.4.0|checksum:220a5abd1349f01c9fe090a8131fc7cb93eb972028bcfc8421a10638036c2cb9 +3.7.1 hoe:>= 1.4.0|checksum:fafb39a3ae2aa78f9286d2a92bff2ac300d533f9c2258cbc5167b37a7d3d6e15 +3.7.0 hoe:>= 1.4.0|checksum:2d3c619bf3f95686cc8226c46a384dec9137bb843331a9b4bacf3b7b49d40e5b +3.6.1 hoe:>= 1.2.2|checksum:7c217220a6832f30de63723f86a7f990622006de53443224a8943747183a53ee +3.6.0 hoe:>= 1.2.1|checksum:2b510651624d1b9ce180a2dba99e1346c853db03bcdc4167ca8c592f3a677365 +3.5.2 hoe:>= 1.2.0|checksum:5a2109130ebbed99e37ec3d9209c761d397b131dcc19aeefa239264d845b21f8 +3.5.1 hoe:>= 1.2.0|checksum:e26b11c350a61ac84bd2307c0d006eec2b828d0735652324483b16c2be9d85a8 +3.4.3 hoe:>= 1.1.4|checksum:57bc771c34692746257d775a80765d9ec6fe2c97b7477f0a5930d4cb154b4724 +3.4.2 hoe:>= 1.1.3|checksum:98e6bccf2fdc84efa684d8ac9ebee66b2bfe47426e717187552eeda01c11682f +3.4.1 hoe:>= 1.1.1|checksum:2b879fc76d5ffa57a03400f336110cc90926ba16f45ecd318214cdfb95b31bba +3.4.0 |checksum:adcdf57a7e3327e46d6593ece926bfb4a165e81f0fec3d5e5deb2e8a9021aef6 +3.3.0 |checksum:0b534a7312cf0d9d5f2030a974e1e33e7b4c9d413dc45dda6938e19424005593 +3.2.0 |checksum:235d00f759d88d0c071ca8b8e11bbaeb17d72526b486d09233243041bb84e491 +3.1.0 |checksum:bd61221d47d1e7c22960be51f225635078828d1b6ab26308899a93d3dbff6def +3.0.0 |checksum:beca78dd0752d1061922cf22af7adb18c5c8348e4e53a4cf287079ace939b9d7 +4.2.0 |checksum:a2ddaaae5decd418f874902c2d1b9d49cd1a8ef30d9527b5a6a684409508229f +4.2.1 |checksum:a04fe382b476bff7f14750be83f9f8c8b3ab0a382e863ce04bcae9ba6b849b2d +4.3.0 |checksum:0631216173a0e55ff47a21b8f96f526eae03a3402dbb9bccf23a3f4318e24653 +4.3.1 |checksum:746635410e8772ac03d5b10878ac59db08973707d2cb34ecd1cfb456e8247a9d +4.3.2 |checksum:c802f4f284de3465c5ae788a159593c207820e258bef70d07d6f45027fe5073e +4.3.3 |checksum:2a19d064380d7fa3afb825767a52f19190dde6c4599678d46bf17125df5d68b3 +4.4.0 |checksum:28855f0ce0d4577d6fccc8b2c815b428c1d40376b70980d7c0e7658400ed14ef +4.4.1 |checksum:a79df273bf4bfa223f967f12daf0717ba148fad272c5f57e846764adc06c7d32 +4.4.2 |checksum:7325414108f87a5fab07242679e977ab7c69503189f67e88439f90df982c58e8 +4.5.0 |checksum:30c0d30e567afd740918866b48fe9224a60bd5e1272c901023df29cc4baa2a16 +4.6.0 |checksum:583b194f72aa8b74fbfa56aa09049e2b82efd6721d9db5b3c11b13d848ebbefa +4.6.1 |checksum:53978be822962de9d02ce8f7ab96ee90fb0b7d8596b77bbb069793c0d8c44812,rubygems:~> 1.8 +4.6.2 |checksum:004e4afa490ab73cfd46e0fb9e6021a81354d081c3c524ca3cf8dc4d438dcb4e,rubygems:~> 1.8 +4.7.0 |checksum:3c6cf0c9ca0461683ed08013edfdec936bfc549f06c00d9cc739f980b2aa70bf,rubygems:~> 1.8 +4.8.0 |checksum:dfde6589c1e5ad5a0e9af017b0c4693cffda5388634bb42c47bd46d4f24d29fd,rubygems:~> 1.8 +4.8.1 |checksum:7b3c9d7b32609d29abf409b22f2032f229deefb948ffddabe26099f03f33e84a,rubygems:~> 1.8 +4.8.2 |checksum:4b5af0805b855ce03dc74e97db683974e71f710333a099f6dc368f6e52726c83,rubygems:~> 1.8 +4.8.3 |checksum:ae5d35ce508a56120ce8c20f4a1344072cd5da0929dc1fd33688c7eedac662f6,rubygems:~> 1.8 +4.8.4 |checksum:39cf67a76c3a66c932ce8769b8cca27b75763950f2822c06f4de6161ab46931c,rubygems:< 2.1&>= 1.8 +4.9.0 |checksum:262dcbe08128d090360a852551ea0a3c722733b9bce6114403751842793e7799,rubygems:< 2.1&>= 1.8 +4.9.1 |checksum:be3c0251cdc007cc9853d8e1af0d87e0611854e9fe6a2713e806512e1f24b1d1,rubygems:< 2.1&>= 1.8 +4.9.2 |checksum:f1dab48d54f309d3829f1b6f2f34bb2b2eb5358caa77cadff0f2d3916fdf1fa2,rubygems:< 2.1&>= 1.8 +4.9.3 |checksum:6854332f86d43374320487b2aad625f39684268b6dbdf5bcd3c93788993ea065,rubygems:< 2.1&>= 1.8 +4.9.4 |checksum:4d46dffb814585533d56dfa1a8a8eef2254a4db00584721b824d922d19f5996d,rubygems:< 2.2&>= 1.8 +4.9.5 |checksum:8d93c6fd25e3040661f24829bb97f37973c8b99ee0b52c91dfdc2a1d5a120b5f,rubygems:< 3.0&>= 1.8 +4.10.0 |checksum:98bb398bb7b30b5d7562fce8ff8c5ba6918690175ef95a5509ed63324f5d1296,rubygems:< 3.0&>= 1.8 +4.10.1 |checksum:e11fe9ccb71de7d2a58fedf0a8ad06b2c6a92515070a655b0c471ff11405d3cb,rubygems:< 3.0&>= 1.8 +4.11.0 |checksum:c81b515c0a620379877edad823aad8e155700166e6a7f6e441e7b1c5729fa05e,rubygems:< 3.0&>= 1.8 +4.11.1 |checksum:a5b5c2e457d05cee95f4fc50d5c133421c3a2697683cba33882e604242632077,rubygems:< 3.0&>= 1.8 +4.11.2 |checksum:8d7a4750af6aed5038de2969b6975543ead00ae2c50607915563a5ce4cf5e6c0 +4.12.0 |checksum:5301757c3ab29dd2222795c1b076dd348f4d92fe0426e97a13ae56fea47a786e diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-activemodel b/bundler/spec/fixtures/rubygems_responses/info-activemodel similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-activemodel rename to bundler/spec/fixtures/rubygems_responses/info-activemodel diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-activerecord b/bundler/spec/fixtures/rubygems_responses/info-activerecord similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-activerecord rename to bundler/spec/fixtures/rubygems_responses/info-activerecord diff --git a/bundler/spec/fixtures/rubygems_responses/info-activerecord-deprecated_finders b/bundler/spec/fixtures/rubygems_responses/info-activerecord-deprecated_finders new file mode 100644 index 00000000000..d9c1b99b55a --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-activerecord-deprecated_finders @@ -0,0 +1,9 @@ +--- +0.0.1 |checksum:711d5f816e421cf149b59c5e9640960e1b9ee38667afbee6ea982bc27b06d70a +0.0.2 |checksum:fe5995580387f00d2689f3b4494b411d4e1f2e63fe12e283c725e753c2576f0b +0.0.3 |checksum:88fd97def9b72539478e7f46eae94bb503fb502820f4667528e7c6e206a6daa9 +1.0.0 |checksum:c29d84f06faf6309a399bb924c6b1bdbb58151149457dcf5c078b82ad84cbc3a +1.0.1 |checksum:849f962bcb80f7ea31e799f7a73f96e3a2597f5da469cac7297491cc03c815db +1.0.2 |checksum:3eedefc135d39c1d36a6f034a8c002bfca7e4160f14a6f3436a25436eab94623 +1.0.3 |checksum:97ea365c348857818894bc5d8f644efa04f7543009419da5cef442ee053c4ffc +1.0.4 |checksum:d548665a464319f2736052800d28beeb3e0309698d4f6ca3a976ecf327a3b70f diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-activesupport b/bundler/spec/fixtures/rubygems_responses/info-activesupport similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-activesupport rename to bundler/spec/fixtures/rubygems_responses/info-activesupport diff --git a/bundler/spec/fixtures/rubygems_responses/info-adamantium b/bundler/spec/fixtures/rubygems_responses/info-adamantium new file mode 100644 index 00000000000..7945f368fe8 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-adamantium @@ -0,0 +1,14 @@ +--- +0.0.1 backports:~> 2.6.1,ice_nine:~> 0.4.0|checksum:6b5e7c7548022269529fda9736d115ea715b52199390729131dc579991692aa3 +0.0.2 backports:~> 2.6.4,ice_nine:~> 0.5.0|checksum:9e5ef7cc4d9cd62bfc8340ca08bac450fa3d0f0ed40b32b93d5b8f67743febef +0.0.3 backports:~> 2.6.4,ice_nine:~> 0.5.0|checksum:cba53cea1d45985a5f2734342c89a5b71b54a8d26d0ae211ebcb766998c3862a +0.0.4 backports:~> 2.6.4,ice_nine:~> 0.6.0|checksum:d0c5ecacd7938054b96d5593768243db4e8c712a4385a8d03ff40370efd09ff0 +0.0.5 backports:~> 2.7.0,ice_nine:~> 0.6.0|checksum:33d0bd78e7f7a31640c019744cb599c82a9913eaaacbec03e42933a91bc65724 +0.0.6 backports:~> 2.8.2,ice_nine:~> 0.7.0|checksum:7f591debf4f663508c3f1356cc24d6b1e9a10c015e1744aa7e3eb9babf53d6a2 +0.0.7 backports:>= 3.0.3&~> 3.0,ice_nine:~> 0.7.0|checksum:a1b0c3c233ebf0e89995ce5289ef54c03a0f6eae8f608489d61afab276deb675 +0.0.8 ice_nine:~> 0.8.0|checksum:1d71afaed37fe5a0e8a7c24e77ce786be9fc3d2567f242463f296766256f885e +0.0.9 ice_nine:~> 0.8.0|checksum:b291271d3365a59417f7406296b195ade81ac65a86565d0a47a00b6651d2003f +0.0.10 ice_nine:~> 0.8.0|checksum:14eaf208883bf028dda9fa150a7f81ad638804fcff8eabc967d1efd288486cd6 +0.0.11 ice_nine:~> 0.8.0|checksum:861a2974439be1fe144f6a7e995ad6aaf8d78cb9f095e0c181034a0843be4eb8 +0.1.0 ice_nine:~> 0.9,thread_safe:~> 0.1.2|checksum:4102b3487f197d44f2ea4f4fb8ab440c17ffa356aa586d2014ab65605941acf6 +0.2.0 ice_nine:~> 0.11.0,memoizable:~> 0.4.0|checksum:5379dc1090ec6ce115eaed4271a2056f3b72ee94d1ff866a169bbb37a3c8c504 diff --git a/bundler/spec/fixtures/rubygems_responses/info-addressable b/bundler/spec/fixtures/rubygems_responses/info-addressable new file mode 100644 index 00000000000..dc331f754eb --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-addressable @@ -0,0 +1,37 @@ +--- +2.0.0 |checksum:04b3c6a7760a387c4688bb3b80e7844ced3f5883a1ec65351cde5f40506d96ac +2.0.1 |checksum:bdb81ae7d0cbec0782a82fa98c0e2f7b28719ef40c387caf0090d000fd7d30db +2.0.2 |checksum:3b21ba60d1a2c9e3d20a284ce1f374b82f667b273c55b9388ec355853e444f53 +2.1.0 |checksum:c6c1c93189daf84af6149bb719e0f19a6afff9ba7d6dbc8321da2acb0df5b72a +0.1.0 rake:>= 0.7.2,rspec:>= 0.7.1|checksum:c5eeb7b926a98d96cd2ba54a05b7e3ba9961b3b3ee50f3930447bcff6842645b +0.1.1 rake:>= 0.7.2,rspec:>= 0.7.1|checksum:b93280d97a9ffb8022789721df3abc73d29fc5c4f9f25ac67b0a597e616cb50e +0.1.2 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:e3d541b5e18590c9918ffba654642878ef4316396aa7d6858bb4428ab853099a +1.0.0 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:61fc58bf3f6b69109b71376c0f4669fb851d7a1a8c535dbbf2c6c6d7d248aff0 +1.0.1 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:5db929d40e9d66e328a35619aced179435c806f767dc1b2863ee69e8a57e0bd2 +1.0.2 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:4f1acc4d7a234d08784d0f271733b1dddce3be12a789ba824688dd640ac50c58 +1.0.3 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:ed888046c0d76db9089b3849161389205ab2ecceb3390823e690278fd92819db +1.0.4 rake:>= 0.7.3,rspec:>= 1.0.8|checksum:1bc46df001cb386300ec8047aa885c5cb811ec5d30de55531e49c1bc72aa4da2 +2.1.1 |checksum:00fb83fa7d1086845e8f4565c5e932369c3873fb1488f3e8aec63d12c92f8b84 +2.1.2 |checksum:d32025ad5b4706954805564a0e89d4c8ad7763158b8610d4a86ae766fe9eccdf +2.2.0 |checksum:8381a0c1ba5855e6e0542fc5f6372dc0d8feedcef47f9d26e704915a54e4e6ba +2.2.1 |checksum:32fe27151fbb2924dcf8df095dc8992f4102308b626f84a0308f24e2ec0a1cce +2.2.2 |checksum:3ca45ebc9d07a03a8fb62c83c306242657e70210e8580b6cf4b0db056c581ded +2.2.3 |checksum:bd207175f4f72c443446cb03b473e72851c4a8908ee16ceefd831e512f679b5a +2.2.4 |checksum:9b388092d588c7a57b6304241429b814d6ac9b8ddc09c8554d9553311798e789 +2.2.5 |checksum:ebf984098b10dec9dd8228f5cb1caeb9f72c279c11a86dce728e03453c797d38 +2.2.6 |checksum:c12fc812b582cc11f54da1fbee366d5fa944359ce1e9ad5d3098b57ab883b23f +2.2.7 |checksum:8e87ad0cfc99668819c1c08bd4a71bbe4153c5a6c77266f56b7cb634b2953bea +2.2.8 |checksum:8958a2cf63d3b36ca1f7aa939eb36e7ae8822471877402b180ea44a98ace3cff +2.3.2 |checksum:7bca58a8ff352076dce4c7eb54802fa1e52fb4e1930d30a436f3dcf5ef0bd185 +2.3.3 |checksum:10961d0e3e621365d4ed9d2af7817a156452efff2253922f84044fa4d640c55a +2.3.4 |checksum:786b58ea02a08caefe15802bb64a7d35b025d39cc082de10330c279ffbe63e17 +2.3.5 |checksum:e74d0e825fe79b12943c7e3cbd3a5c92f7e3ebb94485b2493d320d6876321b86 +2.3.6 |checksum:e822c28133d151d450778bbcf1f6e7742d4c3aba54498eb0da33d80a3990ee8c +2.3.7 |checksum:7022baaa16500f065a290cfd2d4926367c10a40421f725582adcea546a0024f4 +2.3.8 |checksum:a64ef127ac7b0ceed1324dfbccb478e8b0e4b272f6a53a8f11ffbe826a576394 +2.4.0 |checksum:7abfff765571b0a73549c9a9d2f7e143979cd0c252f7fa4c81e7102a973ef656,ruby:>= 1.9.0 +2.5.0 public_suffix:>= 2.0.2&~> 2.0|checksum:bc5bf921b39640675fbb3484cdb45e4241b4c88d8d5a7d85a3985424ad02b9c8,ruby:>= 2.0 +2.5.1 public_suffix:>= 2.0.2&~> 2.0|checksum:b09603b313a94fa3674d8fbaae77cc7c778e9d3cde5fea3b7c1fe447941818c5,ruby:>= 2.0 +2.5.2 public_suffix:< 4.0&>= 2.0.2|checksum:73771ea960b3900d96e6b3729bd203e66f387d0717df83304411bf37efd7386e,ruby:>= 2.0 +2.6.0 public_suffix:< 4.0&>= 2.0.2|checksum:d490ad06dfc421503e659a12597d6bb0273b5cd7ff2789a1ec27210b1914952d,ruby:>= 2.0 +2.7.0 public_suffix:< 5.0&>= 2.0.2|checksum:5e9b62fe1239091ea9b2893cd00ffe1bcbdd9371f4e1d35fac595c98c5856cbb,ruby:>= 2.0 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-appraisal b/bundler/spec/fixtures/rubygems_responses/info-appraisal similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-appraisal rename to bundler/spec/fixtures/rubygems_responses/info-appraisal diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-arel b/bundler/spec/fixtures/rubygems_responses/info-arel similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-arel rename to bundler/spec/fixtures/rubygems_responses/info-arel diff --git a/bundler/spec/fixtures/rubygems_responses/info-atomic b/bundler/spec/fixtures/rubygems_responses/info-atomic new file mode 100644 index 00000000000..293a8ecf12d --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-atomic @@ -0,0 +1,58 @@ +--- +0.0.1 |checksum:2e8d6b4dccdc15a51468a6e4f73abb2b18ac00c39e8bad5bea197b8fd51e7044 +0.0.2 |checksum:a7bf7b4233699dd8e1d4a819db37efdffefc7e978a38f6d6cd7a92ea178b0483 +0.0.3 |checksum:d98ad763e0d079d059c8aa8ac7678fa5f8441f6376a82a83835e5792210715c3 +0.0.4 |checksum:3c2b06f9ba8b635c07ea1d0b721c63b4c57145c856bc824055db013902543e6b +0.0.5 |checksum:dd1fc4f741893a02b98eb809b4e84055efeb9f77557ef73c5dc876eb6b7f1b5d +0.0.6-java |checksum:d3d5604f769f9788d5501a42b5dc9495a4be2ace23657abcc984ec676872e5d3 +0.0.6 |checksum:b74ad42368b08a4fdf755e0498f1b716f877c9a39d735adf1153c53b619a6c46 +0.0.7 |checksum:bded3a6fc79cb1d26f8ebdcb3d60011c1fb6efc988340cd3d2a1cb235b012cb2 +0.0.7-java |checksum:37f42beb6cba57c2e3da94168aed536a682fb9fd365e71c410bc84101ab4f4d1 +0.0.8-java |checksum:a1b099846b47694b3bbc7bf09356684ae230a11af99b61fc09a00e88184df234 +0.0.8 |checksum:7d07bdc057ed3dcc07a271279582118682f7c4c114844b568b77871e5d098c8a +0.0.9-java |checksum:5cb3b13ce369569fd0e25c266f59176e98b77bb8a56a408f5eb5d75eddc6229b +0.0.9 |checksum:42b21ba821941731b79e36a07bf1e1530f0c054b7af26cf2d9a74ca51ceacc47 +1.0.0 |checksum:e777bd6bffaf3ab34b60609c81b89a51c9eb8ae47597c577e3abfef9514cc525 +1.0.0-java |checksum:37090762ebbc7aec744074c1ca6ee1095f6cf987a209954aa5b5014c8178e2f0 +1.0.1-java |checksum:aa6910662147fbed2af4dcaaac43f358903862f9ff84c4ed096b9d4047199ac9 +1.0.1 |checksum:54a8cbb32dad10b6b5258940e3ff8c6abe27971e1fa19600f6825a78640f2a83 +1.0.2 |checksum:1edf8db00e33f59889ea7b2ea9402d21d4e436dd28af5030d4972e77cebf17f4 +1.0.2-java |checksum:e26204db564f07f18e320f52d53b01dfafca7b0a04994906e31e457f5e596e77 +1.1.0 |checksum:edf62fbee2b9483a7b4b0db59fb2de52ee5a58d683352415a8530c5c35036c93 +1.1.0-java |checksum:bb7840d05a71a556165e2eb3560e90c175c1ac3b62b1b425803ddde98d242af9 +1.1.1-java |checksum:e9c9bcf03aa790311193c2adbd3eef6ef50919e20915a60037e7318bfa7a44fa +1.1.1 |checksum:836a4d2f76adc661122cc7f2dc1bdd2530f2525f1764d6c227dd8e8d6570b87e +1.1.2-java |checksum:ddeb79ebe3edff467570fd6cf4abae6d7db74a42ad4788806cd7e3fd99d770af +1.1.2 |checksum:81c5a112c9e4893954e18c50ce3ec28a711dc817c7e3e137b177f704978e3f5c +1.1.3 |checksum:88a7ae339d616002a6a93860fbf06d710030bb6e5e328f2af73f9d7b59821cc8 +1.1.4 |checksum:364d3f7ee7a3e91144988135eee59542038a7e57837d8202fecedb4ac0d8029c +1.1.4-java |checksum:ec02587b95fc92ad571f4a46797081ffbe9a1feb19e16e5606867a9e20197284 +1.1.5 |checksum:44ad4227f4a1911f60641dc478543ced4229c7c581327d001f027463b05bbda7 +1.1.5-java |checksum:8c4edc7a103bd95a69d2b7317b86fc447f87274275158f79cf27adc70c92fdcb +1.1.6-java |checksum:3649b9b2771af46eb679e9b2bc4960d4a42abd43a003157577bf1ba8be56109b +1.1.6 |checksum:ec47fa7871ec95d80f84497a036358bd44f9798387e659fca1bc16057288a304 +1.1.7 |checksum:903e3f560d5eba341e6af1651745a3856e10239234aa6729c1c7f681b3505afd +1.1.7-java |checksum:98e3bc47e6959611818853b5915093100569c07cbeda1694549350b5e4c172e3 +1.1.8 |checksum:a4d40ae51332a4c4af8a917dbd639d95f90a23e7b01598b4ec178cbdc290e7d5 +1.1.8-java |checksum:db5e3bdc183cf23891e1420da061714ebb42e7b486fcf787957bb02eca13d98e +1.1.9 |checksum:2ace0cc912af18c87e10f0edc98653e655e0ddc24eee401de97f5e8a75e8ac35 +1.1.9-java |checksum:7cb37a0fa4606e18c6ac2f206cfcffaee79355e52eaa1dc16623a8aaae3f55bc +1.1.10-java |checksum:17f18bbe25e23b93829f92bd1845d46d444c0c592d157cb8f1cd324e93e03815 +1.1.10 |checksum:508a337c2d14fd514fc6cc45adf4129e4c7a3a172a0790ae5a4646989c584657 +1.1.11 |checksum:436df6ad26836a52d54ef47756f267f740ac510b972d3025517f4cb6ab297332 +1.1.11-java |checksum:110c546ec8d7c88344ba164b9b2dab34a34972e19956cfa71b68649ace5dc086 +1.1.12.pre1 |checksum:9de62c0639635bdf13575a7820f8165772b118de2ae200548533177dd8ee168d,rubygems:> 1.3.1 +1.1.12 |checksum:7b0cf12e2d481a7aa218df8a29b9a7e53538c12b0f8f6c12d39ffeca358c130d +1.1.12-java |checksum:20ab44b2bd87d7be3ee020986a3c4a545f641f79d2192cf75ce1686aefc91ef6 +1.1.13-java |checksum:2c86a939b05632c4216f80fa2173b64c53d81baaa2e8df1c020aa9c6d9eebd93 +1.1.13 |checksum:1ac09cbb3ad811e72b682d68465c209f28bd6c3b1bdda11613d754669943be69 +1.1.14-java |checksum:1e0532ff1443ecf39bac3e913c997ed0cc6f7d2ee57480ab1e40e538197147a3 +1.1.14 |checksum:64c2dcf79fc48e156730a5a477b7f28a602de8d1da68a3c711d297dc5f88bf25 +1.1.15-java |checksum:949861e1a749cb82f8695a458afb48dbaea9a2a41b8e0c6b44eea2010f9f0985 +1.1.15 |checksum:c6bfbb7faf3831498986528b4a612ee8bdd424be967f09d70e8ace4e6a520571 +1.1.16-java |checksum:3102cf77b37ee68838d3c15de233a829ae8e1896037b3cb5553ed86e4547afbe +1.1.16 |checksum:56748e82ab4a29bb76e4f73843587a322666ed15d90e1925119afaa12b38dfc4 +1.1.99 |checksum:093fa4d0522bfac61b4793b00c8e14dae846d5c1d28fa9dd6ab6112be1ce09ce +1.1.99-java |checksum:b689099d39f1981f00a579e66a2ea9a893b227cb737aca7253dc7a00457e5a6f +1.1.101 |checksum:aab2010c2a958e841f0f698ce4ea081f1fafbe931809527275499bff1119998e +1.1.101-java |checksum:540e14f72312468a454e39f10a946d89b0756149322e0e68e3e762f87f947ae8 diff --git a/bundler/spec/fixtures/rubygems_responses/info-axiom-types b/bundler/spec/fixtures/rubygems_responses/info-axiom-types new file mode 100644 index 00000000000..cafa6dbaa7f --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-axiom-types @@ -0,0 +1,8 @@ +--- +0.0.1 backports:>= 3.1.1&~> 3.1,descendants_tracker:~> 0.0.1,ice_nine:~> 0.7.0|checksum:5b38e450721c4665ca990abfc03f96a327f62c257d58b3798eb865045ec1a439 +0.0.2 backports:>= 3.3.2&~> 3.3,descendants_tracker:~> 0.0.1,ice_nine:~> 0.8.0|checksum:0e37868fe0b7bdfbe1ef1ec9ee57a62e67da23f6cd89de7e40ba026007ab9376 +0.0.3 descendants_tracker:~> 0.0.1,ice_nine:~> 0.9|checksum:ce943bc0bcc0fbc097961e0d90933305f06c32656da1a88a1138b541dd84ffcc +0.0.4 descendants_tracker:~> 0.0.1,ice_nine:~> 0.9|checksum:cd58801dfe2d2803086ce66d9e3902caee76a97810d788fa6f4855fa8e7344c6 +0.0.5 descendants_tracker:~> 0.0.1,ice_nine:~> 0.9|checksum:f67b87e9d7276f78cbee8f09f9bd474d63d7b357d271c63bfac5092b4670d54c +0.1.0 descendants_tracker:~> 0.0.3,ice_nine:~> 0.11.0,thread_safe:~> 0.1.3|checksum:9ff88884d498742c2f520e7238f83fe7a6830cfa9b945b9d764fc108696c2f4a +0.1.1 descendants_tracker:~> 0.0.4,ice_nine:~> 0.11.0,thread_safe:>= 0.3.1&~> 0.3|checksum:c1ff113f3de516fa195b2db7e0a9a95fd1b08475a502ff660d04507a09980383,ruby:>= 1.9.3 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-backports b/bundler/spec/fixtures/rubygems_responses/info-backports similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-backports rename to bundler/spec/fixtures/rubygems_responses/info-backports diff --git a/bundler/spec/fixtures/rubygems_responses/info-bcrypt b/bundler/spec/fixtures/rubygems_responses/info-bcrypt new file mode 100644 index 00000000000..a82371e3a25 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-bcrypt @@ -0,0 +1,43 @@ +--- +3.1.3 |checksum:72dbe89d2349b4762da831fbe3996675c4fec90fd69ea515d097f8bcd1c64fb4 +3.1.3-java |checksum:4cdd02dbbb0685f7b495ae151a55d35fb611930b2a145142f8010ce90e144fee +3.1.3-x86-mingw32 |checksum:067254f18a5172f9083beeb025d59d4d96075b85352a61123820d1b37f9cfdcf +3.1.3-x64-mingw32 |checksum:206f273d0eb40718971f05d30bd5bf6dc0ba528aaecc4c5bf37ea3945b94807a +3.1.6-java |checksum:6f8f57700bbfc125fc73a761178f71cfecc17aeaf8c9528083c43be6dc9c53f9 +3.1.6-x64-mingw32 |checksum:0e49bd76bd007cb73fd72e12742059f57e19c7d7f671998472c35da82580b3f6 +3.1.6-x86-mingw32 |checksum:47dfb51047373842db548c07a270235d510d5f8b81b008b5425baf9bf22a5829 +3.1.6 |checksum:f29dc5b40586b2e00b7fd5e4d1fe8f83e84f89117490320483faef1cb1932ece +3.1.7 |checksum:1c30953152c7151eac21aa59eed7ea933a7bc5d5838edea1d30d79b005955702 +3.1.7-java |checksum:27251769299da257134c449ebcdd10126fc110579aa054854dca43cc42e47525 +3.1.7-x64-mingw32 |checksum:29cdc466f8083416c18dcfc4725a3c9e034a8b0e711139fcecb5fb848892a4f8 +3.1.7-x86-mingw32 |checksum:fcbe5715fc563ba4f515d9f97c138cbe015bc33dd83ece9fd129bcb8e6871642 +3.1.8-java |checksum:2ffa48347c25db4236dbaa7aebc02100c7ffab5c97111d163b66c4307663b535 +3.1.8 |checksum:f0537c78dbe5540ca6338c357df5bbedb1b2dea1c864053730bd7dd046ab54ab +3.1.8-x86-mingw32 |checksum:ac3c42dcb70a7e4398d863ce6be1d13dc8a2aa8fbcb2a5801b8d1e0a5cbcf298 +3.1.8-x64-mingw32 |checksum:7645b6c1a56043ac6f19d098ae433c488c468a059311c37290288a2f76051eca +3.1.9-java |checksum:a1a47e5feb8883c1a513f2592e11cb06ce97f9a0dc3ef48708aec3ee64f8d9f7 +3.1.9 |checksum:10bda421e4423be8c3d719010b56be99a593de4c584737963c98fc939fadef3f +3.1.9-x64-mingw32 |checksum:a5d14d3720c726c972af60d998353429a7d296d41f5b8e94a19ab93ca6f0a2bc +3.1.9-x86-mingw32 |checksum:8061217489cd91098123c466361a6a3bb9a372cf8eebe6500f8499c7d170ac41 +3.1.10 |checksum:86d25b7eaec3db734bf681aa0e3d58e121766d75c849113aeb602549ff3f8e95 +3.1.10-java |checksum:b9e67f1ed4dc07141b2cc2b2c964e0201a7e6949c5e653d323686ff421f31c82 +3.1.10-x64-mingw32 |checksum:f0abd6fd7b841951ee9997c9d6fc3369108667633caf9e37c92780f4a679105e +3.1.10-x86-mingw32 |checksum:a152bb8f037d3bddb6e340ccec54c3f53793cf13e4ebade3bb58a70f8db383b1 +3.1.11 |checksum:a0fc22135205c851f46e8a661de8be242d54951cbd2c37a6fad5c8069b2645b4 +3.1.11-java |checksum:b1e61f3c813935b5ef398e12897ba218b28888a7128dd22dd05acdfd6eb4c7b0 +3.1.11-x64-mingw32 |checksum:638fe51f1e355d76de820bbc70e6b324309aa19871afcda4b0b1419235bb8a06 +3.1.11-x86-mingw32 |checksum:594ca986b4482a404d9e17b6f274e1f85de0adcfb7c56f83e200e019f00f3874 +3.1.12.rc1 |checksum:42b30e9bf409f5193d1a00365be956e27cdddf210767afe7b86bacfc9d9a20b0,rubygems:> 1.3.1 +3.1.12.rc1-java |checksum:9b13a4b3ed61986bf0e74ceee59d2d476fa99af22cb296d4c0e1052e8ad15471,rubygems:> 1.3.1 +3.1.12.rc1-x86-mingw32 |checksum:78f553de28e0fd1d20a540d87e28772d5f6d15d48eb740bcfa43a71d6f0d79b2,rubygems:> 1.3.1 +3.1.12.rc1-x64-mingw32 |checksum:bf772afdd94d10c7dc048f0c58ce1c180a0ee457c5c776f8a7550855e50338d9,rubygems:> 1.3.1 +3.1.12 |checksum:defdc7d58313b6b34858babd314c56aba27151ae65d5095a86b652363ba64b7b +3.1.12-java |checksum:768c4c20925950455935eacd481653ca3585216bdd443bd21bc550d991f155ee +3.1.12-x86-mingw32 |checksum:f3923976f36ec863192c2b0f0a17d432d304e2562a900102d8c51c0e49dee6d2 +3.1.12-x64-mingw32 |checksum:b11fd29ce90003cc972ef71dd2999bd6201e769d8eb313db023d9c79c99fe3f2 +3.1.13-java |checksum:ba3c74c38355ee2e6a3d4ecd90839c719d1172b2bfd8143d86dff83c6f367d1d +3.1.13 |checksum:976a1afc2b10e78cb8017ffb76583361a867ef4d60d6588558c08e274ba8202a +3.1.14 |checksum:0860c48452136f9516edc83959dd8cb19a83d1aca181f7d48f15fe8a8bf5fd07 +3.1.14-java |checksum:e8300e5c669e194480af7912cd5559e866f4e348da1c9afbefdcb23ca87358d8 +3.1.15 |checksum:ef428fc73a7ef363b4506eb08d1d5218beb9d08f7ee67f194c04f8ad8e34288f +3.1.15-java |checksum:dc7ca76a03a248f8ae2bf606be0873cc16d60c27f0b1dca098b979ddfd4552ca diff --git a/bundler/spec/fixtures/rubygems_responses/info-bcrypt-ruby b/bundler/spec/fixtures/rubygems_responses/info-bcrypt-ruby new file mode 100644 index 00000000000..e0a7b9a9fca --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-bcrypt-ruby @@ -0,0 +1,61 @@ +--- +1.0.0 |checksum:7dbea95589bf9d3bd2df9dc8de9e250e230c8882df03f4cdf8b1527913cef3c2 +2.0.0 |checksum:8a686bce741cb442913ba76b9a947893a099a6edda358b9bd03cbf8d51b44db7 +2.0.1 |checksum:cc8e185ee079cdd99b1b5b45028bb9e6e3186800a6bba103dbee81253bfd1625 +2.0.2 |checksum:d1440bc902e8e4e3651bd0053baf00f84317c8733e28463a7029617342d4fc3d +2.0.3 |checksum:b78d8a802f887f2c38d20df3e7b93f08ee61f178b9ad6a9df9d7ff8a782efff6 +2.0.4 |checksum:0b49b76ecedc3a9a58112146b6de062c805d567e366a5889b518f6bb66e9e830 +2.0.5 |checksum:728d9ccaaf1c93d00fd4f7ac2f0414b6cca0d3874ad6d37ab42e640fd3843f4b +2.1.0 |checksum:89d16225ca9a059fef5469decab8d713552343a9366509519209f53c4cb16ff1 +2.1.1 |checksum:61c6db7e7e4aed8d844e90ae0a9956a1996b093cb3b95e371ead06d04aedddaa +2.1.2 |checksum:6b7150c6accf5c99a8d170bd6057542b1f9237de1bfd0aa5b7611246ced5e4f4 +2.1.3 |checksum:a68a69870523c44bef1385c59b1306dcfa611efe7def0f8b3505d531d565f880 +2.1.3-java |checksum:769bc7f19a55e2fff8c9b29629a5b9bfc9d1d75d503080f6f3e9cf60bb911440 +2.1.3-x86-mingw32 |checksum:09b38893222eab5a6b6e9400c94c124c4770ca674a9b79b0f41eff6b9a474516 +2.1.3-x86-mswin32-60 |checksum:bed88c69b4fe340b11a00d755fae254f024142a61c0515bf6752e35049d23d66 +2.1.4-java |checksum:4a461e81f07af07ffca3c95a7e331e1fb7a8c542ce114b8e8bb90355eac99597 +2.1.4-x86-mingw32 |checksum:6ce60015aaa25c69a4dc3e1bbfd80689a86c3f2c7448749180c39ec6d0a29e60 +2.1.4-x86-mswin32-60 |checksum:85e64aa122a9a900ec6b85999719fbaab4fac54ad17f7d739c340cd2b8ecf8d9 +2.1.4 |checksum:6198fa6c0c1a2c2fc437e03f956866fa82e2178f4d4006ce5a77823e4643d853 +3.0.0-java |checksum:b1e20b8c67a6c81d2a73ef9db9dc486591d88200105f1e7952c3e75fb55fb459 +3.0.0-x86-mingw32 |checksum:321588ce1cf41713b9e554999cab0308c4c3ccc9e6d87e5a2f115aeb2934e7a6 +3.0.0-x86-mswin32-60 |checksum:269b7f3abe6dad0618b835e04cab30ef119e32777e27196bdb6bb0aafe7c5738 +3.0.0 |checksum:dc9db6f2939b3fc3cc49cab5e68c56f3387a3f0765bcd009b360cd2d20041c32 +3.0.1-java |checksum:d01afee2f924b47bb0abd156acbafc3f0f2938f11a81331c9c4cd80a9e41e8b5 +3.0.1-x86-mingw32 |checksum:cd16b566cc561b232f122a4a6e9bb7de91008e3c483246f36b8978cb6a250335 +3.0.1-x86-mswin32-60 |checksum:6487dc15cea76639feb113e0f8cd11e46fcfa951f3ffaef0cdedea54de710bbb +3.0.1 |checksum:1c677889ceef0d03680162e5560ee15600c2de60a9f2113b88710ac97c7b6c4c +3.1.0 |checksum:4e610d22ba98a254d2622a4a0b620016774618ad8affbd9ecdd64f79ea8d4ee3 +3.1.0-java |checksum:00089be2e19338d64f272ea28c5e1f9a5d9be0f5a3a409ccd946ddf1f12234b9 +3.1.0-x86-mingw32 |checksum:cdf5b2317fe7323b69966ac1e7a90eac13bd67b3247a18f36dc3428412ff2177 +3.1.0-x86-mswin32-60 |checksum:170c58b859e3b5282e9b460988e950236bcbb980dc29d14ea231cd0d1ba5fd15 +3.1.1.rc1 |checksum:412ebfd72f48d38073b5c115849890d050baa498e2f63890c237a4d8bd4f9c15,rubygems:> 1.3.1 +3.1.1.rc1-java |checksum:7f9aa90b8c7efdc670a8328c0a7d337060a9423598d84e344f9b06f564a92481,rubygems:> 1.3.1 +3.1.1.rc1-x86-mingw32 |checksum:8f99a646a6c9797f8ad7c4ff5d1b3984d810d25cf297e0092cd3465b267a7494,rubygems:> 1.3.1 +3.1.1.rc1-x86-mswin32-60 |checksum:1f8033839244ea4fbb09fa101219a5658259aee1e2ec80df476b81469abd796a,rubygems:> 1.3.1 +3.1.1 |checksum:6c41754ca9160086149301548e8781b5fdf52c05b4adcd2dfc8d0783a5f56b8a +3.1.1-java |checksum:768f5ccbf3a01e92a8c5b348a878be3b46073feb30b0a7635ccfc4d43c53cac5 +3.1.1-x86-mingw32 |checksum:d13e1812d401ac03bba24dcd88cf85044bb6c0ee5d4b963bc8b2ba20adbe4fb4 +3.1.1-x86-mswin32-60 |checksum:1d252e7d62192eacad9ab6b6635c7e4c990093646e35e3e7492713410409f9bf +3.1.2.rc1 |checksum:3b81d023c6372d40d76abb375adc4a885a890ce7f0b3f8a95ff8c7acae48d38e,rubygems:> 1.3.1 +3.1.2.rc1-x86-mswin32-60 |checksum:5dec2b698224bef621d157d897959cc1a888404a72e22e2ea618468f7505b67c,rubygems:> 1.3.1 +3.1.2.rc1-x86-mingw32 |checksum:2eb0d2c40c18eec45786423f93bfd91dc64809fce02d16b4803730fb5ef17fd2,rubygems:> 1.3.1 +3.1.2.rc1-x64-mingw32 |checksum:1e7b510645b4da9a1842460f3f8af30913346fef7b5500b85260855d23d09491,rubygems:> 1.3.1 +3.1.2.rc1-java |checksum:bb0a9bfb911779be72a22666156feb716606ba237c0ac2b26c321a9b9dc9c841,rubygems:> 1.3.1 +3.1.2 |checksum:e3857f0e4f5ecbd8bbfd3f6e662aba80e4fbc60a4c78b4771bcc074b0d50f8e7 +3.1.2-java |checksum:fd858439a68bad1e67557ddfcecce65ef1d412452cb62e26a3073b0b7b63c835 +3.1.2-x64-mingw32 |checksum:22149ce36d728809bb5a57f6245508548d2de4e1e2f1691c62db93eba687d957 +3.1.2-x86-mingw32 |checksum:ad724b55861312427622342444b69af69e59f8ec60bf8622aa724531b2e767cc +3.1.2-x86-mswin32-60 |checksum:839e43cf5c5b47cf60476ea90f4f829331fe724b47de5732c9820b027d378260 +3.1.3 bcrypt:>= 3.1.3|checksum:083bec75a3537de27ee1a04afec2353de693236bab69c65ebb3d19be9abc0bec +3.1.3-java bcrypt:>= 3.1.3|checksum:aca54bc7a1635f2ddb7f8cf2e802c52b030fcd83e2f7a8bc7228b16c798802af +3.1.3-x86-mingw32 bcrypt:>= 3.1.3|checksum:54d9365fa45cd0a46054b840f2b0b88dfc2e52b8d78b8a25c6caccb9acbaa7ad +3.1.3-x64-mingw32 bcrypt:>= 3.1.3|checksum:34f7b128e54727256a32bdf46bf370df0d9b7885fdf52d09b92e2c239dc3ec22 +3.1.4 bcrypt:>= 3.1.3|checksum:3cb3ab765ce7b3a1f8f64c7bb82f6a71024e3e4766dfaf32b6f7b8957b56fe09 +3.1.4-java bcrypt:>= 3.1.3|checksum:0e9e2285753d0e3cdad43cc781cbd6c818dd5a00cb19af8867fffdf2e10ccf0b +3.1.4-x86-mingw32 bcrypt:>= 3.1.3|checksum:15194257790a48a804f12c6a8dffb30002110ac5838d292b9b256785c1905f72 +3.1.4-x64-mingw32 bcrypt:>= 3.1.3|checksum:ec3911d79ec6c5bebb07f6bf9b435c8cced9c91703cad293f1adf71f166e045b +3.1.5-java bcrypt:>= 3.1.3|checksum:0036beb31497c84c581a79194e274383f6eb764b092ffd50135431db9821fd05 +3.1.5-x64-mingw32 bcrypt:>= 3.1.3|checksum:621c0b09aed911c55ef5cfddb8ce7f6fa7d68a1366837cb45c14dd13d152676c +3.1.5-x86-mingw32 bcrypt:>= 3.1.3|checksum:b286616749f03e7877891791c46e583e67fb023d8e25ad7423fdc02f5477f1bd +3.1.5 bcrypt:>= 3.1.3|checksum:12706615f32df94d7d6942a9338da02d7e7a9963fdc4ffa27233caf24cbc19c8 diff --git a/bundler/spec/fixtures/rubygems_responses/info-bcrypt_pbkdf b/bundler/spec/fixtures/rubygems_responses/info-bcrypt_pbkdf new file mode 100644 index 00000000000..9c5d8b3ef80 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-bcrypt_pbkdf @@ -0,0 +1,17 @@ +--- +1.0.0.alpha1 |checksum:9f9941474467aa7f30b76b71228cfedc9c10334ea4be7fe08db8cb147ca49dfc,rubygems:> 1.3.1 +1.0.0.alpha1-x86-mingw32 |checksum:785f6b624fb174eca63fee5dd3173a209156991300e5141bea0b1bf651da0732,rubygems:> 1.3.1 +1.0.0.alpha1-x64-mingw32 |checksum:516f94de9f8fb8f8a1c61a5c1898538ab18c3eb6f472f3155abc0dbfa2fe2d99,rubygems:> 1.3.1 +1.0.0 |checksum:1b86abaca5f4b0e9626b3218ba8f680863bfb3ea2316e1cf647be3c346984432 +1.0.0-x86-mingw32 |checksum:0801d2d9f77ef5f21bdf0fdfdb03476066c2bece056527d875b3414727958222 +1.0.0-x64-mingw32 |checksum:46849ede220dbdd22a7808637e1481460081b5b2b9e46dc7a448120fa05db254 +1.0.1.rc1 |checksum:a751f3142b36bc8ee9d0f38d5942fa8fc0e58a2b89720243e331aa40cda5f27b,rubygems:> 1.3.1 +1.0.1 |checksum:65c4c8abd31109f47ec837fb3a6d052dc090d5fab5c943b2bef3d48244d67a0b +1.0.1-x86-mingw32 |checksum:e858034fedf36347661d9d03362e39f41b3c701a43386a6b7f1825dfe9ec4a2a +1.0.1-x64-mingw32 |checksum:5b8fd5e4d1b316c4b259c4b3e5b0483cdf4997c5122855acdb7156bb429b4e7a +1.1.0.pre.rc1 |checksum:4a8ce73b25e03976faca671f031dff7c7dca7e3fcc33a72f30997eae1b0ff6c8,rubygems:> 1.3.1 +1.1.0.pre.rc1-x86-mingw32 |checksum:e0069401f1499c6c2629e6c49b958cc96a09dd876809c6b3e3595f6dcb6ad5f0,ruby:< 2.8.dev&>= 2.0,rubygems:> 1.3.1 +1.1.0.pre.rc1-x64-mingw32 |checksum:fb79e65d982f1ba56c8d2bcce4543d9f4c588527e0315baae1798ad59d0ed22a,ruby:< 2.8.dev&>= 2.0,rubygems:> 1.3.1 +1.1.0.rc1 |checksum:4ae4942a1e78c04645dedafaa48ae546c045ebb7309368a9bba1c96b8ff1fe46,rubygems:> 1.3.1 +1.1.0.rc1-x86-mingw32 |checksum:e1f0697884111f4c6db63fe26865f38b15d4dbe792ce5795df8dd90ca579c505,ruby:< 2.8.dev&>= 2.0,rubygems:> 1.3.1 +1.1.0.rc1-x64-mingw32 |checksum:7d8ecd4d1f9f871125837160e83517a38ff5773fc8a6129c22856fd8fe5fe1d4,ruby:< 2.8.dev&>= 2.0,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-builder b/bundler/spec/fixtures/rubygems_responses/info-builder new file mode 100644 index 00000000000..189198a3fbf --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-builder @@ -0,0 +1,25 @@ +--- +1.2.1 |checksum:b5b0b1bc8c9d9ba65e7404e37597a15cb90df36584cafc43cf6014522982ead4 +1.2.2 |checksum:aa0933fadbd798dc52a7a966dbf10f5006b0fd20099c83ea7b99ffa6e06eace3 +1.2.3 |checksum:a7b3896996022e383112c6ff09581290ec1dd2738def39b2487a1b9dbdc277f8 +1.2.4 |checksum:c48e88d89479c950b65af48c204500f9489bd19d7f9ec46963b68059f66a49b0 +2.0.0 |checksum:919c5da783109da5b67b0c6fb75122d306125838b61afd6fced50fdec2660f01 +2.1.1 |checksum:e1d7c0b97468e63ffd4b35513ebc5a9f0ce949049ff6c1698bfed275f1eb01ef +2.1.2 |checksum:0620b1c79431871b3323ff511da891db841419ff25d176e2c6b80e73b77ee542 +1.1.0 |checksum:945155e9ee8f4d4f09d2e6152d0f5c298da25348fe56b4e4419934c5706cf8e3 +1.2.0 |checksum:31f2059ee1a9a0f8f762f1e29f49a6b1c7f5f73953b52a8db0000a4cc36717f9 +3.0.0 |checksum:fbd3e15e5de02245f7d649b3415b2c2875cdc9a14dccde89aa30fc14a314618e +3.1.0 |checksum:6cc2471b6e206b49ea36c205f1d55eaeaac8b2776b9a6521aa4b6384730e9b35 +3.0.1 |checksum:3691d8f2c281ed0268c6a1c4375a0e92249d44cfa76d8c1684ed2627836d651c +3.1.1 |checksum:3733e618324a0d6605c968bc4798995fe4f41f517e8f672abc775f3f8f970d8c +3.1.2 |checksum:2b896df0f509b349137319e160e120fbb38470e0ee5c337ce7503f6fbd571197 +3.0.2 |checksum:5e020d3d884420f46ab6b6cf010b82b39629b29b7fa3dd6145724be2ec4a051f +3.1.3 |checksum:35c233db41c9b0646a6f66ee78d712b4a67ce3934a8bb23af0ed6fbf13d6dd70 +3.0.3 |checksum:1d5471cdee27648a8d7485821aff888be68b538ea631a21038b194ea2810a503 +3.1.4 |checksum:b700924902c2680a4f6568aa8dee2879010754c305ea651ad7eb83b583970bdc +3.0.4 |checksum:a1a31cc496700003b6809f09fc2fda5d22532a1551eed48ee402ed44040cc442 +3.2.0 |checksum:60513dc77783d13ba1ede817dc1e70183873b1018e8e9f79585f5d6ababb4c38 +3.2.1 |checksum:1176b392d0a2b1c4cecff44d2b88f3eedd518a39268bf636e093963c0642f152 +3.2.2 |checksum:62fb9ad70ea42219a0c8d209a30281803712c717df7cb8f5ce5f63b4d489d191 +3.2.3 |checksum:21f3026ba615d87488329aff4aa4c10464563de3c648f678d8edd26374892b62 +3.2.4 |checksum:99caf08af60c8d7f3a6b004029c4c3c0bdaebced6c949165fe98f1db27fbbc10 diff --git a/bundler/spec/fixtures/rubygems_responses/info-bundler b/bundler/spec/fixtures/rubygems_responses/info-bundler new file mode 100644 index 00000000000..81358af0732 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-bundler @@ -0,0 +1,284 @@ +--- +0.3.1 |checksum:46ee4daadda796c1e9433b45015ff43f67ea47c8cf10e6f224ff5d87126d3302 +0.3.0 |checksum:c90db69e215d0caa267149111284bb35558cf9640bfa03c73317218397df2363 +0.4.0 |checksum:fe921f0123736bf47ddbea0ea4714b6f5666fd5aa1929e2d916437b3bb028080,rubygems:>= 1.3.5 +0.4.1 |checksum:e9265ccb8c92eb64a530165449028791e30b27b8fbc302ac83b8d351f8ee90d4,rubygems:>= 1.3.5 +0.5.0 |checksum:f307e4114542163c1c0738380c46b252395024c9ed4261ca12ddf1982eb02da1,rubygems:>= 1.3.5 +0.6.0 |checksum:ed37a7e1a0e1c6c5ffec48a4dfe49bdde4e49a7dc98c2579c3f7f5ecb66bf673,rubygems:>= 1.3.5 +0.7.0 |checksum:f699a9be9b5fda5cab2eb15a8e0ce18991b0919bc2d1d1953c961b1efeff79fa,rubygems:>= 1.3.5 +0.7.1 |checksum:6198a3990437309059ff0d746d2439014e707bfe5c7ee2aa4b6a6622e134d68b,rubygems:>= 1.3.5 +0.7.2 |checksum:758a01f20e576607bfb28ab27f6163517baab3e1ab8b5594adf8551d0fa80445,rubygems:>= 1.3.5 +0.7.3.pre |checksum:d867e96bf15e396337d462f89e83732ad4c92868fa760f6c840e5837c07b0196,rubygems:>= 1.3.5 +0.7.3.pre2 |checksum:0fed607229783a0e94719a34ae260ffcae4039b935e049804110c64f8dba665e,rubygems:>= 1.3.5 +0.8.0 |checksum:6c36833c591f45710008280e80c4ce02c372b9828fac32bcc74e71ae393e00ff,rubygems:>= 1.3.5 +0.8.1 |checksum:8dcdaec5f576e1ee58c5e5b2a73de7bfcd52183567a7fa16f63816465ac901ee,rubygems:>= 1.3.5 +0.9.0.pre1 |checksum:e022bb4ed35d0745ca7b5def01aaae298c2babedf11d521603accd45ac6279ad,rubygems:>= 1.3.5 +0.9.0.pre2 |checksum:6065e7159e38bc1f191249425e80a9b0f012141a81c82fef4ec1fc786440f6c5,rubygems:>= 1.3.5 +0.9.0.pre3 |checksum:a5c0f1946373328d4a8d735f9587297d6fc8514541547209c323fcba0cbd9386,rubygems:>= 1.3.5 +0.9.0.pre4 |checksum:6287aac4ce7a7131737ccbebab2218456eb7a94ce731c52a79c6cb04bb598724,rubygems:>= 1.3.5 +0.9.0.pre5 |checksum:6b285d7d0a2b0db71d0b2451c049606ab9037d9ccedd16632f6e6f8847cc4513,rubygems:>= 1.3.5 +0.9.0 |checksum:b13a7dc0bc5dc278c8e5de0f7d899c6fd87841648205e64a9748080ae249ab7a,rubygems:>= 1.3.5 +0.9.1.pre1 |checksum:b7c1f363f7f2836c01f4c79eff08860becba11e003176740c87593bab907fed5,rubygems:>= 1.3.5 +0.9.1 |checksum:7bc0a8155eb9c487934ebe4189e299eae5582ad063028ec6c6b9ff85ccbb0a5f,rubygems:>= 1.3.5 +0.9.2 |checksum:d44280912d04f01823646c09047965c2d3c18b03cbe4e4d0ad158196bf1d4ee6,rubygems:>= 1.3.5 +0.9.3 |checksum:905ed9228622dc24294ac7a415eaac0299b06909ad1b1232b0821ccfb0305fc6,rubygems:>= 1.3.5 +0.9.4 |checksum:8c07153c4b4f8eb08405c6d8cb3ae4e778bf5349efdd876958df779b5c06fb25,rubygems:>= 1.3.5 +0.9.5 |checksum:a302a687b6dc726ad7837adccc5f149ed3a9f3477d0ecd64efb2524e54356daa,rubygems:>= 1.3.5 +0.9.6 |checksum:bff7ba69061b5b8b75d6064bc55b72a8a9b2178add115137f427f083ce2d4261,rubygems:>= 1.3.5 +0.9.7 |checksum:68a2b32d6fccd7e8a5caaae21dd7e249fe4d4339d803bb0beb7e539bba2b09d0,rubygems:>= 1.3.5 +0.9.8 |checksum:9ab32b41c0a59fa40d0eb3465739768fa90e26a385058205b071373db77400af,rubygems:>= 1.3.5 +0.9.9 |checksum:038bcd6b0d95eccba8caedcf6bcfac19188e37a09a6dd8dcb4c872c222fa4f44,rubygems:>= 1.3.5 +0.9.10 |checksum:f7356f065c8b1c1aa31ea0fab01d64617c40c13fbc5d99a6f41a0a006274febc,rubygems:>= 1.3.6 +0.9.11 |checksum:1f0de01382509eb312c0624caecbf74ed88f6be6aa63a590ab039c8c88195fc8,rubygems:>= 1.3.6 +0.9.12 |checksum:7d0111d78a452ddb7a72a44396d88ecf4c33deb9270e45927ec1b765271b19d6,rubygems:>= 1.3.6 +0.9.13 |checksum:d49388d19577375ff3460b34eee81aca2d673af8e700609f28dc7200a9b932e5,rubygems:>= 1.3.6 +0.9.14 |checksum:c9b59efa22a24d959051b0fe566073ef64ab85baf6b2b37a2bc90c7fed00743d,rubygems:>= 1.3.6 +0.9.15 |checksum:13d9022f853c17537ea4b3e6b396449ab60f1467d1e491b07a8b9707d34e09aa,rubygems:>= 1.3.6 +0.9.16 |checksum:8686cde60bc94f9f9e5f06cc0a4166904bd8500d93f9090ee69b56288c0e7102,rubygems:>= 1.3.6 +0.9.17 |checksum:d7c68cb8f1f4e24d3552aed7bc67e850faa4c12ce81854811f0fd5ee78653eae,rubygems:>= 1.3.6 +0.9.18 |checksum:515b87628c46af6a8a4472294c8e07f2d1be307cb272cfbe49e1e94fd94bd25b,rubygems:>= 1.3.6 +0.9.19 |checksum:3be651ec7706f61ad611559844376c1f1be12d0ddd17d9c96ce341550d8bfc07,rubygems:>= 1.3.6 +0.9.20 |checksum:941038390229510b086f98f04b9b217341193266076b8822a8a271f3439bc459,rubygems:>= 1.3.6 +0.9.21 |checksum:4447753858bd83101f1213fcecb60eec29b96bd18a40cff4714dd91d6f0a0464,rubygems:>= 1.3.6 +0.9.22 |checksum:57bfcee38ab4ace7f70468d7c2559460505c1cab53b1642578efa899ec11607b,rubygems:>= 1.3.6 +0.9.23 |checksum:b342adf248d193cbb6c6d64d73b3fc9c0dce196c645cb685b3cf420740de7655,rubygems:>= 1.3.6 +0.9.24 |checksum:ac9955cf23000e63534fc1ef940cef3f2df4eef0415b62fed1a8e1c78381fbb0,rubygems:>= 1.3.6 +0.9.25 |checksum:4a060d0071af200a8aac0e7747ef9db4d1d1dc44a6e3a5b0d0ad43454f833dad,rubygems:>= 1.3.6 +0.9.26 |checksum:cfa4b309d005751b43dcfec7b569829faa38e1b5e332747a77eb97ff7c1c6b41,rubygems:>= 1.3.6 +1.0.0.beta.1 |checksum:52292d91950c7ad85cc11498168d471a4f7a5f78338781509d762e9001891cec,rubygems:>= 1.3.6 +1.0.0.beta.2 |checksum:4fd7d962435a005ae4028fe2e1f6bccee79811fdc375ca962923d4433a80856b,rubygems:>= 1.3.6 +1.0.0.beta.3 |checksum:2d418140034557df74fb9937923fbaa5997bf31fb5fcc03d3e9c7158e3cf9d21,rubygems:>= 1.3.6 +1.0.0.beta.4 |checksum:6665b0da3cf0202b63e1f52a8069924323f6daaf1801db6d67f88140e983180f,rubygems:>= 1.3.6 +1.0.0.beta.5 |checksum:fe13f3426acce5b26320b19207df7e0cc48127747a6bda3f57841059a51dcc73,rubygems:>= 1.3.6 +1.0.0.beta.8 |checksum:9c0f04f82686a8440e93ee8b37cfcb400d1ea6b6fe3573c2a4d29086a4704d66,rubygems:>= 1.3.6 +1.0.0.beta.9 |checksum:d95fffdd1e9d00de05f26633d715b0fec97e91197156edc2f55f601f9ba9a7ff,rubygems:>= 1.3.6 +1.0.0.beta.10 |checksum:818033005821fe96a38d888a428610fd5d99af233f92caad1349296ac9cc9fb9,rubygems:>= 1.3.6 +1.0.0.rc.1 |checksum:d55b5e3fbdf2b52a4fd6ee24020deada3ad3f116bbc2a4534e489ca8683f11e1,rubygems:>= 1.3.6 +1.0.0.rc.2 |checksum:cc46ce41919d9bcca9a6561b4ecc1463b8f96fb3cd97c115e826b52da260b79a,rubygems:>= 1.3.6 +1.0.0.rc.3 |checksum:69229ed0062f32c7b855133dc482bc7832a933aa18ae8c182b1e6ad9e5304551,rubygems:>= 1.3.6 +1.0.0.rc.5 |checksum:a3c794deb163c43be5bbf0ce31a8f6961d111378c5bf669d8e0872d9610c732c,rubygems:>= 1.3.6 +1.0.0.rc.6 |checksum:5feb373c6815a93b87630e1fb4e8f771bb84cbee6ae64ee1467f0a44402295af,rubygems:>= 1.3.6 +1.0.0 |checksum:60605563fcb6de38d088fd6416bee408405d365a608fdaec674339fc50d52f74,rubygems:>= 1.3.6 +1.0.2 |checksum:a62d9f7f21c975553dfbb8bc826a2f4ee86e98a996829e58441f528b73a3d1c4,rubygems:>= 1.3.6 +1.0.3 |checksum:2ad0c0bca6a74de182279768ebf54c0cd8584b0841077f8ae884d0e64e9f2dd6,rubygems:>= 1.3.6 +1.0.5 |checksum:2cd8c7aa1c11637ed688ed8591695fdf355f7b418088759880487b2ad1482749,rubygems:>= 1.3.6 +1.0.7 |checksum:761c0b957f794a442d1385755292abb1ba636960632a485ebf06c0a99208f6ca,rubygems:>= 1.3.6 +1.0.9 |checksum:f10e39eb283b231e51d5c304d32b82354e7dce45af33812f7422add8fb7ab1a4,rubygems:>= 1.3.6 +1.1.pre |checksum:6c92c8860520ac78e3190a5558973de90c17665d5dc56162b79cd73a2ac2ed33,rubygems:>= 1.3.6 +1.0.10 |checksum:ebe11eabeb9bd6272735240975800dddc347cbb48d9665d2b9c53d2dc752f501,rubygems:>= 1.3.6 +1.1.pre.1 |checksum:ffaadd9cbf43516d0ab9daa472bdd87e1338af3412cd02a8025041dc5e56c515,rubygems:>= 1.3.6 +1.0.11 |checksum:5f3e3ffd66bf8c2e66b5952b0dc856e4adaddd3f203789934c183d0accdb0fd6,rubygems:>= 1.3.6 +1.0.12 |checksum:103fec97d369fd518a7556bc4cc597b69d609f723949439760ecd9b889e5e7cb,rubygems:>= 1.3.6 +1.1.pre.2 |checksum:c529225d2b9f3e96b76d0f9b8c270411ef677564ea0b5f5abb7e2353651e7a83,rubygems:>= 1.3.6 +1.1.pre.3 |checksum:f1abcaa89a6e20566977c4b81d9ff00a348946fdbaa210433d0c9f04381c908f,rubygems:>= 1.3.6 +1.0.13 |checksum:4ad01020f6a25331761d821439ff15426c4726b71d347b8e8eda01d7e99dbff0,rubygems:>= 1.3.6 +1.1.pre.4 |checksum:03b92cacfe8e3a9fe438a2e4ff9319803dac655c85c43647706a917f72a88247,rubygems:>= 1.3.6 +1.0.14 |checksum:1266f59adcf8a03607657b286268101d0bc2a67243cc480fa47d1a5eb8abc35a,rubygems:>= 1.3.6 +1.0.15 |checksum:37f36b76cb19463738616f098c53610f654b0b246c8b72b3f9694cb28013d11f,rubygems:>= 1.3.6 +1.1.pre.5 |checksum:b768b12c11c2641169f12700996c7e12d643daeaa5c41e0463b2891bdd39287c,rubygems:>= 1.3.6 +1.1.pre.7 |checksum:436d88747dd8e9acb84312da35a693eda27c297a8b33fa2ac8540a732fbf119b,rubygems:>= 1.3.6 +1.0.17 |checksum:c2351609c768eb981fbb748eddd3e7d1b9ab01e150941430f366f741a327ccb0,rubygems:>= 1.3.6 +1.1.pre.8 |checksum:0d4269afbd8bbec51685d8ff0c689895e28137e99fe54a950f7bb427dd1c55e4,rubygems:>= 1.3.6 +1.0.18 |checksum:abace9e70731ac1d3be808f6160a9540b80d23cd27e1a94077b3f95d57c4e167,rubygems:>= 1.3.6 +1.0.19.rc |checksum:94592c45866b1568a1ba245961265de929b7120c949f9613c3bc158aa7ca83c6,rubygems:>= 1.3.6 +1.0.20.rc |checksum:e7f0758f1149c3333861fac882dd2378e73112ea8d459f068295a6bd8b6b2fcd,rubygems:>= 1.3.6 +1.1.pre.9 |checksum:7a1b8a7f27c34ab0c16e36e637442cb48073a2ee3c7a576145bece7295593bff,rubygems:>= 1.3.6 +1.1.pre.10 |checksum:0dbb8cd0adc1438abc51555b9b3e62fdc41841b03be295af24aa4d8a9a68db07,rubygems:>= 1.3.6 +1.0.20 |checksum:c38a0b5bfbd06655362815124e711cb68bf22af5e23e54c65f68cde5d986609b,rubygems:>= 1.3.6 +1.0.21.rc |checksum:fd5eebc8f72aca7f2c4f9c61803084c61a9a3c774a7af777877e64b8ab77fd93,rubygems:>= 1.3.6 +1.0.21 |checksum:4603cb044a1a7f78042692e866615fa7158d830066ffce075911bfbdcbf99d51,rubygems:>= 1.3.6 +1.1.rc |checksum:a15528cd8561a70d0a21c1d7b04af2f3762053e4cbb98128481e698b7688862a,rubygems:>= 1.3.6 +1.1.rc.2 |checksum:ae0012625bf40a4d90c3f8897d50ded44bebc367f51db5ff6c00d276e0e961bb,rubygems:>= 1.3.6 +1.1.rc.3 |checksum:1cdebde97203a9f5e75d314aa1c63fc8a6925ce5d826403c65098f3052abe367,rubygems:>= 1.3.6 +1.1.rc.5 |checksum:9a576c246dc641e99c10ce706b99d1598a68ac542ff8e1b724ff3d0bebb59715,rubygems:>= 1.3.6 +1.1.rc.6 |checksum:e7fd17db270530889a0d0fc7a7105818b1793ff5c406f09cd677aa729a3fb50c,rubygems:>= 1.3.6 +1.1.rc.7 |checksum:040cb01572e37344408b3ffed6fc30186e9d219d32b4dbbdc5ab8e360428b0b8,rubygems:>= 1.3.6 +1.0.22 |checksum:c0e7285aa312240747b3a3b1de59786a04950a4240ec6c96b9d0efdd58d4ec43,rubygems:>= 1.3.6 +1.1.rc.8 |checksum:a2a51612aa484af260597733889f174db984813809770927acecd27a71da5018,rubygems:>= 1.3.6 +1.1.0 |checksum:e1075ee2a6d1e6460d80ef1421db686e08885286bc3db9216f1abc7ee20d3a2d,rubygems:>= 1.3.6 +1.1.1 |checksum:fd5b79cf09648e13b759ea1c7be1830029d7be1efb2fe80620619cfedf099915,rubygems:>= 1.3.6 +1.1.2 |checksum:4bd9e56ca0a64e7069527997faa2f784cececfb6fadffd7b98652f22ce170b8c,rubygems:>= 1.3.6 +1.1.3 |checksum:df5ce52b6229bae5cf2eabae71858ea7e735fa0e479b4d00cff1ee18c5f6e800,rubygems:>= 1.3.6 +1.2.0.pre |checksum:ccc93aa16ded6b1f46d87ec562892c2412edbf1b73f240a43345eb96d56d5897,rubygems:>= 1.3.6 +1.1.4 |checksum:203f23d42f175f3a66e3c882821f207187bb2cdcbb86ff76ab2df700e624f28e,rubygems:>= 1.3.6 +1.2.0.pre.1 |checksum:8ec36f6618d2bc8264a01ce6c8376739e5424c7414b5d80b1900cb5fda61b85b,rubygems:>= 1.3.6 +1.1.5 |checksum:627270b2c18ff6747ea15427aaa5aec30c15718a3db27693d929fdbd431679bf,rubygems:>= 1.3.6 +1.2.0.rc |checksum:be9a324056a56da8c7ecb9137335f7c63a400c512241538a2a27b8d41cee6c7d,rubygems:>= 1.3.6 +1.2.0.rc.2 |checksum:481bac30301cc62a47585d0932d0a90e3eeb72f3c6c801d5a6e90030bc2160f6,rubygems:>= 1.3.6 +1.2.0 |checksum:abdafd376d88d8823851d5396a522704014bf21d5ad80b802f97245b5fbab903,rubygems:>= 1.3.6 +1.2.1 |checksum:7093e4f750cf34b6051d765e7f86a88ebe4394921571532233f640f1a7ce6790,rubygems:>= 1.3.6 +1.2.2 |checksum:aa15860bc6918acd8d38043266563ddce91eac81c22ff4c10ef837ebe9979df5,rubygems:>= 1.3.6 +1.2.3 |checksum:9c6c3553a94b93a1664337ead705d73a410c54269a97c7084e2d800498f5c62d,rubygems:>= 1.3.6 +1.3.0.pre |checksum:de5e1a74e57c4ac70fbdc3e8d96a311d2c59d7a9351cc624ae0f6c3700fc29e4,rubygems:>= 1.3.6 +1.3.0.pre.2 |checksum:b003aa946b5d58067e5dda5ab82288d161e84c176439b72841c9a9e3094df353,rubygems:>= 1.3.6 +1.3.0.pre.3 |checksum:de84814aeb94dc52a0915eb4aa62a27998c799f977a20c9315c9216ed3ec6d4f,rubygems:>= 1.3.6 +1.3.0.pre.4 |checksum:17bead0191cca10b335c9f1aa8acaa0781f76755ace69e15349713d8cf55563f,rubygems:>= 1.3.6 +1.3.0.pre.5 |checksum:f0a3dfc1ae2b081a293199d8288348ac9288468b692f20a0c948181a7ba20bd7,rubygems:>= 1.3.6 +1.3.0.pre.6 |checksum:aa83496672b9341b4c1fd48766c09d5c7cbcf0e02fc7052811c3c92c08378125,rubygems:>= 1.3.6 +1.3.0.pre.7 |checksum:0e7961a19640dab4ac24254a34688fae903acd512f3c7e17811d8513f7b84bc5,rubygems:>= 1.3.6 +1.2.4 |checksum:f4b53b7c060d732700ee60897372caa5e87f64230e0c1158346ff324ec52205d,rubygems:>= 1.3.6 +1.3.0.pre.8 |checksum:524f95d1785d9ce99ce75895f6f44531c9028d66a390321b6c67095b4f94f8bc,rubygems:>= 1.3.6 +1.2.5 |checksum:7efe3e651e89ed092cb9178925e124af2300e8c8f778eaedb423a9f583bc8923,rubygems:>= 1.3.6 +1.3.0 |checksum:f723b7328abc90fd3cf406a6fdf193eb48ddba8d9303408b2d6ff193a0235a9b,rubygems:>= 1.3.6 +1.3.1 |checksum:459c3a9336ae91b8e1045a6e3ff94fe8c218e73141b3b6009d169190a676bbda,rubygems:>= 1.3.6 +1.3.2 |checksum:fbe574abd927b00a9e908e824c8a0e0b78d07cc1a80a8eaa247dc6bb6355bd97,rubygems:>= 1.3.6 +1.3.3 |checksum:919978d5b199ac24c6f0945849b6e4a4fa0b637fdd6c6299e755489fe627c23a,rubygems:>= 1.3.6 +1.3.4 |checksum:12e291979824f8dd485825d9bd85fd33fda09c1a46ef8fc0cb145b68c361f9ed,rubygems:>= 1.3.6 +1.3.5 |checksum:08b89047f7b829f3e197a28fb1bde74c3f5cfea1552f99dfba237fee30eaffe4,rubygems:>= 1.3.6 +1.4.0.pre.1 |checksum:ff0c02ba5944e8da112efae3cca856aba192c41dbbcec25571a47e07134f9c5e,rubygems:>= 1.3.6 +1.4.0.pre.2 |checksum:f89e418afb5d8968c23071c807d89ac81314e218b992fa2014d81bd66ccd2799,rubygems:>= 1.3.6 +1.4.0.rc.1 |checksum:922d0e5798754f14bdaaf8d2adb711e3c0a86683562c996a2ec62504b936385b,rubygems:>= 1.3.6 +1.5.0.rc.1 |checksum:dca4b0f97f0908682a7395c7043d3c68c27ec977f8ad3243edc66d2e707516be,rubygems:>= 1.3.6 +1.5.0.rc.2 |checksum:0284b0f926765a14fd6fc0338756c202a7c32037349e69823b23cd15ca83feb8,rubygems:>= 1.3.6 +1.5.0 |checksum:23ca9206ad22ee13ac162c826aaadd3733f4f56d2b0a6a04e12a58257d2658b9,rubygems:>= 1.3.6 +1.5.1 |checksum:53bbc1b911d60dc5eb581a02411a46028165dbba193e0c7c407a53bdc7ef288f,rubygems:>= 1.3.6 +1.3.6 |checksum:2ba6a8ce2367b2e382b9691e6fba8089db40bb4bb88054ded1adf2616cba125f,rubygems:>= 1.3.6 +1.5.2 |checksum:e696038798bbe0a49f73eb08dfc7f57618bcaffc6ca4391d8e6ab28d7720fd41,rubygems:>= 1.3.6 +1.6.0.pre.1 |checksum:2ecf0faa9d6bfbbd571f9337f14fed1a4dc89f2684a9bfde24f6c84f70b4980d,rubygems:>= 1.3.6 +1.5.3 |checksum:149c96a57c8c1f02c5e5c2d71f1d25f8b59f7d7f2b101106c0e217232c78bd27,rubygems:>= 1.3.6 +1.6.0.pre.2 |checksum:deefaa616f85e7008e61131d5832f97573a98bb47e9a9310907c6ad05e848f50,rubygems:>= 1.3.6 +1.6.0.rc |checksum:661eacc25edf6c63d32aa74df52a86b99f15b76f486ecdb4aaea3ef678b704bf,rubygems:>= 1.3.6 +1.6.0.rc2 |checksum:96183fe888423a3e1060f4a210b1fd9eeacf8689ab6a2ebb21209e3d2235a278,rubygems:>= 1.3.6 +1.6.0 |checksum:0b3affb2ed505ec3b04f58a883c44bfd2afc75988fbe7ee2a4e603a5d803531a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.1 |checksum:ab6e3b0bed298cb2a3320d521d38979b4f58415c27b8627cb8765793df8c94db,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.2 |checksum:194ae4470a509341c1f8c79b53aab042b3d1f463bfeabdf914281d1bf926a74d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.3 |checksum:57eb3d7a41d6fb1c99ef62f654b5a95a0736889ccedcf68af175d433dc4c4521,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.4 |checksum:c71be83c77dd79d08ce6b0df83857ff804b5023f85af892bc361f20802c0111f,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.5 |checksum:14b42fa2beb54ddfa00d9fe4d7eb9fce1d3f0bced34c498417ba27bf8a039de8,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.0 |checksum:32ac937d82bc7980011b6d1ae41ed215a415fef7ed2ed9a3721e251872c58b6d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.1.pre |checksum:90b1de11a12174419b255d18fd7f3c37dc920ebf97aeb443937d452d1bf8a9f2,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.1.pre.2 |checksum:f0fdc2e222ea89113ac95700bca62e812ea05570fedd3b5da4384246dc29348a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.1.pre.3 |checksum:b188510610733faf12f8bc6fdb29ae5f53d67058175fe2bdb6f3d9a374425920,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.1 |checksum:02169ba6550960f0456c1825a0882641c553172abb2198c748f42514ebc29e90,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.2 |checksum:0c7a7c3db178597681a6c56462cf71f0f12dc8175bdf2fd38b8044bfe362caf5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.6 |checksum:e5091199e486db925347f80f9a324ee3e235b46a917796cfef69e44653a77a26,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.3 |checksum:d2cfd2cb30a14bbaab0cef7917d220d6285d6eaed024e445680b47c816592303,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.7 |checksum:345e544c760bd383a1eb7eb913e815465cf5223549c5a0bf94fdf7d7e0e0540a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.4 |checksum:09414b2dedd098bab278a46bd9a10b9cf6b409e06bb90f40ae001d60fe015388,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.8 |checksum:6e9cddf4d131d74b4210036ce4c86111f5a81fca367147c0a6e286deb7c7aa60,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.5 |checksum:8646f1b5b05aeee81b51d2b8a854b3b7451859a83b4cd5ccc6635a618208f9a4,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.6.9 |checksum:413dfad0afe80ad5c666b36ae87c955e03dca0ef3b353db1a42fdba53b1a94cc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.6 |checksum:4c02fcdbc02253b5eed7b8bb7ee5ecad8f6774c8b2d43c7ec40ef58361cfce1d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.7 |checksum:b0bdf77f8150d013bae6958df4be016c98c85da774aeab5a42f9533b469321a4,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.8 |checksum:0fa93d1836e81987d7ee7d8f3c86a6962e2a2d8eb77726568ea09ff90c5720b5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.9 |checksum:9579b8c55f850196ebf6940a10b34ceb54d7670317af9b969abe9f007300a2bd,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.10 |checksum:3a5b029493afa2423bd3cdb340af54a807b96736be1b4282512cb122f4211b32,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.11 |checksum:e70609caaa462e71ae29dcc236f73559c130d83fc4fc9c3e39f785df8bfea40b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.12 |checksum:8250a219eaa28d5f14e24802540285d97a8eeff0dbe26ed6c9150b78cb902fb9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.0.pre |checksum:f016711b03bb5aa917b23cbd7062f493e77d0306ba1938d12870deaffa657dfd,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.13 |checksum:a3c7f6fa006c62c88acd21655eaa31dd6731cdd5a77b826be23f9d17e728e78b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.0 |checksum:98522906ac94a4d78de6c724f3e1e201681c4397b359d87fd2f4a491798b74b6,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.1 |checksum:177057a97e8709bb570c58bb7c89759a029e1ce618756951c8333ea18c380275,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.2 |checksum:342da88174d60adbcb30217325c72f6974d812355dcd6fb3acc001dfcab4485e,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.3 |checksum:fa2eed66b1611ce9b5da896ff348c8c800f3e91d42797d6bfe091b72d1370de1,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.4 |checksum:3a17c8e4df1e96b59d292da8e4841545fc1cec2e079a71478cb9bd8e78a5a393,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.5 |checksum:bdd4b6d604cd81346d45f912eb6f70f06104b320bc85b5a10162ae99ffa9457e,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.0.pre |checksum:37a008313b70159484ac424cd51efe3195d058b126b9185640bcb37bd78994c5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.0.rc |checksum:ba40d1886954c1baf60aa37132247d61af82ebbefe8b88e4c2355ecd5868c5db,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.0.pre.1 |checksum:978249c9027028f04ba76a1036a07e229c75d076343d7857d0d968742757fa1b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.0 |checksum:e47a3ad1b37f4bb41d6a30bb5538288c0d1cb11caf6d86da2c653ddc78225c8e,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.1 |checksum:55a9d7e34133130614c4552886fa4a480a33fb44f2479ebbee3b6ea33d2888ab,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.14 |checksum:04c6c3ee221fad57bea2841e01b6c879431e412d7b79c82234a9aea04920a166,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.6 |checksum:56c10559b334884ceb3998d5d150c06cf322bc2dca7cf578c8c4609a7d2ae2bc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.2 |checksum:f327204a48106f5682c52e10c1954fb0289d97a2d8b420dfab31d6f3b05d6932,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.7 |checksum:c12f7cbf2a486c432f569d26f06d1d78ee0a3c2fd6519989d81e08df2bb0da94,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.3 |checksum:db09bb06357f63b235f58836a8c434f4f55814b4bdeb0826aac9b2bd808a7aed,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.4 |checksum:3890e20fea4fdc44e61cd1422b4272942fef2a43a62f469ff6b08e615f1328fa,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.7.15 |checksum:bf491b71adafe39bf7396d143393d6b100bd441d8fcf0323d42a13893e1cf36b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.8 |checksum:bb9c2d14433173eeb66c460ce9f1957385482ef55234fafb95e62de532f3dd1c,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.5 |checksum:ff0e1058789b34e293a35187bfffce592dfecfc1f8664ca2b8e1732987380f5d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.8.9 |checksum:a7609f3f1e5ba72b56f991b5b64492b8199461f5d836a82c665a55e036999acc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.6 |checksum:16ea402865debde4cb64e63f70a0f5bd464649a29ab256579a7ceb42cca45ee4,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.0.pre |checksum:c70b2729e3268865253aaa45f900d5719929ab15ec245c125b93d0ffb26d76f8,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.0.pre.1 |checksum:d85898a2fab27cc8b5ae2ff9ef08eeef9d47e8404771485e68e5ca6531c929c9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.0.pre.2 |checksum:149d58b1a5fd40511ac856e88fa5956297852074271a3fe6751a33d570de65ac,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.7 |checksum:fb0803424f340e24b990da1815dc63b6f4a916b31f1b61c95226ba68b110258c,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.8 |checksum:cb5a70519a38449e4a3c1f9519c586e78611434178f0bf32a0a6e6d1aa78ec31,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.9 |checksum:8d789d1174de8a42673f13ecba6675c95e6585c79a9a166b4d8aeb9b4c09138b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.0.rc |checksum:3eea3edd6a00e1a4eaa2d92816b314bd74fdc5a2c4f053c9ee19891f75c363a5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.0 |checksum:114208e155f5d55d3ce1b420462a8352bd88e3018f8758eac046b9bbf425f685,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.1 |checksum:57e4b969ee140920b9d33d16b6cdffd9d0ed8302ecd1b0c5b4e6257938770e9e,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.2 |checksum:83013b20b7894f3cbdf5faae16ff3364831b7cbe8762c1c85f748adf13fa9357,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.3 |checksum:9c2c7093468c763eeadad47dae9de4d7ed2e6f08e80a130d1b0d6db6a46608cc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.4 |checksum:180284a435d24ef325d7897196032e64424a6efc1d7b0b6b13b61574d98ca2f5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.9.10 |checksum:1a6b2dc1e613e7a1e6dc5ef9852eee4b3965dc3edd4e39325226f550e676f779,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.5 |checksum:cc166e24197d772d85a0788d1b2e2a12c0c5748e54c898abd275ad948ce17dfe,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.10.6 |checksum:fb2933d12304cec75dac75b93a1cb045da026b291e6c65b09744ceb900769fee,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.11.0.pre.1 |checksum:62f655313f8d5ea8ca3019077ef7d1c543cb438f4df981378c59bf938e4635d9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.11.0.pre.2 |checksum:cd3b847df2f977b308483ecfdb7b3980cc5a4219515a2702e69c9f7c15c34859,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.11.0 |checksum:7bbd63426fe89de6fc66adc19837fcf1f44bf29fb3018dc5a5dfff357aa4dedc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.11.1 |checksum:7ffed4f74a3f9b9222be04a3d3640443e235173887394176884269a4ea16cc96,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.11.2 |checksum:c7aa8ffe0af6e0c75d0dad8dd7749cb8493b834f0ed90830d4843deb61906768,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.pre.1 |checksum:98be8e0928a35ca19f6167c109562ed465030658627935045d2010a2eef0f3c2,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.pre.2 |checksum:db0451d0dacc561adf211bdd60de90ec46dc6a60309274840ce8b0d32595433f,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.rc |checksum:a110cd5a0ede334c55593db3ee4c09ae095fddb61a94cebe67612caed30d17b0,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.rc.2 |checksum:2b2ddbe8dcf86746942af638903de7d53c46fe606cd0d725ea661b3c38eb391d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.rc.3 |checksum:9406ae7a2e3fdb95409a98d2f37ff96af4916189f15fdd2dd2b159da3cccdcfa,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0.rc.4 |checksum:609d9a76912b37ddc163c9b5b7efbd0f142c32284638eab28989fb41ffd9e4bf,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.0 |checksum:5bca5421236b5467e33aa318d8eecfbb64f217c14913f299e8775f0513af29ba,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.1 |checksum:e3133b1a73d51d7adb9898e24ef07d84e479fb121b8f848320756db222ceaed0,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.2 |checksum:5fffd46672fd7c5405cb8b29919b110ad37f3feb40cbc54b1779f593aebf5963,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.3 |checksum:450afb1b440b959dc4897f63f28c999a929156211f07b5a5de9043ebef0212b9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.4 |checksum:9010e3529ca5a1a5aa62969ae1b6997f485edd35cd0720e64dffad80321718a5,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.5 |checksum:6c5e111b828de62d3b5d72d8ae0add77099a34059ede582f0de7c85479ec04e1,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.0.pre.1 |checksum:af998514e3321679841d95e8b6c24cba48b67f7a96770885a953ec480aafd100,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.0.rc.1 |checksum:ee202d15049eda07d7265a891a1646be5d363f7be6f4e282c29f78e608a28118,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.0.rc.2 |checksum:a657c0254c3cb58d35360f0e7eee17991b59cf14b87af0d5879a26aeea5b6266,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.0 |checksum:0c779c47e2561b8bab7c12f82d9ca5d3b0c0a6f7839bacaf1ddec1c2218db929,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.1 |checksum:cf1f6203db06531c7086d3fa3ca8c8e579b2cdd003dd7f4f5063607ef692eb09,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.2 |checksum:a61f8a57781c01cabe5afa468164aee550b6d0b1238fc073cd7b80601df4fc15,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.12.6 |checksum:2d15046557e079bb4a8d8ad69956a7f9bff8a14a5d75860e18781ce2d79f2deb,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.3 |checksum:524092831a73e8d33d1030a2c6cb533f393e1e0573fa10ff1a0f2cbf57342555,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.4 |checksum:92729d3460ec5ed9bc8db04145c3f3373e4e8a994ecebc6fe0f5ab2814af9075,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.5 |checksum:360a0569469c725dbad8e618cf28deb57366123efef93a04518f427cb03ab93b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.6 |checksum:fafd22dfed658ca0603f321bdd168ed709d7c682e61273b55637716459f2d0f7,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.13.7 |checksum:a9f0c8c5cf977cadce77e6185695d4a0b956a73569a5634b15b34cc07fdb7bab,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.0.pre.1 |checksum:7d37be881fb08625f3ad973d1d3f363a1fca13f43f6dc66adc622c82d3d9ebee,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.0.pre.2 |checksum:124c16a3ebbfbb28a9b07125157c15bb8deecb1aba4ef232f4e4e47d40baeb54,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.0 |checksum:ed0a8fe1fb0654a5971ef51e8754816be555494b667535ba285e8e4ff679319c,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.1 |checksum:90a2a220eb18f676def5a9e92aeb595445b9132ae2df5ffa5342e50de030ee56,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.2 |checksum:27abd62a2e01ca898479232c38ca6050d03194d1d460f908ac52eb1a2baecce9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.3 |checksum:9d61c7d983b99eb0b16d64658b182e045bcdd74ef3b139e849777f780782dbfe,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.4 |checksum:dbcd7c05de13ff4a9ded7353fe761767e5777fe9c49d2f1420f50672cfaa4ec1,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.5 |checksum:7118d31f5ed7d6c8f9b767d511f6be9a48e257a816cebd702416a6afacd16518,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.14.6 |checksum:f431206d5e89e803b7cf0dd232683eaec769ec168707e9b3d8297dba35137d40,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.0.pre.1 |checksum:feaff5f0dcb2dc28ba041f3c66c1e0945874a735962923f8e36f967bbf51ab32,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.0.pre.2 |checksum:528a484bed60c1bdeb83a0af0719e9bc89d6fc699fd90aa0cc5366d68b4d09cf,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.0.pre.3 |checksum:062e9de54705acf042ae36bacbc093b0740d038b3c488772673c952c9ffa7471,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.0.pre.4 |checksum:bbae6c788c21b73db8bd6653f29229d5fb0ce3ab09c14771488037133abe3a0d,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.0 |checksum:2d22a3fa26b00a62a19fc29f805a6cdccedaf0e4a7ca55816c27e644b2fc04cd,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.1 |checksum:fa6ec48f94faffe4987f89b4b85409fd6a4ddce8d46f779acdc26d041eb200d7,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.2 |checksum:941ccbcde4749f5f89c42e726fe07fd0e96adcf9fe0e5ddebac3fae000e3f887,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.3 |checksum:ae6860b754b0d06fdb2a0e67dfba99610a003aad27d76a0e77f9ff6b1badaa88,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.15.4 |checksum:fad17ea3a1c15df2f2a7fcea052b35ebeab0dc87906cd762470637bef8c98472,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.0.pre.1 |checksum:cb57be66695afd40d6fcc2fe7c9e411f723392366004b338ce0a4cea92c5df2a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.0.pre.2 |checksum:36538119329b96dd841b37de845748a49787fe62d0d6297796c029c9fe1a8ae9,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.0.pre.3 |checksum:1256c05b6e41bebaa61433d51257f65ad5c25ecf8ddd4634ea98cc962ae6652f,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.0 |checksum:084e7ebe90cc5236520ad49d4c5d9f58b19a98751a249070296a5943f88adb74,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.1 |checksum:42b8e0f57093e1d10c15542f956a871446b759e7969d99f91caf3b6731c156e8,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.2 |checksum:3bb53e03db0a8008161eb4c816ccd317120d3c415ba6fee6f90bbc7f7eec8690,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.3 |checksum:d89111fd6fcea3039df8f945a6be00988e29f32f9271ee35a14c7b83a36ced6a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.4 |checksum:6d04e02370d3066af29c7ef254d43223c717631d9d0ec1b8da849f8036eef997,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.5 |checksum:413f98ef094008a8528d44167c16b0739449bb605ff670d88014b30759971e1c,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.17.0.pre.1 |checksum:f64620f653424225b9157066c63281e491139c5780dbde4938a1df01d557755c,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.16.6 |checksum:07b445ea98d39032d257016a971a0c0947556eea7855ce64970da2a82e098605,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.17.0.pre.2 |checksum:f4359bd4508aecfa364fa409bfc8c10d3165bad9e6e13e4809b071488a59173b,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.17.0 |checksum:a674b4a3e813b2902504a0ce9e84e9ba84979d59fd353362e541ed59ce4edecc,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.17.1 |checksum:cc9042aff791fb05dc037da8dc617bee3fb4d77d74c3d921c2f51c23f231b24a,ruby:>= 1.8.7,rubygems:>= 1.3.6 +2.0.0.pre.1 |checksum:0c757b00b85608424495c4c34cff1e11c3856e660d3b5fc63fc5450d1ecb092d,ruby:>= 2.3.0,rubygems:>= 2.5.0 +2.0.0.pre.2 |checksum:fe83c4cd8703a97a2d55ed7c78fe47c4a659989dcce188971ddd5a0b9ae573d2,ruby:>= 2.3.0,rubygems:>= 2.5.0 +1.17.2 |checksum:b954038e22e232cc94feb323187e42194b4ed6e16a1712b37e5bd6018ec17635,ruby:>= 1.8.7,rubygems:>= 1.3.6 +1.17.3 |checksum:bc4bf75b548b27451aa9f443b18c46a739dd22ad79f7a5f90b485376a67dc352,ruby:>= 1.8.7,rubygems:>= 1.3.6 +2.0.0.pre.3 |checksum:9dc9549eafc4cd2d1d202f2f30088056c0ea631361c3a756894b488c6e22c06f,ruby:>= 2.3.0,rubygems:>= 3.0.0 +2.0.0 |checksum:e21aaa1aff1414df064a627e7fcdb31c43e4a72820082f0153fdf8d6ba288f73,ruby:>= 2.3.0,rubygems:>= 3.0.0 +2.0.1 |checksum:c7e38039993c9c2edc27397aef4a3370a4b35c7fae3d93e434e501c4bd7656ea,ruby:>= 2.3.0,rubygems:>= 2.5.0 +2.0.2 |checksum:4c2ae1fce8a072b832ac7188f1e530a7cff8f0a69d8a9621b32d1407db00a2d0,ruby:>= 2.3.0,rubygems:>= 2.5.0 +2.1.0.pre.1 |checksum:36635c1da65bea5e452c75c748aacc01cc7af59b2c3924b1d4e62f42f6460a6f,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.0.pre.2 |checksum:d91bb1f328d90313a2e37079afe51cc3a4a0027198e88ef94a1e7576b330be2b,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.0.pre.3 |checksum:57557269111a666a821818854f65111418b2417d64ad05dcd4be44469bdd8dfb,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.0 |checksum:b3a865af3c8e78cab4d663e087cef4aa79672aacd9defdf783f0f493e2a25c2e,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.1 |checksum:c20e3e7a18de9d99b5919eaaee4dbeecc55ffcbfd08e1807572a618f426fdfc2,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.2 |checksum:a3d89c9a7fbfe9364512cac10bc8dc4f9c370e41375c03cd36cad31eef6fb961,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.3 |checksum:9b9a9a5685121403eda1ae148ed3a34c86418f2a2beec7df82a45d4baca0e5d2,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.1.4 |checksum:50014d21d6712079da4d6464de12bb93c278f87c9200d0b60ba99f32c25af489,ruby:>= 2.3.0,rubygems:>= 2.5.2 +2.2.0.rc.1 |checksum:2c50355965b6603035ae43199484e9f0f12f45b6d7f7a8d18a503b6d178b4f42,ruby:>= 2.3.0,rubygems:>= 2.5.2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-business b/bundler/spec/fixtures/rubygems_responses/info-business similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-business rename to bundler/spec/fixtures/rubygems_responses/info-business diff --git a/bundler/spec/fixtures/rubygems_responses/info-coercible b/bundler/spec/fixtures/rubygems_responses/info-coercible new file mode 100644 index 00000000000..83ba2be258c --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-coercible @@ -0,0 +1,6 @@ +--- +0.0.1 backports:~> 2.6,descendants_tracker:~> 0.0.1|checksum:8b84919ce6642ba605bdc336ef32b368d06f6213dcdf389f4027613be111d0c6 +0.0.2 backports:~> 2.8,descendants_tracker:~> 0.0.1|checksum:eb8d5c9495e7b051a32d2e5c76c9aaae023527fff92704e29f6094ce89f59f71 +0.1.0 backports:~> 2.8,descendants_tracker:~> 0.0.1|checksum:cadff564b1b4d11e5a78e5036ae3c4976db075f2300fe611a0377db91b8320bf +0.2.0 backports:>= 3.1.0&~> 3.0,descendants_tracker:~> 0.0.1|checksum:9a9704c0b0acdaf2a7f17d8d50d69caac4a11aebf6a65a0b888956978fcaa117 +1.0.0 descendants_tracker:~> 0.0.1|checksum:5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc diff --git a/bundler/spec/fixtures/rubygems_responses/info-concurrent-ruby b/bundler/spec/fixtures/rubygems_responses/info-concurrent-ruby new file mode 100644 index 00000000000..0751507dc19 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-concurrent-ruby @@ -0,0 +1,122 @@ +--- +0.0.1 |checksum:71c6aa53a05c92c07f28c8e8d6c37f2a2a04e01d60c52ce245db4e87f2704f97 +0.1.0 functional-ruby:~> 0.7.0|checksum:5b8e92480d91783cd956212b0ff097e69c11e5231a848625769b92a2de85b932 +0.1.1 functional-ruby:~> 0.7.0|checksum:458c2e3b8fd0240936866b89091e02e27ceaafdc2bbf7b2abc21e9f7ac3e6793 +0.1.1.pre.1 functional-ruby:~> 0.7.1|checksum:d12935ef902fec0d491687e1e6ffbc94029c4c0adb757127a61086506a266003,rubygems:> 1.3.1 +0.1.1.pre.2 functional-ruby:~> 0.7.1|checksum:0c2a2f6d1554580d8a822317326751f3862e3bf1dcdaa100ed517f25f845aa00,rubygems:> 1.3.1 +0.1.1.pre.3 functional-ruby:~> 0.7.1|checksum:26db200d1fc73e6f24f30df69bf3d05da3201435ce4da452554e791148be2501,rubygems:> 1.3.1 +0.1.1.pre.4 functional-ruby:~> 0.7.1|checksum:038aae90bc606d8cf1c9f7f4ba947cf061e03a5cc3321a97fd21b14b752a4bdd,rubygems:> 1.3.1 +0.1.1.pre.5 functional-ruby:~> 0.7.1|checksum:0c5f51419ac7bd9809f12dc2f34c3cf536153dc65003ac758e48be682746f78a,rubygems:> 1.3.1 +0.2.0 functional-ruby:~> 0.7.4|checksum:136149fcb5df894203cabe5554f24d1d331f4108b5e3df403b1e49a1f524ff02 +0.2.1 functional-ruby:~> 0.7.4|checksum:8ca954f1da7ebc7154ac0d017598b3f8c2e983652734dde6f7ca898ca733a2e2 +0.2.2 functional-ruby:~> 0.7.4|checksum:5d022697c2afcdb7da66ec9bcc4714db0738095a3805bbe25c69479b18893b42 +0.3.0.pre.1 functional-ruby:~> 0.7.4|checksum:499b374c7e70ba387be65c7fea93f381d2cea763e27e84926049f659dfa28d11,rubygems:> 1.3.1 +0.3.0.pre.2 |checksum:099a2607bd2af117cbd21350a077198ddcf35e96ede598775481a2554b1ea86a,rubygems:> 1.3.1 +0.3.0.pre.3 |checksum:b4baee562fe06ac7b3c9f12a2e6e37836b2d2a5311ea1f483fc0dcfcf32f5b30,rubygems:> 1.3.1 +0.3.0 |checksum:8c49cda5da5f3825d9042c4136999b63c86b0e5c7cb9f79ad07f0004f886589f +0.3.1.pre.1 |checksum:d2b7f8164c8fd42c83d9dccf0049cd9f653c82fb7e5e8416e371f895f0d5c7ad,rubygems:> 1.3.1 +0.3.1.pre.2 |checksum:5dfea5e0915d3ae8756432d0d227f1bb9eabfcd4f91446d9834a3a77c88bcaff,rubygems:> 1.3.1 +0.3.1 |checksum:2de604f96137f7b281a7915728cb04c27c0ebbdf9f5e9fa2e487e9bfb7bae2a7 +0.3.2 |checksum:b39010ce651b579ad5d81c79decff87cced2d21e488f1b9c278e689b61a2bf78 +0.4.0 |checksum:9ac92eb235709c9b372ee11954c53d6fda3cf7de6c6e5efa59fc65731da5f2f3 +0.4.1 |checksum:9a0e1c8ac7a80e9eb60ae3bd4008e606b7c7622acef7b2d0a83d8f40aa65e4d2 +0.5.0.pre.1 |checksum:74b47ed674389008dab8832c60e2d1dfeeeff09acce0374f3f5286012371b6e2,rubygems:> 1.3.1 +0.5.0 |checksum:ea2f2ab4a91fe0e8ba10808a87a736257244d80beb4eb1a832a0ae14623d472e +0.6.0.pre.1 |checksum:924c76954071301e80c30a61e950332f333ffc3a94c73842557b6928f3f80de9,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.6.0.pre.2 |checksum:173773de3da6d228a61c26d29a578a2b23d31a54cbdf320f003104bca7544efc,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.6.0 |checksum:e2d8b37bdb6271c473577741cbecee6d9cfa1cfab3058cedc2257d5554a6b7bf,ruby:>= 1.9.3 +0.6.1 |checksum:9daa81181a858f58fff468c5bf3a817e28196309aa07af2062cb5a215a1ca2cb,ruby:>= 1.9.3 +0.7.0.rc0-java |checksum:5e4fb52b18087531e4d4c611eca29463badc715f04e95431ac4bd87ec35274e2,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x64-mingw32 |checksum:21f2b081f4b983f812154f0868bf507470653fd98dc47952bfecaadd11d294a8,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x86-linux |checksum:a3c6f44b7d71749f648cb296e3e7e1c33677b00483785bd1121e798ee83199d1,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x86-mingw32 |checksum:16d189120b89bf30b282f1077c2146184ce7ea1baadb0be7b68c0aeb839ecfe0,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x86-solaris-2.11 |checksum:4a4ce0ffcf989f771317450fb3efcea26291e752354e50aced4bd65e5e1eb887,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x86_64-darwin-13 |checksum:8d586f7bffdf40d629fb1dd60d4137c3fe0d0e63437330b8d30fc5b1e5a6c178,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0-x86_64-linux |checksum:969f8e95b2c123b1d57cdcbd179f01000a62a51e2bfdea3340c516fc4fa7a7fe,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc0 |checksum:f18ba81b62474099b72a63e9d9d2b714a480c5ce8347b30ff5baf54f679edb1e,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-java |checksum:d2e602d7c940f278ed90ea9ba86d6d6225cd6a86770a2d7263113445e85a761e,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x64-mingw32 |checksum:d9e22c023d5c2412cc0ed0c8d13d1d028bdea4754cc35320cd22d7285e12c02f,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x86-linux |checksum:a00369f48ce65a35c30dda19b28eb3f7e548efeaebbf54a52cc4b9df96d52026,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x86-mingw32 |checksum:44d3713d6ca0cd362ed7a346f46d509b34e13ebbe0ecdf1c958e0e5de616ee1b,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x86-solaris-2.11 |checksum:a2298e7c6e56f5a0c4b8c6595bd9526c5a3bb822d7056755d7c67fa1e1c48f67,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x86_64-darwin-13 |checksum:a53328c2807e5e553e30da97c8eb4d39a3be044a6f7fa27d0b54299b3e786dc0,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1-x86_64-linux |checksum:34b0ee1a6b81edd5dd8e9fa5354c57fec6d16bfa5d907e11afead52047efb293,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc1 |checksum:96e58bc0e06c6ffcf1839a4d5d09922ad98e6191d9168c551814f741c02106d6,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-java |checksum:04e9d1627be7ec8197fbf053a8851cb8b2685797b48ecdb74fdbd525f965e4aa,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x64-mingw32 |checksum:19c8570542380a6bb8261fa571c1e3451bdc8f1c85b248ceca7e7236fe0a7a35,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x86-linux |checksum:16d576d085e3d77bde6cd6775436b24bc55a3f9bf559d7ff9e845c90714561d6,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x86-mingw32 |checksum:59ab69299f738cf49314da32101a2fd0d463cac44f9d064324f7b39c8d88bffc,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x86-solaris-2.11 |checksum:57400a3ac9af3672a598f44d7a3fd1a46c2e163b4b6d000e77c9ed7f90dd5950,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x86_64-darwin-13 |checksum:180c14f41726ad0f010a1ba1549ca6aea22c5b86b24a225e4356dcf38ae4b438,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2-x86_64-linux |checksum:301360e797f023dd1dfabe4e90dcbaa86dece56f962c5fc0321647ed36ae5494,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2 |checksum:62bf001bc7537cf6e7fedd0375c02405fd1feb1b1c68617e2a43221cb2461038,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0-java |checksum:09512fe1643c3cbb3205687576c2789d5a1de36c3179ab86c605c3d31bd512b0,ruby:>= 1.9.3 +0.7.0-x64-mingw32 |checksum:1ef848f3b073ccb8e5c968dd68955762274e73b7479ec6d3a4d552431aed8e4e,ruby:>= 1.9.3 +0.7.0-x86-linux |checksum:57e474affd42696fc182c9fccb24beff148db314e710babde99d2810ab5454f2,ruby:>= 1.9.3 +0.7.0-x86-mingw32 |checksum:44ea4f2bd3122a3bf1056b53a76b34ecf8ade23ba964ac8e486cebe37e49f143,ruby:>= 1.9.3 +0.7.0-x86-solaris-2.11 |checksum:ca8d7e82bf3abc3d412c2204c1bdd9c23859ad8f9b362942f6a92544922e728c,ruby:>= 1.9.3 +0.7.0-x86_64-linux |checksum:1e0b0ab58d34fcb1d29c26ffe3c9dff4151ab1587cf82d0783946a2fd2ef325e,ruby:>= 1.9.3 +0.7.0 |checksum:a7e5ce31d89f1b9a3b3524e96cf9071733d34c384f64974376294ade762bdd79,ruby:>= 1.9.3 +0.7.1-java |checksum:7e06e02b2ba568b7490d95a91c1df54f5302c8902e3064049095aa477e88bcbe,ruby:>= 1.9.3 +0.7.1-x64-mingw32 ref:~> 1.0.5|checksum:85a8b47d0b355e7d1423bcd09847c44f269941dc60cb72fd24e4d670260172e3,ruby:>= 1.9.3 +0.7.1-x86-linux ref:~> 1.0.5|checksum:e422a45f7b7e19a8d3351fc49f7487aeeeae1649db849430a0264b6a1fe5212f,ruby:>= 1.9.3 +0.7.1-x86-mingw32 ref:~> 1.0.5|checksum:b8491c80b3ca0bcc19aa739aea82e63d00fa3d51c020135b9ae94e9795f86a2b,ruby:>= 1.9.3 +0.7.1-x86-solaris-2.11 ref:~> 1.0.5|checksum:23ed9ae61975380f31407d6420a4d6bf9b1082f4341046613e57b8aa91f199a0,ruby:>= 1.9.3 +0.7.1-x86_64-linux ref:~> 1.0.5|checksum:ab55ff661060639a0be1fa5029a3aec4f092b67560141de7b0be6a5a1bd25b60,ruby:>= 1.9.3 +0.7.1 ref:~> 1.0.5|checksum:8787bfb50a1fef69e8d7909dad67482e7a1d3633f5531e86ddf269279aa9fdf8,ruby:>= 1.9.3 +0.8.0.pre1-java |checksum:0b30f0dd7679336ceed25592e979476abe90c684b6f991d610462c845e351924,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.8.0.pre1 ref:>= 1.0.5&~> 1.0|checksum:4e3de0d59897024d79af0106e7f9ec9c0cde5337c5e15fcae0e7501fb1d1371e,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.8.0.pre2-java |checksum:25d98b5a891f1228b356ceb4630ed1f9b2bfc8b3a1fd35d3ae33012fdd55cd1a,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.8.0.pre2 ref:>= 1.0.5&~> 1.0|checksum:34954f5f33d878ea5513b9ac71f190546c23281704f3932bbb71615a8fd0ebb5,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.2-java |checksum:c1fdc2db8aba840fb76b7d76d0b5adf10060e729de9e1c347083275c8e9bcd72,ruby:>= 1.9.3 +0.7.2-x64-mingw32 ref:~> 1.0.5|checksum:ea49950f4b8e515c6776625bd1386e57a1556fb9e44268d4e1cbb7d54841d4e3,ruby:>= 1.9.3 +0.7.2-x86-linux ref:~> 1.0.5|checksum:ef59a92962cff8ba911ce4ccc70b0519ad5448653fa572f7e38524dad87bd0c8,ruby:>= 1.9.3 +0.7.2-x86-mingw32 ref:~> 1.0.5|checksum:db4e3645ea73c29422b5725607f2fe5bdecc4ccb025d7d38fdebb1bcdb4ed802,ruby:>= 1.9.3 +0.7.2-x86-solaris-2.11 ref:~> 1.0.5|checksum:d5af0bb288f97d41e9579c60a9f6645c7794f92bbb478f057984d0365a90d2b0,ruby:>= 1.9.3 +0.7.2-x86_64-linux ref:~> 1.0.5|checksum:cd3fe5e679280113d664f206fecb51655069a1d0a8ebff936ceed9908922c1e2,ruby:>= 1.9.3 +0.7.2 ref:~> 1.0.5|checksum:769ec7f4a3f4ca3bca48a0e3f02f280ea01bdc6d017c9fe5452461d5149670e2,ruby:>= 1.9.3 +0.8.0-java |checksum:d75b184cf8a0a6f3cd2326d76bf8a9b9d622021c0fd904d7fd36ff574da20a5e,ruby:>= 1.9.3 +0.8.0 ref:>= 1.0.5&~> 1.0|checksum:1da7e62e6853cafbc351280e8638110a7709d10350b7f3290d54a303d977e04d,ruby:>= 1.9.3 +0.9.0.pre2-java |checksum:8d0b278cfb18406058154e72ff49fa97216320e06d41d81c68a8d14b2ecd1779,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.9.0.pre2 |checksum:1b883698f3f94b0cbc33918aa686f032cb2628f50427a3d5dd4c5d065513e832,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.9.0.pre3 |checksum:214d77c83d9dda4c297af821ef543ef1600df180f3e9aab46ff98166b94ab2ef,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.9.0.pre3-java |checksum:b7c48e2d10a56c586463e2458ee5213f5320080c33143980af41360b543d4f78,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.9.0-java |checksum:d007330d979ef77add6f452c0a15c15d3b90a2d9e1ef527426feef53d5a22db1,ruby:>= 1.9.3 +0.9.0 |checksum:a88574aa86900dd2435396849c730ce04437304a1725f5f5d51dad0f65b78b9f,ruby:>= 1.9.3 +0.9.1-java |checksum:fed602fa5528dfebba70f2ce1661ff52897b16124c287a25f4dc6918dc0f0747,ruby:>= 1.9.3 +0.9.1 |checksum:13b66e5c57274693ec945db733208a919544be67b43db0a393e9d94964ecadf8,ruby:>= 1.9.3 +1.0.0.pre1-java |checksum:1f70ce3e6e9c8a55d36726757c2a16e28adb38a86a7d1ac9b9d0b24f8052d06c,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre1 |checksum:59664c2324ab4111518e326bc878b6eb0f0c5a51199838914168267e33d8147f,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre2 |checksum:2ed87a549ba37800e0e0b18f4c189e986fdcd69229bbeb08bcce7c16d1a07974,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre2-java |checksum:0c9956c0b5bbfc0c03d1663fe815b85f76667b8a3168648be2ea4b471e51dcf5,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre3 |checksum:8d7dc826bacb55f3218dafa41d1b6954bfc4662431b3f2586dd801284fe17da5,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre3-java |checksum:38d6bdd4b587cba4b230dfa4640f819d8c3982435a6e4e467dccd1c2ec8d80b3,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre4 |checksum:a62a8794f352a5f1cc10886f21feeab42b92986c1697ab85a36fa0a831bafe8a,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre4-java |checksum:a527c10e6657541c0b34be4eeac754aa9625d9e6bf5a9fadbd3aa2e1eea17c04,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.9.2 |checksum:de0ecd09a9133e9be1ad2934547e44075e0a68a515cda10dc0864a11fded9b7c,ruby:>= 1.9.3 +0.9.2-java |checksum:42985e8925aba0b4599b1c2a37008a73100041fa7fe00e72066b4f9f6c7fb274,ruby:>= 1.9.3 +1.0.0.pre5 |checksum:cf179a0ed3d05747fcadd83ffacac3f4d250ef7afb97bfb774f0537613c5fe4c,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0.pre5-java |checksum:509af3def4b0769ac3c5348a049fa0c4a3343b7036b44deff6e54d6f2194da70,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.0 |checksum:bba0491c25d791fa8ada675b8818f938f6f21e1b6feb9bedb720ed3f1d7b0d63,ruby:>= 1.9.3 +1.0.0-java |checksum:7c95f74662623b4cb582deb110180115fb290c4220b66fcda19f4922191ccb81,ruby:>= 1.9.3 +1.0.1 |checksum:565616a4e5551162cae01b71ea262afa354c5bd23dd300ff0ee060bd1ebf2f8e,ruby:>= 1.9.3 +1.0.1-java |checksum:a59dba6a9ad1fb0e0b73be6a803912d20407136135bfc97659e1eef41c3fd2ca,ruby:>= 1.9.3 +1.0.2 |checksum:5c4b4cce37fc538660fae3b9fb7b51a2bc443eda4c5394e51521527fb6d264cd,ruby:>= 1.9.3 +1.0.2-java |checksum:6496a7f5671ef84f386a45c623a5dc4fe1694e0042d0d720a6f4363dff342091,ruby:>= 1.9.3 +1.0.3.pre3 |checksum:ed6c87dad91a37649ed6d80d31b8747d2de90ca763ee2b0cec33960b512037fd,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.3.pre3-java |checksum:79a2f686973e1b514aff7be39539a18a4625f6355d7d696b31fb31f103ea681d,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.0.3 |checksum:f147ee7b088953d964f09b12c8c99cbed839426747dbbb22e48f16edf47a8dea,ruby:>= 1.9.3 +1.0.3-java |checksum:64cd678add8d7f9796afc88ea2abeead1f4eca845f6b9a19a7770dad41917f95,ruby:>= 1.9.3 +1.0.4 |checksum:ebd266064280cf52fab521ddd369d51a95f6aff664119e229b07101a6088f25c,ruby:>= 1.9.3 +1.0.4-java |checksum:2da72c7f85e5c258b1d9e203ddd008ac9ad8e6114c0c905047dbca5a810bd48e,ruby:>= 1.9.3 +1.0.5 |checksum:8ee1206d0145a51f9ebdf735e4b5d6a957e085323b9db32e9b04f557dcd774a0,ruby:>= 1.9.3 +1.0.5-java |checksum:8d6ebb7a4bf77d8735035979cae16198f6401ce238bb8c5f17bb3d3954f305df,ruby:>= 1.9.3 +1.1.0.pre1 |checksum:fa38d1b439fba3f177a07c24f44d77705a0734fd664a2bb98c34932e52dddeb5,ruby:>= 2.0.0,rubygems:> 1.3.1 +1.1.0.pre2 |checksum:0caaf89cebf881ec27d5b68c0cd9ab71e80b468b6221ea27c578d41239d7098d,ruby:>= 2.0.0,rubygems:> 1.3.1 +1.1.1 |checksum:20d27b2cdf1ede752c1db32b21c5f03b0552760dd5409e87c72128216913d9ae,ruby:>= 1.9.3 +1.1.2 |checksum:0c965ec7ae9f39ae65c4f58b2e5ddb2266bd5668a37457cf6ace8054167b552c,ruby:>= 1.9.3 +1.1.3 |checksum:6b4bf154eb36502635143198425c35fc3262b3c088d7df179704bb5beed409a3,ruby:>= 1.9.3 +1.1.4 |checksum:e12e6ab140d8d99c14763a605b9671a5e182d4bf6dc951d4cb5debe86eeaacc7,ruby:>= 1.9.3 +1.1.5 |checksum:5611d14d8699996b17f18e704f4257b73349efa2d9a75fee6566a0a387c807f4,ruby:>= 1.9.3 +1.1.6.pre1 |checksum:7b3cc5d61a10fbd779627cc61fb4ca5d8ce85380028cab3467f8137f8faab7f1,ruby:>= 1.9.3,rubygems:> 1.3.1 +1.1.6 |checksum:14da21d5cfe9ccb02e9359b01cb7291e0167ded0ec805d4f3a4b2b4ffa418324,ruby:>= 1.9.3 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-declarative b/bundler/spec/fixtures/rubygems_responses/info-declarative similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-declarative rename to bundler/spec/fixtures/rubygems_responses/info-declarative diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-declarative-option b/bundler/spec/fixtures/rubygems_responses/info-declarative-option similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-declarative-option rename to bundler/spec/fixtures/rubygems_responses/info-declarative-option diff --git a/bundler/spec/fixtures/rubygems_responses/info-descendants_tracker b/bundler/spec/fixtures/rubygems_responses/info-descendants_tracker new file mode 100644 index 00000000000..89a857c927e --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-descendants_tracker @@ -0,0 +1,5 @@ +--- +0.0.1 |checksum:fdfffd8345dc4ad36e2ae114822305e7a8397db92c8f6c76ec461341a94ea4da +0.0.2 |checksum:0310e88e0cb3d8d93928054ce9992f0a364ee76525766f8cb7e5a6f42aeb822a +0.0.3 |checksum:01d7079bc81d4743e138bf77a7cc1ece123834fa6883f4241646163401922920 +0.0.4 thread_safe:>= 0.3.1&~> 0.3|checksum:e9c41dd4cfbb85829a9301ea7e7c48c2a03b26f09319db230e6479ccdc780897 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-diff-lcs b/bundler/spec/fixtures/rubygems_responses/info-diff-lcs similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-diff-lcs rename to bundler/spec/fixtures/rubygems_responses/info-diff-lcs diff --git a/bundler/spec/fixtures/rubygems_responses/info-domain_name b/bundler/spec/fixtures/rubygems_responses/info-domain_name new file mode 100644 index 00000000000..14d7e0b670b --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-domain_name @@ -0,0 +1,40 @@ +--- +0.0.0 unf:~> 0.0.3|checksum:253ca514b3b28c93305000f91f549c5c4d273239400fc11ecccf78b392ce0502 +0.5.0 unf:~> 0.0.3|checksum:2e3db64381833d5584b2026c166de23c0f344fb4f09d109b1f97753e00fccfa2 +0.5.1 unf:~> 0.0.3|checksum:c2e5ab5fb04ccf73657389b74b2ce126b93d28b388acc1140116b82d7bc047d3 +0.5.2 unf:~> 0.0.3|checksum:1d67b8848bcd93f88e50beeccd66bac34ac62240683307577e902bbd6df7111d +0.5.3 unf:~> 0.0.3|checksum:78419503db6fa727c4731f7d3fc055a4f6fc40ad2339d135e3756fcbb8c4b25c +0.5.4 unf:~> 0.0.3|checksum:d0ad8f844c899afe0123f65ce6cb5b4153dd62675a5df6003070d39b13ba50a5 +0.5.5 unf:~> 0.0.3|checksum:0809e9372d9c56b9584ddc03d4088dc4cdeafe01c0416809ede0120618f64b7f +0.5.6 unf:~> 0.0.3|checksum:79a946a186063d0080505eea7a7f9712a67233a3e3fd6e500b3b3dfbf99513d9 +0.5.7 unf:~> 0.0.3|checksum:38e5e52136d4f69b6f8e342de82666596ae58dbdb59d48cf75e5ab1a77442d17 +0.5.8 unf:~> 0.0.3|checksum:cb5da047ea68af5c0b365e8b4b6e2e6d3b8d286b92eae5334016d784b3966ae7 +0.5.9 unf:< 1.0.0&>= 0.0.5|checksum:f0743caa39d4027f4104be1d676bb9d99c0bebcb261adb5f3ca95ba331ed0809 +0.5.10 unf:< 1.0.0&>= 0.0.5|checksum:948e447fd7e6284bbb520e7c421bd9695ccb4cf87802917d916741c50fb3ff6f +0.5.11 unf:< 1.0.0&>= 0.0.5|checksum:60ba79d2af9c47b3ef4f99199efbee188b869516363f29708805a9c4f4f99222 +0.5.12 unf:< 1.0.0&>= 0.0.5|checksum:a063d0429b0beef64d78f92059dc1be21abd713bdfc5449bcedd5de415cd94c4 +0.5.13 unf:< 1.0.0&>= 0.0.5|checksum:bbafaaf2d663a9985d99d7b35b92bd0dbff2bfa35e3e92c075ad2e2199daa754 +0.5.14 unf:< 1.0.0&>= 0.0.5|checksum:01cfd3317652336686f5133db10707658b163e873da16ce1dbb2935f27471ef2 +0.5.15 unf:< 1.0.0&>= 0.0.5|checksum:fb2ba4f2d9bb4cdc7b6eceaa1a793b65fc775b0ab94e2d2d8ae0645a22c0ff88 +0.5.16 unf:< 1.0.0&>= 0.0.5|checksum:ac0a58faac65a33dad514a4dc7ae40d0b7a391d99fdf96ca9f1b8f887a3f1011 +0.5.17 unf:< 1.0.0&>= 0.0.5|checksum:10905b25c882b2b3930047d56c7b398511ca054f2fe11ec9c0f349be5f6dcce7 +0.5.18 unf:< 1.0.0&>= 0.0.5|checksum:d8c4110c2bd2bb6f35e173147171aa2e8a0c8bf7eb249d6b0a47e5eea163e0c0 +0.5.19 unf:< 1.0.0&>= 0.0.5|checksum:8b2afa70da06e751790380a63073d639b71a1575c36dc62ea7fb614ddc9e47b7 +0.5.20 unf:< 1.0.0&>= 0.0.5|checksum:da6c0c1e1c98affb5607c6dbba3650db4eab44f775223c1293bda17027429a9e +0.5.21 unf:< 1.0.0&>= 0.0.5|checksum:d83a5b92ceee0349f0af446450cb9753b2192a2a2605fa52c5997d9feb13cbe7 +0.5.22 unf:< 1.0.0&>= 0.0.5|checksum:cb8bbf0f14f9fa97f0ae9de40fa785f3a6c0b26cdd903afef165af2821907364 +0.5.23 unf:< 1.0.0&>= 0.0.5|checksum:f1269404aa9611427e2733a75adcc0fc028a8143b7c9bdabbce58bad76a0b662 +0.5.24 unf:< 1.0.0&>= 0.0.5|checksum:8cbd6aea8859823f89aefeec49232e9d4377456fd42d08accfbc0cc6b32a55f6 +0.5.25 unf:< 1.0.0&>= 0.0.5|checksum:5b492888a095f2f00027a268932c93d0432bf8ada568a5c601ff53ce6a761b9b +0.5.20160128 unf:< 1.0.0&>= 0.0.5|checksum:72e9d1ed22af6157b5aa65532cff0cc588f924a97b84ac6e31291095be6d3174 +0.5.20160216 unf:< 1.0.0&>= 0.0.5|checksum:d9880da350cb447a05a2081d237dfbd1df3e0deb92b2fd795eb223e15b038c4f +0.5.20160309 unf:< 1.0.0&>= 0.0.5|checksum:51d7801d1dc076f29900243c305ebe50a2e30d6d16aca931a5ee8c2af5bf3bca +0.5.20160310 unf:< 1.0.0&>= 0.0.5|checksum:da5fa56840cc67d034435880ddfbdd17d765c53d2f049de8a610cfab7f39213c +0.5.20160615 unf:< 1.0.0&>= 0.0.5|checksum:afb018732f1d0b322b213413868cd21011dba62fd77b38ceba2e7a9ee67690b9 +0.5.20160826 unf:< 1.0.0&>= 0.0.5|checksum:bd177e0e1354fbb96fe66ad5330da417c202f88ee7368f3e2eabf642ee7ee765 +0.5.20161021 unf:< 1.0.0&>= 0.0.5|checksum:549ebe3f9ca703354f319c3733d46a926ef72c9654c769b325df40ff9f49acf8 +0.5.20161129 unf:< 1.0.0&>= 0.0.5|checksum:e8f92582942a41348f02eaa7cc061b9b9d54d81ff9251d1bc3f0cc499c78083f +0.5.20170223 unf:< 1.0.0&>= 0.0.5|checksum:faa895f66fe3c3f9cd9f77bbcc10f3a8456b85163e5480d1c64b804532fd6bad +0.5.20170404 unf:< 1.0.0&>= 0.0.5|checksum:6e8e5cf80b9fdfae3ef730e73a30bce5da0a1e4a70f6e0a0b8672a28a3471a8a +0.5.20180417 unf:< 1.0.0&>= 0.0.5|checksum:7b74d1fe58937c6021d210d123a8e880787a047dbc411cabd6475b6216a76d29 +0.5.20190701 unf:< 1.0.0&>= 0.0.5|checksum:000a600454cb4a344769b2f10b531765ea7bd3a304fe47ed12e5ca1eab969851 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-dummy-pkg-a b/bundler/spec/fixtures/rubygems_responses/info-dummy-pkg-a similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-dummy-pkg-a rename to bundler/spec/fixtures/rubygems_responses/info-dummy-pkg-a diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-dummy-pkg-b b/bundler/spec/fixtures/rubygems_responses/info-dummy-pkg-b similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-dummy-pkg-b rename to bundler/spec/fixtures/rubygems_responses/info-dummy-pkg-b diff --git a/bundler/spec/fixtures/rubygems_responses/info-elasticsearch b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch new file mode 100644 index 00000000000..95c2694029b --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch @@ -0,0 +1,79 @@ +--- +0.0.2 elasticsearch-api:= 0.0.2,elasticsearch-transport:= 0.0.2|checksum:70b7ce9a18d1b4e0dac58a356db93b14338b5ff2b62eaacd6595f09319afc748 +0.4.0 elasticsearch-api:= 0.4.0,elasticsearch-transport:= 0.4.0|checksum:efb569b0a166a28976f74170e83aca25a478950e546bdd790f5d7496798b4e53 +0.4.1 elasticsearch-api:= 0.4.1,elasticsearch-transport:= 0.4.1|checksum:baf9ba8d7d62a283a8d603a63a45ef7f07bcba95137394b46b7903f4bfa042d7 +0.4.2 elasticsearch-api:= 0.4.1,elasticsearch-transport:= 0.4.1|checksum:82eaaef9be3ef005ab3c4e7839f0ca5bc4d2a6cfd5d79e93da1dc5cb98aa12ef +0.4.3 elasticsearch-api:= 0.4.3,elasticsearch-transport:= 0.4.3|checksum:856b2cb8a2b5a5c69d44a43c7716cff630a42c942f8bcc428d47ee9709b1ede7 +0.4.4 elasticsearch-api:= 0.4.4,elasticsearch-transport:= 0.4.4|checksum:86c2c6340cf60dbba73fc686b5669dc032798e7deb610ba825dfcabbc51d6b8d +0.4.5 elasticsearch-api:= 0.4.5,elasticsearch-transport:= 0.4.5|checksum:b98e99026806670c20f357a04ad3f15c67b3e43999b7ec9a64ae41be43a1792e +0.4.6 elasticsearch-api:= 0.4.6,elasticsearch-transport:= 0.4.6|checksum:5bbf979a0656db6bbb4f9f96c0d9f181e6b92c79e2670b5d7be916f255e1b380 +0.4.7 elasticsearch-api:= 0.4.7,elasticsearch-transport:= 0.4.7|checksum:025604520aec3922105aebc5025e5ab05602ea91ddc18aadb95526182f9b2a33 +0.4.8 elasticsearch-api:= 0.4.8,elasticsearch-transport:= 0.4.8|checksum:4681cab9e8918c19eebf472f105c74e96797437ea29737c7352cceda09bc5864 +1.0.0.rc1 elasticsearch-api:= 1.0.0.rc1,elasticsearch-transport:= 1.0.0.rc1|checksum:bc26a4ee9b6d30fa6bb2dcc53f18d0e49592e3cf35d5e6f106215d93f3a84202,rubygems:> 1.3.1 +1.0.0.rc2 elasticsearch-api:= 1.0.0.rc2,elasticsearch-transport:= 1.0.0.rc2|checksum:589697242866090b16ba3f8b05ae381ce8f8d9928b803f4e0bd4df59aefbcd71,rubygems:> 1.3.1 +0.4.9 elasticsearch-api:= 0.4.9,elasticsearch-transport:= 0.4.9|checksum:45ddfd1e0dd310b09eaa61afb62a6ab7b223f269f325672c5eb31ec74757dc45 +0.4.10 elasticsearch-api:= 0.4.10,elasticsearch-transport:= 0.4.10|checksum:708a9fdce5147aee7a37fcfa1c35052601f549394c45f69e16ee4ca8698a724e +0.4.11 elasticsearch-api:= 0.4.11,elasticsearch-transport:= 0.4.11|checksum:3daaaae1c52a60a3305c7a7557c0d6e42ecff037b8869d5e81b818a573ab67b0 +1.0.0 elasticsearch-api:= 1.0.0,elasticsearch-transport:= 1.0.0|checksum:e868765f25cfcb3d2b62089ae43706afc0cb92924b12f2a5e88ebbb962ff6f9a +1.0.1 elasticsearch-api:= 1.0.1,elasticsearch-transport:= 1.0.1|checksum:5487583f1963ebada7f4e1d41f2617b828b56af97b65530af6994627b320ef87 +1.0.2 elasticsearch-api:= 1.0.2,elasticsearch-transport:= 1.0.2|checksum:a6d137e779c04b92e2dab40e30f2dc3a6ef0d5743e161c3228a9e015a3d7e203 +1.0.3 elasticsearch-api:= 1.0.2,elasticsearch-transport:= 1.0.2|checksum:e6927f09fb04c92c4ff161c3785c484fb17fbdf51004b15cd475a365943a1a20 +1.0.4 elasticsearch-api:= 1.0.4,elasticsearch-transport:= 1.0.4|checksum:de01ce960f5b51b1be7a375f1a0d9bdc3d7d44a6a0249f5c1cb903622d02236d +1.0.5 elasticsearch-api:= 1.0.5,elasticsearch-transport:= 1.0.5|checksum:95e3e04f297d4718046b73e36c5fd254ff3edefe2e258352e94014fb7c60e7f5 +1.0.6 elasticsearch-api:= 1.0.6,elasticsearch-transport:= 1.0.6|checksum:00505ded9ae5b8c1df30604812afe4396e64c3716ce69a636119cde74cb35542 +1.0.7 elasticsearch-api:= 1.0.6,elasticsearch-transport:= 1.0.6|checksum:b06aaf3c4aec178d98bd2bdbffc92dfd2cc39ab63e573889a6a6f2f50c555763 +1.0.8 elasticsearch-api:= 1.0.7,elasticsearch-transport:= 1.0.7|checksum:14aa51d9145e0a1dd44ac843789620fef173b8cfc428d01e86eca17493fad14d +1.0.9 elasticsearch-api:= 1.0.9,elasticsearch-transport:= 1.0.9|checksum:86cc7aad5880224bc8b2d64eb3dbc3380d360ec23ea66c09a65262ce4974d92b +1.0.10 elasticsearch-api:= 1.0.10,elasticsearch-transport:= 1.0.10|checksum:2076dbfe2f717614dc450cb09abd2db964888c423d2f27e0469eb30b0a68e084 +1.0.11 elasticsearch-api:= 1.0.11,elasticsearch-transport:= 1.0.11|checksum:468442417d1e4c1ab500b79f466338dbd658ffb3d99c09fe2aa403f66bdfd9e5 +1.0.12 elasticsearch-api:= 1.0.12,elasticsearch-transport:= 1.0.12|checksum:a0c6386797fd2809c0cd03150e82f50fad9bc60f690decdd945b8a6cc48807aa +1.0.13 elasticsearch-api:= 1.0.13,elasticsearch-transport:= 1.0.13|checksum:dfff648b01024c4a70a1ae991eab0671d82bfdc48181ca2c30f4099ce608a0bd +1.0.14 elasticsearch-api:= 1.0.14,elasticsearch-transport:= 1.0.14|checksum:38463d314b467cb46e80b59511e3e4e35ab1ff9a6143f4b8536914a798770fa1 +1.0.15 elasticsearch-api:= 1.0.15,elasticsearch-transport:= 1.0.15|checksum:9e0b3c4496f5b394b869b0b9c37b16e8d231379a6c85632940fad2d8011afc87 +1.0.16.pre elasticsearch-api:= 1.0.16.pre,elasticsearch-transport:= 1.0.16.pre|checksum:547003baebd1ccb947e88360eff1dfd0d1f994ad9893a8e1393cff37a126a84b,rubygems:> 1.3.1 +1.0.16.pre2 elasticsearch-api:= 1.0.16.pre2,elasticsearch-transport:= 1.0.16.pre2|checksum:fef733867b7fc827f58c3987c34f068148d7addf5c937bcd10b953713ad8715c,rubygems:> 1.3.1 +1.0.16 elasticsearch-api:= 1.0.16,elasticsearch-transport:= 1.0.16|checksum:749a5910779bf2bb946858f1298a58a17b39ae0fc3437991fca0b03c0eff13a3 +1.0.17 elasticsearch-api:= 1.0.17,elasticsearch-transport:= 1.0.17|checksum:851be34a15c8fa5e4f38e94bba73266cfe343c557ab99c6be1c850934657fbbc +1.0.18 elasticsearch-api:= 1.0.18,elasticsearch-transport:= 1.0.18|checksum:80c2105610b215807bacf02a0ec4f91e3ab851b65bf973a73a952c53e209bef1 +1.1.pre elasticsearch-api:= 1.1.pre,elasticsearch-transport:= 1.1.pre|checksum:84b4017e3015c3e8824fbfb9550eb45bd8cc04b532d4f094ca7beba3e6712f91,rubygems:> 1.3.1 +2.0.0.pre elasticsearch-api:= 2.0.0.pre,elasticsearch-transport:= 2.0.0.pre|checksum:dca5193227d21ee6a562985ff81b0c1f55f0bb15440a4f4ae98e18c3720374e5,rubygems:> 1.3.1 +1.1.0 elasticsearch-api:= 1.1.0,elasticsearch-transport:= 1.1.0|checksum:bd62d4dfec720a0efeb10e9ddcaf71881c068bfe90c1b08086d73736f3d4da08 +2.0.0 elasticsearch-api:= 2.0.0,elasticsearch-transport:= 2.0.0|checksum:d0a8a4fa94d6a86ef264fd1709c062fc3c483c527ab3a51dfb520595c55d906c +5.0.0.pre elasticsearch-api:= 5.0.0.pre,elasticsearch-transport:= 5.0.0.pre|checksum:8ac6eb042e27bea27803a5d55bb03027e393e1ba829d1a95ba517306f22f9bda,rubygems:> 1.3.1 +5.0.0 elasticsearch-api:= 5.0.0,elasticsearch-transport:= 5.0.0|checksum:58f3b30717681c4132cf198c209cab44c23ca9966d0127a061c7872a8e2c5b0b +1.1.2 elasticsearch-api:= 1.1.2,elasticsearch-transport:= 1.1.2|checksum:0c5eb48e63cb2d7b3192665e1015ea22759a34afa7b03b263895e2bdea3123ac +2.0.1 elasticsearch-api:= 2.0.1,elasticsearch-transport:= 2.0.1|checksum:5f6afcface9a8f575b14866b0fc786a26046655a08194f41e64838fc98ae3819 +5.0.1 elasticsearch-api:= 5.0.1,elasticsearch-transport:= 5.0.1|checksum:3383d8d240646c8a16eb5ff06a3c4a44c8be564741a426786b602f1fba582e1b +5.0.2 elasticsearch-api:= 5.0.2,elasticsearch-transport:= 5.0.2|checksum:f54a1e684b3f97608edb3bcd00571f8bace9b3e065ebaa50ebcd965d638c6371 +5.0.3 elasticsearch-api:= 5.0.3,elasticsearch-transport:= 5.0.3|checksum:443d424d6b3a3b5cad5e3bb3a95fa83ab80becf39944de83ff4844dfb325333a +2.0.2 elasticsearch-api:= 2.0.2,elasticsearch-transport:= 2.0.2|checksum:f03defe73766f05028553f0ad2585c20d70db15ad7d8f95c8a49073c40b65642 +5.0.4 elasticsearch-api:= 5.0.4,elasticsearch-transport:= 5.0.4|checksum:9188dede93d5f2f485365937986d483bcb300344707159413e121aed2119feca +1.1.3 elasticsearch-api:= 1.1.3,elasticsearch-transport:= 1.1.3|checksum:5b3258746f3ee393873ab3e36a20f907d69eaaac9ad05a8563ed7e507f50b7d6 +6.0.0 elasticsearch-api:= 6.0.0,elasticsearch-transport:= 6.0.0|checksum:4a44b82fc6f17e605fb11ae2778e37e1c45d5485df36c8a5b47cf938c5204a96 +6.0.1 elasticsearch-api:= 6.0.1,elasticsearch-transport:= 6.0.1|checksum:39a37616d17bb6123f4180a3c3107ffa2ee1fbfb74b5a038ff30e503013ec484,ruby:>= 1.9 +6.0.2 elasticsearch-api:= 6.0.2,elasticsearch-transport:= 6.0.2|checksum:48c2df7e730dc689872663a9e0454dea45457696efe26645759495dfb7f50828,ruby:>= 1.9 +5.0.5 elasticsearch-api:= 5.0.5,elasticsearch-transport:= 5.0.5|checksum:15efc3d416092ba306904b048920545b00b8e2f7400f2e7fe890e51fd17619e1 +6.0.3 elasticsearch-api:= 6.0.3,elasticsearch-transport:= 6.0.3|checksum:be32aba9307c85c7ae01dae5332b9e8b9b2d18dc806c3f9aee8b969b1f5ac198,ruby:>= 1.9 +6.1.0 elasticsearch-api:= 6.1.0,elasticsearch-transport:= 6.1.0|checksum:e9d23df1c29e529042119d7102429df09f195b94c60731551efc68a9a23a4a98,ruby:>= 1.9 +6.2.0 elasticsearch-api:= 6.2.0,elasticsearch-transport:= 6.2.0|checksum:916db1ffaf09dbfce0f9cafce0e5453c0c4aa8b3abf49729c411fd3d6a412761,ruby:>= 1.9 +6.3.0 elasticsearch-api:= 6.3.0,elasticsearch-transport:= 6.3.0|checksum:16fb0d6404bcca967b372eb4dd710afb56593547d0a0faf873b9da06121fa1cf,ruby:>= 1.9 +7.0.0.pre elasticsearch-api:= 7.0.0.pre,elasticsearch-transport:= 7.0.0.pre|checksum:8fbf4e2ba0c97d9dbf51dad7d01dcc8835023785fd94c09ac42f0b9787dbfcf2,ruby:>= 1.9,rubygems:> 1.3.1 +7.0.0 elasticsearch-api:= 7.0.0,elasticsearch-transport:= 7.0.0|checksum:e82fa0eabf775d8e83a88e6d17b36cbd125d97a1f7a268eecd30e2c53eab4c2b,ruby:>= 1.9 +6.3.1 elasticsearch-api:= 6.3.1,elasticsearch-transport:= 6.3.1|checksum:a354c6faaccd37d901a013545f72d18447e9844ad70318e65ffdf002f33bc752,ruby:>= 1.9 +6.8.0 elasticsearch-api:= 6.8.0,elasticsearch-transport:= 6.8.0|checksum:00bf8a12ef595d1246da7edd6e9ab8caad09e76f3f7bc0c7530d85495755e7ca,ruby:>= 1.9 +7.1.0 elasticsearch-api:= 7.1.0,elasticsearch-transport:= 7.1.0|checksum:097260d225ef06d90f2ebd49522537c572b76297b58af222e35084e7ab8defca,ruby:>= 1.9 +7.2.0 elasticsearch-api:= 7.2.0,elasticsearch-transport:= 7.2.0|checksum:31e002f26e7f02f4c0942240e2c29ea73bb5c66bb51a564dec5d3748d2b87281,ruby:>= 1.9 +7.2.1 elasticsearch-api:= 7.2.1,elasticsearch-transport:= 7.2.1|checksum:c86027dabebba7e18142866a300c5d8e05ea6973ac9782c08dcdbf281f5500a0,ruby:>= 1.9 +7.3.0 elasticsearch-api:= 7.3.0,elasticsearch-transport:= 7.3.0|checksum:305c37aecc660040f0d8e2f5efdfcb72215bdab8e125cdcfa40bbd27a7be8f64,ruby:>= 1.9 +7.4.0 elasticsearch-api:= 7.4.0,elasticsearch-transport:= 7.4.0|checksum:ae105056c10721ff1e4e2a3d4c7af26018bf389148e99a4afed68c166d661ace,ruby:>= 1.9 +6.8.1 elasticsearch-api:= 6.8.1,elasticsearch-transport:= 6.8.1|checksum:befbed0d33a6cced936d8762fe1aff1322b881a3bf4967d3166ccb7e35662d39,ruby:>= 1.9 +7.5.0.pre.pre elasticsearch-api:= 7.5.0.pre.pre,elasticsearch-transport:= 7.5.0.pre.pre|checksum:2ce160a63ec5adce0fd2d67ae9f2d07425fb451a2222a591f2b5bed59d9015e8,ruby:>= 1.9,rubygems:> 1.3.1 +7.5.0 elasticsearch-api:= 7.5.0,elasticsearch-transport:= 7.5.0|checksum:44774def0375f0946767ae3e599592a859558c78c5eaeabef8737393d587e892,ruby:>= 1.9 +7.6.0.pre elasticsearch-api:= 7.6.0.pre,elasticsearch-transport:= 7.6.0.pre|checksum:0751a34a270b16800a515482c536e6da00aacc6e0821cfe638762d4e14f3da04,ruby:>= 2.4,rubygems:> 1.3.1 +7.6.0 elasticsearch-api:= 7.6.0,elasticsearch-transport:= 7.6.0|checksum:2c3ad99561d15bd7a5e9d60ede5a9535c3bcfba78d113c57fb6279786d65e5b7,ruby:>= 2.4 +7.7.0.pre elasticsearch-api:= 7.7.0.pre,elasticsearch-transport:= 7.7.0.pre|checksum:aef6de72240f3e83e6bf1b2a88d0982ffa98c8de39e21e75bdde3fc7dc8f7fee,ruby:>= 2.4,rubygems:> 1.3.1 +6.8.2 elasticsearch-api:= 6.8.2,elasticsearch-transport:= 6.8.2|checksum:6ea83d0601ba30ddaa312e4693339f6c361f2ef086a1ba3256be7a71b5395f94,ruby:>= 2.4 +7.7.0 elasticsearch-api:= 7.7.0,elasticsearch-transport:= 7.7.0|checksum:e9cc8e7f279496c0b08eb356966babc1adf3a38209aea4faa6a5932269e2ffaa,ruby:>= 2.4 +7.8.0.pre elasticsearch-api:= 7.8.0.pre,elasticsearch-transport:= 7.8.0.pre|checksum:e17d5ed628329de0d964b90a64e14a935e09ca337ff73903d060bd8407d9d85d,ruby:>= 2.4,rubygems:> 1.3.1 +7.8.0 elasticsearch-api:= 7.8.0,elasticsearch-transport:= 7.8.0|checksum:5c13f90d22bcaeb9ea2b87eed564fe4fc97113edf83361aa6494b75cae131756,ruby:>= 2.4 +7.9.0.pre elasticsearch-api:= 7.9.0.pre,elasticsearch-transport:= 7.9.0.pre|checksum:b1dce484e826de7cf91f5090d07d4dff86022af5a0fd7512d53b2feeb7a65db1,ruby:>= 2.4,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-api b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-api new file mode 100644 index 00000000000..cc08bac462f --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-api @@ -0,0 +1,78 @@ +--- +0.0.2 multi_json:>= 0|checksum:50509415973c517db9d650cbc06a02d2d072fd1e929313af17b35bf681c1b6e2 +0.4.0 multi_json:>= 0|checksum:9019c24a306cc3fc4c49d2d2fe26dad727f227bcb8c7996a578a3d66706f051f +0.4.1 multi_json:>= 0|checksum:a1e26c469d7618b2e6e2d329ee06b54a480884a20069c1d0df4c8585b2709331 +0.4.2 multi_json:>= 0|checksum:70f05785bde4f9c3ae113e04ac44a52946373a4daabab87bfb61abebc3ae75f0 +0.4.3 multi_json:>= 0|checksum:c23f2f1bbebf1e0f325262a51b7a14f153fa5b7f6e59784c8e2cdc6370549653 +0.4.4 multi_json:>= 0|checksum:5dbfe5245b4e64ba86e160d14ad2607afeffe448b609f782038f949cd42b9995 +0.4.5 multi_json:>= 0|checksum:6c6bfbb102035afadcebfefac34cd315b54388a8d54ae53f36620c92d56c7de5 +0.4.6 multi_json:>= 0|checksum:24334fdf6f999f0e63c960ad675f5a4e234c701d1d9f7675bbd221a06964620d +0.4.7 multi_json:>= 0|checksum:9dacdc02d1ced8dbec4e1f3dc2d837207325db718283581b473a4ea5253d9844 +0.4.8 multi_json:>= 0|checksum:30915d90506d1f29008f643385a9eb6ee563b3d7c429cef36bb1b205d87556f3 +1.0.0.rc1 multi_json:>= 0|checksum:cfda93de101ff2d9a6a9804188ef6df9198264bdde9e6f6f91e9ba268b01e1ba,rubygems:> 1.3.1 +1.0.0.rc2 multi_json:>= 0|checksum:63f2078845a6f6f34a11a51ddb27896671555c0677e1832c82d6da19d7308c92,rubygems:> 1.3.1 +0.4.9 multi_json:>= 0|checksum:5459ea1b1a206b0812dcfc4bad2a4b6b3f52c230f79ef7b48e9f689df88fe12a +0.4.10 multi_json:>= 0|checksum:5808b17d101d525c9e8d788f9cd378c8c296148f8265ecbd558b2e4c31a1a1a5 +0.4.11 multi_json:>= 0|checksum:b95438ce8b02a785819d509065d74b6819aaa7a0a1e64f740bbb240ca0cb0f18 +1.0.0 multi_json:>= 0|checksum:f2e5ab456d3ed91b21b666144b9723ec4a6e6134e75d07461f26ce339e783100 +1.0.1 multi_json:>= 0|checksum:9fdebcb47af5d31785cc9b0eae270c26c5547daa14ef720a4a7d23e78ce0851b +1.0.2 multi_json:>= 0|checksum:e65a733b101c9b352898a440c5ea45a2ccc86e0d4672d49e49168b130309a969 +1.0.4 multi_json:>= 0|checksum:f71722ce1c4d6f087fb3476bb005c2ad7e6109ce6e0a71c8ada052e12d57c604 +1.0.5 multi_json:>= 0|checksum:6583ee58493203c3e6c95fef342dc60f9ed3a6944a34ecb5346aacbe836f7294 +1.0.6 multi_json:>= 0|checksum:286b144cbaeab870ed02ccca8b4e78f225f97bcb7a7e115092d827803c2c60db +1.0.7 multi_json:>= 0|checksum:6932c363f8d4f51c9c279775a2f7c663bfd083615e8dbe66ff8850077fbd6739 +1.0.9 multi_json:>= 0|checksum:d1ec50dc62c2f5f6af51a4cabc740ea7a17cf022e9b763611ada8c1c56296098 +1.0.10 multi_json:>= 0|checksum:e0a22965376c60d9a9099a756d3db1108808d0c86d00fcaa94e28211e26859c4 +1.0.11 multi_json:>= 0|checksum:98f1637686c2ee3f23ae485cd510ebf12a43e03caec400fa7d26b063085235f4 +1.0.12 multi_json:>= 0|checksum:f51e5ce2213d34dc3a5862e484cfb13312a8b26a8d5c065c53693cc2b9c8e6fd +1.0.13 multi_json:>= 0|checksum:8b810579ad7183df6d1b9a261cf5f384fe75705421707f2aca29b3d5c9434548 +1.0.14 multi_json:>= 0|checksum:397ffb640c73961422bf4b288fe65a2b6ff405080cad42a07c88363822b09ab2 +1.0.15 multi_json:>= 0|checksum:5be054696fdc7affb6cbf2a3a73f23f7772b2fe593dfa9a7e181b8eab1333a2b +1.0.16.pre multi_json:>= 0|checksum:8649bede3250cdc9de92f226792ff5f9bb1fd1a4bd2f751358256f6d89df52c5,rubygems:> 1.3.1 +1.0.16.pre2 multi_json:>= 0|checksum:82d9b115cf042237afa5be5eaaac9d8e9fd3478ba07b0bef9fae9654f370cb06,rubygems:> 1.3.1 +1.0.16 multi_json:>= 0|checksum:deb6d4c41c059db7bf587eb48ea576996e3860a301aaff448f38c31196575cc6 +1.0.17 multi_json:>= 0|checksum:5d1ec4e2c4e4d5b482aeb2facceb562fe7ad276192cb787575018daff2306b21 +1.0.18 multi_json:>= 0|checksum:baf0003137975ec218d25540344e4feb030dcff8962c72c7642a972fd558d6ec +1.1.pre multi_json:>= 0|checksum:5b2e6372a2f63b4efc8233586315711dd65503407a57863f9da50b889ef7d5fc,rubygems:> 1.3.1 +2.0.0.pre multi_json:>= 0|checksum:8fce5e7c8f8f794c207e2fe996c991b82c6d7cffd8a80c7e39eb7f20fb117eb8,rubygems:> 1.3.1 +1.1.0 multi_json:>= 0|checksum:1aefc144ae0a3d23cdbcabbd38a0ec5d089cafd6ca786469e85cda32569a4d93 +2.0.0 multi_json:>= 0|checksum:49785e1ff754a49281bdacca933862139ccd2a8bef2c6a6f9965d65cea587731 +5.0.0.pre multi_json:>= 0|checksum:3761c66e6bdcc37e66efd61bc8e3da35b57274108d1b8ab73cdda0230df3315d,rubygems:> 1.3.1 +5.0.0 multi_json:>= 0|checksum:96bc01f15d0303516d6da2a1536736b8d239e01603798e90c997c4a32f3fa774 +1.1.1 multi_json:>= 0|checksum:a18d50e4aa3054c025335075ddc877aa8fb6747edd916959ad85cd99d99acc3b +1.1.2 multi_json:>= 0|checksum:49813a1e758da12cdac5a4aef1b005b482e6a241b473ac56cf0a15f8df3a3713 +2.0.1 multi_json:>= 0|checksum:cf5fb0ae875ea9ff87d03cba8603fee0bbb28c06717be0a37813aa98aebb5f0e +5.0.1 multi_json:>= 0|checksum:dae7d32b83eb75373bbefbb24979fc083ad19d1493516da0833d554aac2a2861 +5.0.2 multi_json:>= 0|checksum:5eb9bd5e5c2f6fa964d13bbee5ce7e2166410163bc30826b28962319205f94a2 +5.0.3 multi_json:>= 0|checksum:bc9ab073a2610159f1ec92aca67db93a3c2236134f09caf42c34150c91085429 +2.0.2 multi_json:>= 0|checksum:8ada5ddd89f7496451e8a694b2d3203baf308c4deeb2421f353c520a561992cf +5.0.4 multi_json:>= 0|checksum:5578cc06f2713082e2b9b191de29bae4cf9da606c3d3208b02ff587782216afe +1.1.3 multi_json:>= 0|checksum:e3d6ceb782eedf4234140565a2f66446a55e8f3a3f1d761ee572e21f2013ee75 +6.0.0 multi_json:>= 0|checksum:985409bbd83f990e36e7a926bd883a0f733df598ff0dee08d8e5b141d0c9d471 +6.0.1 multi_json:>= 0|checksum:898fb5a4ad297c3171c9b4d7db95fe1a9222af53922dca3a67b797bc5a188ccc,ruby:>= 1.9 +6.0.2 multi_json:>= 0|checksum:b0b4fff08adb808e1e8b44940618a02ab67d879308fe1732dfbb208bed846aee,ruby:>= 1.9 +5.0.5 multi_json:>= 0|checksum:34a94708f0923b3fd2138ca45519328408b88d740bcb715e36dca46ee8706138 +6.0.3 multi_json:>= 0|checksum:80e65abd135ee15f48f64715d5c6c0b3b11231c035e6491ed719b206ec0dc51e,ruby:>= 1.9 +6.1.0 multi_json:>= 0|checksum:c70609c4d29812fd32cbd162add2e8ba2f2f650563f78f4c8ecc50172f843a61,ruby:>= 1.9 +6.2.0 multi_json:>= 0|checksum:d4b009c86e39e32012450cb0d5e8b02db2caa82c306c2ce868e53d49127db827,ruby:>= 1.9 +6.3.0 multi_json:>= 0|checksum:75e9695858d68e5ec1b6e701e2dfd93488d2c2c28cbb1709681842654188b219,ruby:>= 1.9 +7.0.0.pre multi_json:>= 0|checksum:bad6f64cada9130f9b18e62e5b54379494d891d465c3344cbec6ff46c31ae70e,ruby:>= 1.9,rubygems:> 1.3.1 +7.0.0 multi_json:>= 0|checksum:1dafe08021c4cb4ab8e712040f16ecdd87b9f8403fe77c7bd1b89b9406b331c0,ruby:>= 1.9 +6.3.1 multi_json:>= 0|checksum:11f221d2a68ececb8befba31e6b4793b4bf86e64359e303a486e6fd127ad5f0c,ruby:>= 1.9 +6.8.0 multi_json:>= 0|checksum:8a3df53d0f506e27d7c0b9a8ad4ec0654eb888f376d9afa413cd96a6b5a4064f,ruby:>= 1.9 +7.1.0 multi_json:>= 0|checksum:6bee08639b146b95cbe0b5698556d42bcf4e73d855db8fb5a666a8839a99ed8b,ruby:>= 1.9 +7.2.0 multi_json:>= 0|checksum:015d115000d93bf7eeeba61458d0178060229dd553eefb61f02749d63904e967,ruby:>= 1.9 +7.2.1 multi_json:>= 0|checksum:bfca9350c1c1c437cfcf33b49d5c065df3fe5b9e92c76fec8128cbb67b372da3,ruby:>= 1.9 +7.3.0 multi_json:>= 0|checksum:7f197c3c96abeedb026633d40bedf4099237296723d0a86239696f4ffd00cdcb,ruby:>= 1.9 +7.4.0 multi_json:>= 0|checksum:ec821fe93963d0e6a101ec2813846d78ed2b860485817cd3674c5d003270085f,ruby:>= 1.9 +6.8.1 multi_json:>= 0|checksum:1b21a0db008e6b3fbaf7d0fbe98bb07b2350e0d3a99bb1bab5a1067e6e0faf4c,ruby:>= 1.9 +7.5.0.pre.pre multi_json:>= 0|checksum:5253ca45a68160b589b56535902b36f32014a1f21f24fd59deef3ba0831224ba,ruby:>= 1.9,rubygems:> 1.3.1 +7.5.0 multi_json:>= 0|checksum:98916401e0e8c7f1fec9a5ecc68537dd2b5ebe0b790d3edea69a5c0765f21569,ruby:>= 1.9 +7.6.0.pre multi_json:>= 0|checksum:c032595de358dc9bcd150071b11b597baa5c9d4d2eeb95ad576161767a9c2f48,ruby:>= 2.4,rubygems:> 1.3.1 +7.6.0 multi_json:>= 0|checksum:f8efa22e12d440fff4d7c2a281b781734a0fc368105f39479ddf90ca10fd0b97,ruby:>= 2.4 +7.7.0.pre multi_json:>= 0|checksum:1f3d964d5c3207bb33a9524410c50b68f8827f47a37bc838688da32ba769a973,ruby:>= 2.4,rubygems:> 1.3.1 +6.8.2 multi_json:>= 0|checksum:17f550fd2d331c59911072d37d53a616bca37f51772f90b49cfb6a6cab72328b,ruby:>= 2.4 +7.7.0 multi_json:>= 0|checksum:5bc46fba4901c61a48f2ae76b90b5e70f3259466952c25360e44b3531b03210e,ruby:>= 2.4 +7.8.0.pre multi_json:>= 0|checksum:372326356313f57c31c1ede094e7828b86c46f074ebaa30fb7cc8db044c584d7,ruby:>= 2.4,rubygems:> 1.3.1 +7.8.0 multi_json:>= 0|checksum:17c8276a97c4f2efac67fadfa8965eb0e51c65ffba02f3feff11768abd320e8d,ruby:>= 2.4 +7.9.0.pre multi_json:>= 0|checksum:e2dc5f7d5f7c686e5bb8ffd3284b53b5589930069ff83afe79e92cad67176c32,ruby:>= 2.4,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-transport b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-transport new file mode 100644 index 00000000000..a077248cf05 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-elasticsearch-transport @@ -0,0 +1,77 @@ +--- +0.0.2 faraday:>= 0,multi_json:>= 0|checksum:abc2fda1c940f39a57f6d975fde976f6c530b2f3d9976a375555158cb8b1dc68 +0.4.0 faraday:>= 0,multi_json:>= 0|checksum:538ed0e102cad3c58162da97fba5f5c9e98f22c5ef11a57adece88fffadebfce +0.4.1 faraday:>= 0,multi_json:>= 0|checksum:49a97bb359392dd62c6bdf3b07a5a043e735d8440ce8f1868e0da364ddf8bf2f +0.4.2 faraday:>= 0,multi_json:>= 0|checksum:6cd807d965935602ef27052d3d5461e46b45400ded96ec7c95e92b0dff393126 +0.4.3 faraday:>= 0,multi_json:>= 0|checksum:ed3d9768a14bbd9824c68fa36c8721d68fca1600f078176229fe399b403fa0b7 +0.4.4 faraday:>= 0,multi_json:>= 0|checksum:3261979cc540c38031704b1ae2d2b2c54896e0d9e365095b87f2ea8b74c3ac1e +0.4.5 faraday:>= 0,multi_json:>= 0|checksum:ae70cc166b13a613755d205439c19c8d996f167e5d08e30fe0d14431d1bd365b +0.4.6 faraday:>= 0,multi_json:>= 0|checksum:bb70738a2eeb546e459480806429cc8f7c7f23dd5a6a0a9b5f2614b84283ba1c +0.4.7 faraday:>= 0,multi_json:>= 0|checksum:603261a15def4a1b36f6072824184c34aaededd305a85710af6c902f15ff8341 +0.4.8 faraday:>= 0,multi_json:>= 0|checksum:82f5cff28cdc5d4693d6ae66906a20f64dad934c3ca6299784bc1fef3b015f08 +1.0.0.rc1 faraday:>= 0,multi_json:>= 0|checksum:8b60e095896ed4610a8964368460c0645c16c0f419dc1316f57f307930cdbcef,rubygems:> 1.3.1 +1.0.0.rc2 faraday:>= 0,multi_json:>= 0|checksum:35fac98b719c280be9c931eca02281bc03a4a4a427c53a6512537f09b8825114,rubygems:> 1.3.1 +0.4.9 faraday:>= 0,multi_json:>= 0|checksum:82f3d64540af40066e88458b2b412fc438803ae4fb36c5266fd14036802771e0 +0.4.10 faraday:>= 0,multi_json:>= 0|checksum:b25afeea80a6af5dfb40c8343bdf6177d8fb471d4977e2dcb48cfd4535b5daa6 +0.4.11 faraday:>= 0,multi_json:>= 0|checksum:01ac90305916c9e15e0f8c3b2b883c04a6e4bc0a8277f0924f7ffc1863a7e867 +1.0.0 faraday:>= 0,multi_json:>= 0|checksum:ec94be84a2963a3a2bc9d6e8e2c1c5e5487d6ee9934cf7dc0135e77fa24e2c59 +1.0.1 faraday:>= 0,multi_json:>= 0|checksum:543681c34097985736a6c7297136cfc4f3c22d63c5493de6d072c03fe412f163 +1.0.2 faraday:>= 0,multi_json:>= 0|checksum:d0f03ec4a5f23a6258032f921df125dba36796f92ba25fb633b41c010b85c1a0 +1.0.4 faraday:>= 0,multi_json:>= 0|checksum:cb3fc26956061de4fd806c73b74021bafc3daeafc05575673690b3d5d3b6c3b4 +1.0.5 faraday:>= 0,multi_json:>= 0|checksum:baa278f37f179f52367e7b94ccacb92d3ab119c9b6f315024e58d975556edff4 +1.0.6 faraday:>= 0,multi_json:>= 0|checksum:9581e329094ad55be4d5e0bc17b26a52d2f5d68a65ed38ac58d9207d4048d54e +1.0.7 faraday:>= 0,multi_json:>= 0|checksum:ec031badbb7da2021d3608f0dc0dd37a61c327c3cb45249d5604f1fbf6fabe5c +1.0.9 faraday:>= 0,multi_json:>= 0|checksum:c29a790e9f401640b9c5e1cecbf2d69c0ded195a1f9c1639d0eb525ce8ba5fbd +1.0.10 faraday:>= 0,multi_json:>= 0|checksum:a8cc38f12ed816617ecf5df2363e2d1a4f861bc4d33d0bdd2000bbbb34368c2c +1.0.11 faraday:>= 0,multi_json:>= 0|checksum:573d389f23fd28764f394e01d3a5b9bf626a27666c47df770788dd1477945e57 +1.0.12 faraday:>= 0,multi_json:>= 0|checksum:c7071b2a20ea3b189e5b26e04348ed392147c8a2c5cb1fba6f5d0b2ab4248f34 +1.0.13 faraday:>= 0,multi_json:>= 0|checksum:feb4fb0a77010ce98cfda52fd85047acc7c7fe1075583a8efa28d360979c0a15 +1.0.14 faraday:>= 0,multi_json:>= 0|checksum:ac1cd190faf3783619c19795ffab24ccd0369a07885e925d9841df96b6ba5e7d +1.0.15 faraday:>= 0,multi_json:>= 0|checksum:7ff056fd4ac49c2f464bb49d47f7d6b208e3af55b410ea33d09895a331126c93 +1.0.16.pre faraday:>= 0,multi_json:>= 0|checksum:e584b317f58f50fd37862c04b351916d21b6b83b5f89f33ebf87b15300c9286b,rubygems:> 1.3.1 +1.0.16.pre2 faraday:>= 0,multi_json:>= 0|checksum:a5677bf9ab10f87be841370db7948632688dcaf29296063bb6bd31965c1c27ae,rubygems:> 1.3.1 +1.0.16 faraday:>= 0,multi_json:>= 0|checksum:53625c7c74e4664ce514b61b0258eb8a815de03e40304b496fd1fbfee5228225 +1.0.17 faraday:>= 0,multi_json:>= 0|checksum:7f09b43dc0c87ecceac99923b68650af752b8b147a8ab9d41ff95b3a1e4a271f +1.0.18 faraday:>= 0,multi_json:>= 0|checksum:d16cce362378fa94080434944a3088b5661293ea5e157f8c7b30116cd1cfae6a +1.1.pre faraday:>= 0,multi_json:>= 0|checksum:c5344fcd54a24ebd169e63f0302ae4205f188bf03c4369e8c0f4c56402a24c43,rubygems:> 1.3.1 +2.0.0.pre faraday:>= 0,multi_json:>= 0,system_timer:>= 0|checksum:3c56cdb9228b5e82a86c65426c61f086fa3a51f2ec8022973566d6cd94e313c6,rubygems:> 1.3.1 +1.1.0 faraday:>= 0,multi_json:>= 0|checksum:4723e1ae94754eb91940c998853a24f9c6e6a506a0c145c1b97b0aacfbe99ab4 +2.0.0 faraday:>= 0,multi_json:>= 0|checksum:7cb649b8c65d26c218b21ed6ebc3a1cc3f0f6d822df5a1291426c2b5a6967eab +5.0.0.pre faraday:>= 0,multi_json:>= 0|checksum:9a9690396b6ae18f7811877d6a415db0fabefb91e2ad193018efe118f7468fe7,rubygems:> 1.3.1 +5.0.0 faraday:>= 0,multi_json:>= 0|checksum:24b1fdf2accc94f242e4f56b00c50a37eb13898a9011e967237f212e9b22c55c +1.1.2 faraday:>= 0,multi_json:>= 0|checksum:3443018bb6c0066a6f2f9ac36909fbfa48f7fe88af384a33b54fd3139d1b6974 +2.0.1 faraday:>= 0,multi_json:>= 0|checksum:a342f9a9dd2ef6c0c2cbe496ebd72fc91db02852a07f18e5d0a06900c577f676 +5.0.1 faraday:>= 0,multi_json:>= 0|checksum:97d82622dd0766959a86fbb63b5a139718ea53e12041d6fd5acec1d932953d87 +5.0.2 faraday:>= 0,multi_json:>= 0|checksum:5a30c02c26a11711753d2dfd9318ca210ce0eadfe8c9a3edff82d9946e0dbfbb +5.0.3 faraday:>= 0,multi_json:>= 0|checksum:4628cb791ed315d5e7540ab2919d94571435657cf5890655e0b84905ce54eea8 +2.0.2 faraday:>= 0,multi_json:>= 0|checksum:4bd50b48ea3f2f512a5a24cab0a5e2d0ecf001fb6c9d5586b90155de629a9b0c +5.0.4 faraday:>= 0,multi_json:>= 0|checksum:7c21485b1a58f85696bde20608e36a7eacddbeaf4bbb5a3bba61d49997006198 +1.1.3 faraday:>= 0,multi_json:>= 0|checksum:c916c8fa4c96ff2b3afba6ceec583cfe0ec2a9161606fbbdb5f65bed900896de +6.0.0 faraday:>= 0,multi_json:>= 0|checksum:a09ee1db14942d66c89c80e590fbe3c9b4982551e39bdf42c53b3d547165c748 +6.0.1 faraday:>= 0,multi_json:>= 0|checksum:aef0de2e8d44f9c123c8c2446c41cde67ec8b8c483207dcc60eb21e62d0bde29,ruby:>= 1.9 +6.0.2 faraday:>= 0,multi_json:>= 0|checksum:3e9e2703426501a78a20e6fdc66a6fb33ca80dee88af2003325d470c0e5ffc3e,ruby:>= 1.9 +5.0.5 faraday:>= 0,multi_json:>= 0|checksum:38caa25a9deebbf5e1d80a50a484d9c2b89b4f82d2fbad96204253db861fca35 +6.0.3 faraday:>= 0,multi_json:>= 0|checksum:1a98495e609d5c5c5f2f159b1a2b368a77ddefa176d9277350d768a467ac8b35,ruby:>= 1.9 +6.1.0 faraday:>= 0,multi_json:>= 0|checksum:87edd2e8d508657f634aa8d6cb1ca17d8f20651e4186b579c046945b0f2aabb6,ruby:>= 1.9 +6.2.0 faraday:>= 0,multi_json:>= 0|checksum:edfdb41477b09d6cdb8d74b9e76673d4379f3e76b71f141345f83c21689fce86,ruby:>= 1.9 +6.3.0 faraday:>= 0,multi_json:>= 0|checksum:bf9a85777669b2d2da6fe53d92fb59c43dd7db3616f2cbebf4b9f921e905ac08,ruby:>= 1.9 +7.0.0.pre faraday:>= 0,multi_json:>= 0|checksum:15ffad89596499885f318dd5f700035a8bba5038f1eaa2b78f4a779d685547d7,ruby:>= 1.9,rubygems:> 1.3.1 +7.0.0 faraday:>= 0,multi_json:>= 0|checksum:916b84459d3f1c0ef5cc0d556e3b70ab87216a1c8e5b74f1f75cfe758c81dcab,ruby:>= 1.9 +6.3.1 faraday:>= 0,multi_json:>= 0|checksum:c667551287a50a5564429138c3eabe276af0ce7e812187071ca10c106e855934,ruby:>= 1.9 +6.8.0 faraday:>= 0,multi_json:>= 0|checksum:ac0271ac66e3fde463dc5cabae1ec052be9b779dc9f138dee9047d42d1673a30,ruby:>= 1.9 +7.1.0 faraday:>= 0,multi_json:>= 0|checksum:2735a47e573b61f5144b79e82ce83ef253fd17b13ecfafa4d8f2089489304e5d,ruby:>= 1.9 +7.2.0 faraday:>= 0,multi_json:>= 0|checksum:a5a85c97da23d25b6614fb2eb9fe202987422b70392bc575ee701611456a6e63,ruby:>= 1.9 +7.2.1 faraday:>= 0,multi_json:>= 0|checksum:3fd37b1698339f52cebbb5c81aefb79f623151181314690115497cbe341103cc,ruby:>= 1.9 +7.3.0 faraday:>= 0,multi_json:>= 0|checksum:ce3a8f80abe911de5cdd892aa617bfce553710acc84d4e8bb70b4e1c53401537,ruby:>= 1.9 +7.4.0 faraday:>= 0,multi_json:>= 0|checksum:36ded45a0a37867eb336692c21109430fc63aba3dc4123cfe56d1b6303140ae6,ruby:>= 1.9 +6.8.1 faraday:< 1&>= 0.14,multi_json:>= 0|checksum:56d63800e8e2d5062590c7fbff79fc7d2520b046752f7e9019888343a11ee4c9,ruby:>= 1.9 +7.5.0.pre.pre faraday:< 1&>= 0.14,multi_json:>= 0|checksum:383b91eb253a07f4138b722873213cb048528a67d4d48fa00e6b3be713158fb1,ruby:>= 1.9,rubygems:> 1.3.1 +7.5.0 faraday:< 1&>= 0.14,multi_json:>= 0|checksum:831ffd52cc4308bd1211fd3128d86e6b35a179b149718d8d4c9cc9a3f59afd2a,ruby:>= 1.9 +7.6.0.pre faraday:~> 1,multi_json:>= 0|checksum:216dba7043e273bb80349a4fc1f7d15616d9fb7650b62e4becd90ba284fcf33f,ruby:>= 2.4,rubygems:> 1.3.1 +7.6.0 faraday:~> 1,multi_json:>= 0|checksum:00f329637b4d0decd2ad6f7a6f57f903ffbedf8d1430cf2a8b7bac966a26f8bd,ruby:>= 2.4 +7.7.0.pre faraday:~> 1,multi_json:>= 0|checksum:06d934aa3653d90998988bf0c24014ded2bf0ea263eecc4b41a771d785eb32e9,ruby:>= 2.4,rubygems:> 1.3.1 +6.8.2 faraday:~> 1,multi_json:>= 0|checksum:b7dff24135bfe2c2ea69da592f76bb8795bec1281783e0ffdc9503ba8d58e70b,ruby:>= 2.4 +7.7.0 faraday:~> 1,multi_json:>= 0|checksum:48daf4df3a564236d520313aa269f753e055043730fa2bf94ac37e62cc2a0443,ruby:>= 2.4 +7.8.0.pre faraday:~> 1,multi_json:>= 0|checksum:b158fd767f3f85c48acb99691a916b451dbb7ff760fecd758714113e6175f2c1,ruby:>= 2.4,rubygems:> 1.3.1 +7.8.0 faraday:~> 1,multi_json:>= 0|checksum:7453cc907e1803e358b0933e781e8a734e1a974ae105af39105c060eac957446,ruby:>= 2.4 +7.9.0.pre faraday:~> 1,multi_json:>= 0|checksum:9c0657132eaa142656db1c6eaf46d84f42ce8c95d50c4710a7c7a0f6034fdcc9,ruby:>= 2.4,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-equalizer b/bundler/spec/fixtures/rubygems_responses/info-equalizer new file mode 100644 index 00000000000..39fabf4394f --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-equalizer @@ -0,0 +1,11 @@ +--- +0.0.1 adamantium:~> 0.0.3,backports:~> 2.6.4|checksum:048a689c29253fbea6498a418187bb06e6047c2ce90284c947704195175c51b2 +0.0.2 adamantium:~> 0.0.3,backports:~> 2.6.4|checksum:7bc744315e4d7948b8cc7c1a7560a1134ae65d1b72bfc10e8872535aaa194709 +0.0.3 adamantium:~> 0.0.5,backports:~> 2.7.0|checksum:b215467b785cf79ea7c82a8ed38041061149096b3e4c3df4e56d4716e0c09f51 +0.0.4 adamantium:~> 0.0.6,backports:~> 2.8.2|checksum:37b3c9c9790307b86e3dc5e479fd5fb493ad844a1bdd92b9fc6023d437a3e098 +0.0.5 adamantium:~> 0.0.6,backports:>= 3.0.3&~> 3.0|checksum:dbffa04232634f5b992040c27c11dce87bfbb4c139fb7e9f0c689d9736f9b30c +0.0.7 |checksum:84a56c7fb14554605c2e48830e7dd683d77ca63c72a7d8c167fdf3d019375f20 +0.0.8 |checksum:d66d02ece6935c217e3a81b2e33487825633fd203144e495b6e29f07278909da +0.0.9 |checksum:992b58dc8892afc3c0bde86cd00349b23f01fb702c295c46dd3bfb4f0574dbc4 +0.0.10 |checksum:a1cffc50fc7448a0b16c66e4147c4973c530858ec532b48244349fac99e00786,ruby:>= 1.8.7 +0.0.11 |checksum:44e5bc46f49883e83d159ee9b1f7320b4ae8283bb6329e5d9716f5e7dde855ce,ruby:>= 1.8.7 diff --git a/bundler/spec/fixtures/rubygems_responses/info-faraday b/bundler/spec/fixtures/rubygems_responses/info-faraday new file mode 100644 index 00000000000..04549e95582 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-faraday @@ -0,0 +1,84 @@ +--- +0.0.1 |checksum:8e4920e87ed9005c35f452eee224ae601b86309bd79d95b640947f97b20cb3fb +0.0.2 |checksum:7626c85afa46f89a93b6ec636003798af4a78f23b310f89e07df88f262210efe +0.1.0 |checksum:63375e463f9b5fd84cf8a5f5113d413b0b677c78b278f1fa38481d590242f38c +0.1.1 |checksum:41c9c9ec0b2cfe5da6fbd50b0c9dd93dd83aa5788fad9101f94f4f0aea045180 +0.1.2 |checksum:668c8de9fa88888b69ba5f5b3294f6e22c2606dc6fbee017b8d9e751a129feae +0.2.0 addressable:>= 0,rack:>= 0|checksum:bf911a175c809ffbbc719b9162c0a6985b611080e77a693b72a083314c435ae3 +0.2.1 addressable:>= 0,rack:>= 0|checksum:bc844f9dd204193f48a2e7f0521cdbf3ee74069726869c0af73fa4f8563ebea7 +0.2.2 addressable:>= 0,rack:>= 0|checksum:ed9820894b1aa03f61d95ba3571b1ff8f48a3068cb235fca5538f654e0f439fa +0.2.3 addressable:>= 0,rack:>= 0|checksum:6876e83d4406cfc3a63f25ef2866e1842599dd45e1d2fc283c309819eb288218 +0.2.4 addressable:>= 0,rack:>= 0|checksum:4d5ae4938c2890eb678cdb2789fd2e2db6897b46170ea684acb828d02b14dc84 +0.3.0 addressable:>= 0,rack:>= 0|checksum:f679564a48b0e9394aa26e5ebb55cfec01e1c6f1ee0e22e1eeaa40ec1b9e6109 +0.3.1 addressable:>= 0,rack:>= 0|checksum:bc06bb54e3f2dc03ccbce8680e811b234e9960a8faf1d94994fc4fc00d567fa1 +0.4.0 addressable:>= 0,rack:>= 0|checksum:116432ae7776c50b1d13afdc37b3cc7abff673a7909554dbcc75f6fb505d5dc9 +0.4.1 addressable:>= 0,rack:>= 0|checksum:5990ec411c9dfa2568deb897800c7ef519e04d70f431886888bf2033b078c8b5 +0.4.2 addressable:= 2.1.1,rack:~> 1.1.0|checksum:2ad95bde23a3c2de45907f653fefef0602d5a0248747be2685ce3a244f1208fa +0.4.3 addressable:= 2.1.1,rack:~> 1.1.0|checksum:87e9d0e026b587d09364e0f63cfd7dcdcdbbc12840e8e7b3cf245082a1023af3 +0.4.4 addressable:= 2.1.1,rack:>= 1.0.1|checksum:6244fae578157e055fd94e0800c0aa85680380b25cd891338b33dcfea397a24b +0.4.5 addressable:>= 2.1.1,rack:>= 1.0.1|checksum:3674f3412dac4d1077b5a7b4c1c245cf5ae9e70b4ae3e05d5c7b366fa92b479b +0.4.6 addressable:>= 2.1.1,rack:>= 1.0.1|checksum:02f54d400744e1cc179938748000df22a0f65b69874377f3462185d2bce65e8c +0.5.0 addressable:~> 2.1.1,multipart-post:~> 1.0.1,rack:~> 1.2.1|checksum:219d25d28bf0961ce98820757e2df03595dd9ee48072c0f163fac00b28523b99 +0.5.1 addressable:~> 2.2.2,multipart-post:~> 1.0.1,rack:~> 1.2.1|checksum:7f32a0a50e8d9e98bbc4ecf25f023170de518199ace1fe4a38d457cdb59098d2,rubygems:>= 1.3.6 +0.5.2 addressable:~> 2.2.2,multipart-post:~> 1.0.1,rack:< 2&>= 1.1.0|checksum:e14c5a0a9f682174ff160e65bd7f18d0193717ea8f92670cfa755608546e7a6d,rubygems:>= 1.3.6 +0.5.3 addressable:~> 2.2.2,multipart-post:~> 1.0.1,rack:< 2&>= 1.1.0|checksum:84875c9d33756afe5dc09e38045bac1ce16ad6ed44636c5f3a33a8269720e9aa,rubygems:>= 1.3.6 +0.5.4 addressable:~> 2.2.2,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:66847353b82cdc6d2d22e4e345048a10833c6f11db653c5a533105252cc6d40b,rubygems:>= 1.3.6 +0.5.5 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:6f25c0393645a32562af7ddb3321bb0f2fab668d4df8a817640d5c9b713f1828,rubygems:>= 1.3.5 +0.5.6.pre addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:0838e38cbb355604f33fe9f48303408556640364c0930cceab5133b44bb69746,rubygems:> 1.3.1 +0.5.6 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:e8f9dcff4ab8e244fd28f10e02f44fca529ded098a4b7cb5e92c33dad5b30a5d,rubygems:>= 1.3.5 +0.5.7 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:dd4d9ae5a3b05218207f24652fcd7bf7eb529310ab91a585273f2258ffdf2e42,rubygems:>= 1.3.5 +0.6.0 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:2800051b529fddd9d733232b6a80ef8e4018f4ea4a30e60e48bbcf092da4960d,rubygems:>= 1.3.5 +0.6.1 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:17d4983024a9c02ec84bc2ff3cd6963f7ff04275b8e941d1d1df8f8736ac3ce5,rubygems:>= 1.3.5 +0.7.0 addressable:~> 2.2.4,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:375adbcea1ee76ee1fd7bd7f5b721662eff878f164574010f07f9cc0f61ed356,rubygems:>= 1.3.5 +0.7.1 addressable:~> 2.2.6,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:e25b4a5c0344aa45e3e1e950860b97c3674300d44a9d45ce5ee45e86d38ce451,rubygems:>= 1.3.5 +0.7.2 addressable:~> 2.2.6,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:4084165598137c7e7553265e24c8def5bc7509af2a7062773318fcf17388d662,rubygems:>= 1.3.5 +0.7.3 addressable:~> 2.2.6,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:c918e54efc6fac3623e6cef32cf0ba3aa1869f17a509c208cef1546cb56d20f6,rubygems:>= 1.3.5 +0.7.4 addressable:~> 2.2.6,multipart-post:~> 1.1.0,rack:< 2&>= 1.1.0|checksum:5bbe253bd73f7a79ddd306038ba8ff648eaa78f9d7316567bc5fc48d14ba1d02,rubygems:>= 1.3.5 +0.7.5 addressable:~> 2.2.6,multipart-post:~> 1.1.3,rack:< 2&>= 1.1.0|checksum:29fee7ae3cb1692949b88b6fc72c3da7573847436b9a956e02cf0d7aa1c43bec,rubygems:>= 1.3.5 +0.7.6 addressable:~> 2.2,multipart-post:~> 1.1,rack:~> 1.1|checksum:bd3291a6fe4545bad566610e5c1d0c671eb182aa8d9772e860a85db2c3c3cf19,rubygems:>= 1.3.5 +0.8.0.rc2 multipart-post:~> 1.1|checksum:2c0c9aea15f04c895cfc5b45ee61a091fc3f0c5cbb9ace3e86b340e1dfbe98ae,rubygems:> 1.3.1 +0.8.0 multipart-post:~> 1.1|checksum:5f885e71d01c5818009c39289fd522eb22d478ba9155cdc28195557de4ceb1e2,rubygems:>= 1.3.5 +0.8.1 multipart-post:~> 1.1|checksum:74c7b8441d5fc1853a1eb6d6c158aec47e78f185bd53044ae897351e4ece41f6,rubygems:>= 1.3.5 +0.8.2 multipart-post:~> 1.1|checksum:23373d0ef7bc32567303ad01b9b2059c4100b3fe257d4854b444cc47bf06412e,rubygems:>= 1.3.5 +0.8.4 multipart-post:~> 1.1|checksum:a5d96714bd6154377bf2a55b0a6f5a68e97458145b91c67d516ebd9f15cc365e,rubygems:>= 1.3.5 +0.8.5 multipart-post:~> 1.1|checksum:19a292c730f661344888bb07bb477ec0798524e900de38f99d84e5db1e6d663e,rubygems:>= 1.3.6 +0.8.6 multipart-post:~> 1.1|checksum:5e16df18ed6d57627087f7992bb87095a12aa5d78a5a8436d9056687ed034d9a,rubygems:>= 1.3.6 +0.8.7 multipart-post:~> 1.1|checksum:b1355370693eb48cb81ab2a66f02f791177ef53c83d39699a056f5385a4dcaa0,rubygems:>= 1.3.6 +0.9.0.rc1 multipart-post:~> 1.1|checksum:47a8187a524668bdcbef8cc0ad9cc2ada00644261875981835f05bd3d3d44bff,rubygems:> 1.3.1 +0.9.0.rc2 multipart-post:~> 1.1|checksum:74cd3375b899a6e8f0bf4a0391f902e5a6a2721288cf84144b917f70f556af36,rubygems:> 1.3.1 +0.9.0.rc3 multipart-post:~> 1.1|checksum:537e8e468502fd2b0fef11f555dbc315d2d66283bccaa6c5e4b5d5ec00dafbe0,rubygems:> 1.3.1 +0.9.0.rc4 multipart-post:~> 1.1|checksum:b876b36881cac81b28ca7e8026f47c12f9e04d776e811c8546f2ae1a30b0a175,rubygems:> 1.3.1 +0.9.0.rc5 multipart-post:~> 1.1|checksum:918e1d995008b33e1b875d84edc9e548d9b33dbab33c4bab437d824bfeab827a,rubygems:> 1.3.1 +0.8.8 multipart-post:~> 1.2.0|checksum:24322e1618c706d114190241fbdd6433c2e3aa2a8a06403737dbe6ab6491deb2,rubygems:>= 1.3.6 +0.9.0.rc6 multipart-post:~> 1.2.0|checksum:4f619633f39a69a9e867ddf4fa7c034b41ecfb3732f88477ad6f09afbe545418,rubygems:> 1.3.1 +0.8.9 multipart-post:~> 1.2.0|checksum:289c3b5b57821b52988bdb5178d3e1149741f2bae5fbee2a80bc83feb44ba79d,rubygems:>= 1.3.6 +0.9.0.rc7 multipart-post:< 3&>= 1.2|checksum:b5f248f38120d4c47820bed463aacc3c589cfdae8260a5f2f2ca04f7b06e0a3b,rubygems:> 1.3.1 +0.9.0 multipart-post:< 3&>= 1.2|checksum:86409d329defa4b3b3b5774fcc0bf9b135ef40c60f147dbfaee056238f47918f,rubygems:>= 1.3.5 +0.9.1 multipart-post:< 3&>= 1.2|checksum:5677350808cae1d7ee526fe8f78381c134193173292281ef63faf6efacfd63c0,rubygems:>= 1.3.5 +0.8.10 multipart-post:~> 1.2.0|checksum:ce64927f2c2dbc89ce90710ea021c76a9c2974952c31839349c9cad173cd7024,rubygems:>= 1.3.6 +0.9.2 multipart-post:< 3&>= 1.2|checksum:0662e5caa257c256cff4b073deef5c73e3469d3ed0b8d6e9a05e6861efc4f4ce +0.8.11 multipart-post:~> 1.2.0|checksum:b16608080bd0874d44b15db85833a75cc6dfcc7e7ffc5e0603d043c559f9bb94,rubygems:>= 1.3.6 +0.10.0 multipart-post:< 3&>= 1.2|checksum:d7a610d5336ff5239a75bee135fdd59f5763f703801e6c77619550b05c83f3a8,ruby:>= 1.9 +0.10.1 multipart-post:< 3&>= 1.2|checksum:cb533b4ee2ffba3241c6283dd3b2be008ad1e460603e59165f30c8aeb9b1001d,ruby:>= 1.9 +0.11.0 multipart-post:< 3&>= 1.2|checksum:5986f49009d638d971997082f1a6cf1ed835144a66d5c11dd495bf1d9b66e1a2,ruby:>= 1.9 +0.12.0 multipart-post:< 3&>= 1.2|checksum:467b18cc2683845e90996e2c7f3af0cf34493d78b687445b2b4999711f6f6dca,ruby:>= 1.9 +0.12.0.1 multipart-post:< 3&>= 1.2|checksum:a80da46d8f4d64d011f97768894e33d3aaee25a37b8742d6197f2416857db849,ruby:>= 1.9 +0.12.1 multipart-post:< 3&>= 1.2|checksum:0350b3d3adc9418e4e761198866709fc1b27db116cf52484989aa94d084a7df2,ruby:>= 1.9 +0.12.2 multipart-post:< 3&>= 1.2|checksum:6299046a78613ce330b67060e648a132ba7cca4f0ea769bc1d2bbcb22a23ec94,ruby:>= 1.9 +0.13.0 multipart-post:< 3&>= 1.2|checksum:9ffddac261913057069cad92b54d4eb2a29643781b346a8afac858262b5b88cf,ruby:>= 1.9 +0.13.1 multipart-post:< 3&>= 1.2|checksum:1c82a788fb827fb4c01766e0777ed8044856f92f8824b7e3e6d663ba8fd4d8bf,ruby:>= 1.9 +0.14.0 multipart-post:< 3&>= 1.2|checksum:39ffa339accf15a8e3357ef5cb94ad5c0f4c14ef0d6ee76d3cce96b5911e7db0,ruby:>= 1.9 +0.15.0 multipart-post:< 3&>= 1.2|checksum:4a29d584a33d189ea745bb3b3db36661e28f32a035c62632f09b70df3bdb61b7,ruby:>= 1.9 +0.15.1 multipart-post:< 3&>= 1.2|checksum:bd5bd1ab8db9b3f99ed1113d80522dabf95941e40cc3107f9621546f6a357f60,ruby:>= 1.9 +0.15.2 multipart-post:< 3&>= 1.2|checksum:affa23f5e5ee27170cbb5045c580af9b396bac525516c6583661c2bb08038f92,ruby:>= 1.9 +0.15.3 multipart-post:< 3&>= 1.2|checksum:a2d4d2d05f557c2a6f87ae91cf3d61f757fc9c031dcac9ac9acf7cb011eb1c9a,ruby:>= 1.9 +0.15.4 multipart-post:< 3&>= 1.2|checksum:00e6ffd6f1bccd9dc9e3b993a0004e69680559422206ce4cbb81fd2d0ba8e268,ruby:>= 1.9 +1.0.0.pre.rc1 multipart-post:< 3&>= 1.2|checksum:de12631b59bc41b49b27bb2534c8ab15a6773642f8ac22e57e78f1fdbd0e62a7,ruby:>= 2.3,rubygems:> 1.3.1 +0.16.0 multipart-post:< 3&>= 1.2|checksum:1520361793212590f39987f15bde7b791978e9320fe1819bb8941043a8d1dc02,ruby:>= 2.3 +0.16.1 multipart-post:< 3&>= 1.2|checksum:3a079817a0f16d51d92ccaca1465e3b48115550bbd3504033dc9c8947c57ceb1,ruby:>= 2.3 +0.16.2 multipart-post:< 3&>= 1.2|checksum:bc2790cf183ce1f07196392b300d10233d1d9f04e91065146703f74b47511850,ruby:>= 2.3 +0.17.0 multipart-post:< 3&>= 1.2|checksum:5f19b5c6d22eca82564fe26e4963f58cf0ba34059b8e9399c0b19a4eb25a624a,ruby:>= 1.9 +0.17.1 multipart-post:< 3&>= 1.2|checksum:88a71dc346e55a20dcf2961395f9efabfcb0a956ea722768ecb9cdbdf7f8efbd,ruby:>= 1.9 +0.17.3 multipart-post:< 3&>= 1.2|checksum:c27a8fd7614f1abe9889d8b797246a8e0e5aa6e9d7f1e34ba05a445bf5844f8d,ruby:>= 1.9 +1.0.0 multipart-post:< 3&>= 1.2|checksum:e67631809ae5633a1d2b03adfa83939a91a095f6dc61a1f322826612613dd687,ruby:>= 2.3 +1.0.1 multipart-post:< 3&>= 1.2|checksum:381aee04fcc9effbe5fa7cc703d8f5f20293722f987ded4f958f77514cd29373,ruby:>= 2.3 diff --git a/bundler/spec/fixtures/rubygems_responses/info-ffi b/bundler/spec/fixtures/rubygems_responses/info-ffi new file mode 100644 index 00000000000..7582abd0475 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ffi @@ -0,0 +1,273 @@ +--- +0.3.2 |checksum:5f0b378d12ab5665e2b6a1525274de97350238963002583cf088dae988527647 +0.3.3 |checksum:63aedaf0999174a11b06dec267727ae6a057706c1103b4641a12682f01d42468 +0.3.4 |checksum:cd9b5aa7a816ff41a0b693e25e941730735237a4008051d1388016c91ce53144 +0.3.5 |checksum:ff9772117b89998a164f0c5e4e84617913b895c259b952b9107c3de004a75660 +0.1.0 |checksum:3c302a18ea4836fde8e444c1aa13082879b3e78afeebdea1babdaf53e8c7d1b1 +0.1.1 |checksum:0b3ab13790fed50a88276d3787db3514678a616dc99aa34855518ee441740ac2 +0.2.0 |checksum:acb77dfc3483c1eb90a766369b25480351d84760e22f5e0fe7f8c4030a07f5dd +0.3.0 |checksum:6ba47ddee34a760988a19b090afc12892227c60ccac71f3092826ce2ee4a85d8 +0.3.1 |checksum:61e4ca19716f9505de0195010590c91aca44adfee6815f56a6748b36f26ea924 +0.4.0 |checksum:860200bfc26c861c5f9aabe289289362cb5ba3e7d8a10dfeea002b7f1380c3e0 +0.2.0-java |checksum:9cd5cae48687430c6cfbd8a0082001e917fcb85ee7a3d1ebd330ceb95833c972 +0.3.0-java |checksum:d4add09d36cc7a2b8eb5cd451e464b6ed33e031b4282ba23cd6ff9ebd7c81037 +0.3.1-java |checksum:dfb0189d2474ad60441acedb9d29ac81ed8078f0e71401c3f81eb10b89cabebd +0.3.2-java |checksum:78fb3c15df4e50ce0a454f69c070fdd614f0262da01c64955c889d405b087253 +0.3.3-java |checksum:1e7038e69dd058eb81221865a638415340b6bef8e746923cb624cf0dd8d7ba78 +0.3.4-java |checksum:3d1d05fecdf8c0993569cb7f0a9c4882c4a1cacd66d63fb4f3b92ce26126d208 +0.3.5-java |checksum:5c044e99394837c62b4630a3710e48520ee3d63e6dd1da8850f0b11a29e87a94 +0.4.0-java |checksum:5dd6dc6f0881dc46dfb50498bccffacf13f43b7c77754fa1d06065346c3859c2 +0.4.0-x86-mswin32 |checksum:45c875c891ee12d915bd9c12210a2eec5cab6a1a0874d5646cf84ddfe7b62f9d +0.5.0-java |checksum:cd050ba166dc0a1fb7247f709cf7461f0e01da70f5632f5bc30fc0bc645fe046 +0.5.0 rake:>= 0.8.7|checksum:41fd95c45b3ae3d9209adc832ef98da027fb9d4fa04bb29c225efb881b389fd3 +0.5.0-x86-mingw32 rake:>= 0.8.7|checksum:89230f274f65f6f98a7dc7c084d7b1dc3831bf91d21765980d4a53886cfb6edf +0.5.0-x86-mswin32 rake:>= 0.8.7|checksum:1ada6352d7d53fb825deac088215c3c91a8f391ec53a63946022781eb0536a38 +0.5.1-x86-mingw32 rake:>= 0.8.7|checksum:80b2c72836a14860b3e53acfd8c288985299d970af9a233abcf58eb7802df102 +0.5.1 rake:>= 0.8.7|checksum:f6ac986015c732712c924016221ad385b70586eb1177d108a43208a3b9e97fb4 +0.5.1-x86-mswin32 rake:>= 0.8.7|checksum:39500bf213e1c0cdc7d829d5360294a56ef7a7d15a3b71fee6f628fc3cc4de72 +0.5.3-java |checksum:22c0abea0e0885a2f9aeeccacacaad16c64bc5809562a2a4dd00b4f8f1257915 +0.5.3-x86-mingw32 rake:>= 0.8.7|checksum:9f4081fcefa184efc02bb3c3aae71ab154b75d51aef495a63d7939e6e61f25fc +0.5.3 rake:>= 0.8.7|checksum:8589a7cdafddc97e5dfb838fa68df20f338a9512e0cc7866f425b4b9e88c0fa4 +0.5.3-x86-mswin32 rake:>= 0.8.7|checksum:00a1eed51dc6a4d87cf70d394d9f2118c6e992ab0d516fce6e144d10e5e1c425 +0.5.4 rake:>= 0.8.7|checksum:335ab70e56deaed0b90192ce937119853797ec201c00b2d53c2005ca240daacf +0.5.4-x86-mingw32 rake:>= 0.8.7|checksum:1e3b13dc792ea00673cac3293c3fe83f9a674afef2bcfa1323614de0996227a8 +0.5.4-x86-mswin32 rake:>= 0.8.7|checksum:d09644928f416c7460ae3fc3bfeef5e90269698b6dfd9e8395a037e346dc61a1 +0.5.4-java |checksum:c77c24310b94ce27c84e1fd7bc56b8f7b7c9dc38920d4b8ce73310962dbb2a22 +0.6.0 rake:>= 0.8.7|checksum:345017060b0f3b28a1fa3e58f55184a0adf45251c51306f3329addc4bdaa9636 +0.6.1 rake:>= 0.8.7|checksum:4cc915eb202dbff9bef37bd6c0d6b4a9a13e66e7ef95a84a0b8b878665c36324 +0.6.2 rake:>= 0.8.7|checksum:468b9a62ae3d92247d89dd5e86ed3f4ccb63fa8ff25ec401342ec0320c9120ab +0.6.2-java |checksum:f995841f481875868d41d85a642a20e381cce08cc42314688b63cc5e23b99b08 +0.6.3 rake:>= 0.8.7|checksum:6b317b44933b758045479c817c60ce12c3ab69eb8d3b19f61691606919ee1623 +0.6.3-x86-mswin32 rake:>= 0.8.7|checksum:eec91c1692c467b56e87120fb208f9ff4bf8f62300a9aa8db0798d69643e55cd +0.6.3-x86-mingw32 rake:>= 0.8.7|checksum:8d270d349366a994b54e11df3068d2bcdb1282c8edbcebe91606101c3d66f395 +0.6.3-java |checksum:9abaf2635d0a392872b8030e22d06e6bca144b01cbbaca8fcf02eab8f2fd7cb7 +1.0.0-java |checksum:b6dd406660866eda3ab7259a14a558ea638dc531b734d4054fad1b53d864bbab +1.0.0 rake:>= 0.8.7|checksum:a5b549bc5655eacf817d0f4e60f28761f9515b144c2545dbc4e84cb1f88cc26d +1.0.1-java |checksum:35b6cd14f14c72c4afb874a0b5fc6e63626fbf6132cbfe06877dc1274b58c799 +1.0.1 rake:>= 0.8.7|checksum:aab0b90f30db9dbf300fa0379a50618e4d8fa5fccb41968604bf6bddbc51fa91 +1.0.1-x86-mingw32 rake:>= 0.8.7|checksum:bb254ede8955d143664d079ef88de66e3b668fb9d2245697e2cee1faf3f359c6 +1.0.2 rake:>= 0.8.7|checksum:6452302c57c0257c4295eb565afff8197f52d197f705701fb35fbad113359285 +1.0.2-x86-mingw32 rake:>= 0.8.7|checksum:33a2c545302a1de3b5375cf5b9f203b62a8456090c30d92391032f1bf7b9dc80 +1.0.2-java |checksum:53b63d03a59e49ca0049e0b319a21de489bc4fb1a5bce4ea9b76849550f55188 +1.0.3 rake:>= 0.8.7|checksum:a76e1fabbbcb392fedc397e1883c9e833c80225057c8ad3c473f83fbf0e6ac75 +1.0.3-x86-mingw32 rake:>= 0.8.7|checksum:49822c2b2d23e15d6a1676ac0f746cbdaee657cac0490510c13ba8af4b6d4af9 +1.0.3-java |checksum:8daf9414c960fb1f619b411b102a9983fbb23ff438716352672da19cc464d0d1 +1.0.4 rake:>= 0.8.7|checksum:823f6abcfc20bbd725d03938c2bbe55a7875533eca2219fe6915e0c827071de4 +1.0.4-x86-mingw32 rake:>= 0.8.7|checksum:1017a48b1335b3339b31db6b77aa60d95bd93159c740e27f9efe7214d3551986 +1.0.4-java |checksum:54675188a87d6e050f45d904847c427c13f9d93e4b22e83fe9fc60262a064113 +1.0.5 rake:>= 0.8.7|checksum:93fd5fbe672e58926476cbff1f88c9bd1b6e535b6b391a08137d1c7b0c7749ce +1.0.5-x86-mingw32 rake:>= 0.8.7|checksum:36ade1ac875afb843d31e67de8f4765c9048914dd05179884062f283915aa7df +1.0.5-java |checksum:09baf89ae23f8b598bb72826f4ccbdafca275cf70c6907834980fd32c8064cb2 +1.0.6 rake:>= 0.8.7|checksum:917452d1ef357a106919cb4eb8e23401888ba42200ca695b59a38e541fa5d6fa +1.0.6-x86-mingw32 rake:>= 0.8.7|checksum:cc564a51db86af806cdf8b26b20e6cbd788c04f9439bd5e1c13a48ba3c2746e8 +1.0.6-java |checksum:879099866ec9f81810571ade29b885ddfa7ee3fa077b98ba0190fc07cf8f761c +1.0.7 rake:>= 0.8.7|checksum:60e8d7ab3c5e8f1a4f9871bf00c158bd49907b837c1766c88338587421f48a04 +1.0.7-java |checksum:f7d21096592d02901080ed8b26c744b4523f26b0fdee7b6a7ec5b0783b7fef73 +1.0.7-x86-mingw32 rake:>= 0.8.7|checksum:2ef87f01692ec42c2c1fdee524150f978a8094ba71624b05289ba98b97c7c110 +1.0.9 |checksum:909b86aeaeccb6535935935979ae6d24ccb21fa8fb5f5c3ff7cbf7bd64deb7a4 +1.0.9-x86-mingw32 |checksum:b1f2aa1a7539f8b80feea4fe69104f803d013db26fd1ad4bdb881546ceb5c382 +1.0.9-java |checksum:c51e09de2ea036c802b937ebb70467ebf15935938c508a24b26be2bed1be6604 +1.0.10 |checksum:7e1b70856b0ed43dbcd9032a9b832ca6034ca518137f82e6f9e72021823373d0 +1.0.10-java |checksum:b575f92e32a0df6bf701095040d9ef39f6b960fd9e021459b919f9ae0c404167 +1.0.11 |checksum:2b253b14b0a850eb274a7a85a04d3a7310993a8a21701b4cb26779aaf932fb9c +1.0.11-java |checksum:875eeccae30421dbd3d65c52cf977733a0fa1a1c9a56842d4078329d4c2ac7f7 +1.0.12.pre |checksum:91ddb4c1b5482a4aff957f6733e282ce2767b2d3051138e0203e39d6df4eba10,rubygems:> 1.3.1 +1.0.12.pre-x86-mingw32 |checksum:d3426ff623a93414a3487c737cc2ce35e2b836f35227e33b8bfe1687013a61ac,rubygems:> 1.3.1 +1.0.12.rc1 |checksum:1233ff998444e1bd504a8316aafb28ddf218afb582b713c296165eb963086d00,rubygems:> 1.3.1 +1.0.12.rc2-x86-mingw32 |checksum:6c16db83619e525a4fd91c6f98dd5749b814f63a75bd0fa3d4b5936f8d1f7425,rubygems:> 1.3.1 +1.0.12.rc2 |checksum:71b32cbf33ced1296a66fb13e5eb8cd580aaf0529ff5f589859e51b07456bbaa,rubygems:> 1.3.1 +1.0.12.rc3 |checksum:8623369b60b5d2163d0c5684ca4ae847ecd2462a28e34e49a17abc0fa7f88544,rubygems:> 1.3.1 +1.0.12.rc3-x86-mingw32 |checksum:036b10fe5e4c94d54a0e782032ac10a6efaef43b49e528c2ef68699afee5b09f,rubygems:> 1.3.1 +1.1.0.rc1 |checksum:6d0bc1163687f1f6541a48548505628c1a21b8ebe68f7fb06ed2ec9149987d9b,rubygems:> 1.3.1 +1.1.0.rc2 |checksum:1f5378d638c7182ce2960f9f8108bfe7c1d39174993944e3ffb4e92a55710840,rubygems:> 1.3.1 +1.1.0.rc2-x86-mingw32 |checksum:fb94b18ce9eb6e9948bde56a4f1af1b505809694b706ede87541da688a0618bd,rubygems:> 1.3.1 +1.1.0.rc3 |checksum:7744292b3c8e4d1f17b225fe63240b10190c0afcd494fb6bef4418ffca4a11b7,rubygems:> 1.3.1 +1.1.0.rc3-x86-mingw32 |checksum:d38e3b6ace85ba8c4316c0184f92a315734508e47253d82133f3e410e73fea48,rubygems:> 1.3.1 +1.1.0.rc4 |checksum:3a93d1fbc665803b62456f440120a3266267a63f84699247337940afc0572c8f,rubygems:> 1.3.1 +1.1.0.rc4-x86-mingw32 |checksum:d9580229a843d25e136bf5db2654e3ace52c69c4ac2c5b680c0fa2794775e253,rubygems:> 1.3.1 +1.1.0 |checksum:2f2d1bb12b608a98b417225a6641cb1559716409af81f5cb2032042a35f25235 +1.1.0-x86-mingw32 |checksum:449580025395dd1df03929d8c36fb085cdd18fd27256d47429d3912426d99164 +1.1.0-java |checksum:5676f5a52cbaa5d3e1f2861eeb1910d6189fc6b38b8727e202887489bd152cd4 +1.1.1.rc1 |checksum:6ce7e2bab0f005ca4c49759b7f63a85ab53885c9e2206c70ff7d5ed672422a27,rubygems:> 1.3.1 +1.1.1.rc2 |checksum:67707e13237e56a0f9b5c630ce70738576ec9e56faea053350e3ecf43c68e85d,rubygems:> 1.3.1 +1.1.1 |checksum:942b8e3a7ce3ab72c1aed95f4c4c5ede83e1cb5cbe7fcdbf85d28d7db630085f +1.1.1-x86-mingw32 |checksum:8d3ac2b45c91d8d8784661b2ab5119dc676c375bca47530394fb6ccdfe8c04f4 +1.1.1-java |checksum:cbbe4470c47b1d6abcd631042b2b6ad1fea4fce4cf98f25e5019e7347f542268 +1.2.0.dev |checksum:9643f3be827725c560733d52682c7c88dd308f7fa4b5ced3ebab9a72eeed96ac,rubygems:> 1.3.1 +1.1.2 |checksum:bef889c4f274f20989df3e581f2dc786c174c0c8b36091d1a24a7e236587d848 +1.1.2-x86-mingw32 |checksum:a2633893cdd00167a3ff87fcaccd860f2e2618c4582b739f300fc34c5b7f3c65 +1.1.2-java |checksum:cfdd1d74b0da5c359ed13dcbbc901562312c0080de60d6af9c3e6d8f1dfa608d +1.1.3 |checksum:1faebfe6b09fe2137591c3154546d6b4f5bc2930521b5624a5d6d67f6a24a856 +1.1.3-x86-mingw32 |checksum:4bd509338928aec60dedd7f8ffff477530e3b0dad6282fa1bbfad6a551ad6ed6 +1.1.3-java |checksum:0dceff657b134db60adb828f2f40f3b4b8ec9b685c6b272e420c8ee431691df9 +1.1.4 |checksum:3db0c1cde07279c9ae1d08b8d543cbf91aed125ecc8e261d3dfdafcd42d33692 +1.1.4-x86-mingw32 |checksum:753b459ef8255e72becde35769a9a19630a636127ecdadfcb049e54ba2461f9a +1.1.4-java |checksum:3d513d189f2fca4471dcc7b85b5de8cd2f1924dc18341a1f4753bfd674ba644c +1.1.5 |checksum:93fec40aa7fbaf5289f699b02334d67942ab20449e62e1dcc558f93095fdc957 +1.1.5-java |checksum:e7af7b081bd6a89a8647e77ce6d6e24236cee89a13d153da19c59b9e57f5e8ce +1.2.0.dev2 |checksum:8be737d87fa4c52c5ddc9171488406388e96bdb6d8cf0ed672f43fc3757ed3cf,rubygems:> 1.3.1 +1.2.0.dev3 |checksum:bf2516fc70c50a6a1770dc72fe30761debd6b455db59f32d3081c17ef3743ed0,rubygems:> 1.3.1 +1.2.0.dev4 |checksum:aeb3a45480a92a6aa87c09381c5762687b15a973ae178b226ea7787924dbbd8f,rubygems:> 1.3.1 +1.1.6.pre1 |checksum:6ec34c0f87b84a5331702456f47f35b3c5c742aa7d40a81c558334ae32fa8e34,rubygems:> 1.3.1 +1.2.0.pre1 |checksum:4a3f862cf94b9ed4883469220b75f0eb672e22f67c7fd4193473a54973b20792,rubygems:> 1.3.1 +1.1.6.pre2 |checksum:d72afa4aa28069d0c3eb8bc13719fc6399cf50b2ffb0456024a3b1a5c8451eb3,rubygems:> 1.3.1 +1.1.6.pre2-x86-mingw32 |checksum:352980aa01aa707c697154d64ad7b6006761eb842e0600e85417d7ae9d5318c5,rubygems:> 1.3.1 +1.1.5-x86-mingw32 |checksum:93aa6b787821ba421558c1577f02659b859983a7dd117affc62bc867fa6fde18 +1.2.0.pre2 |checksum:ada03b20c63e74d370a22a684dfe00ff627dfa02dcc3b64704bfa98461932d99,rubygems:> 1.3.1 +1.2.0.pre2-x86-mingw32 |checksum:11fe6cbada1bfb2381fd64c085a0bc71eb0e7f2e277df3660cb2203ea9512e07,rubygems:> 1.3.1 +1.2.0.pre2-java |checksum:a80253999ea4152ad3dfa3aeb863267c7fcd85f8e3e19eb5975012ab4ad0fe58,rubygems:> 1.3.1 +1.2.0.pre3 |checksum:a61ff2757cb7094ac199c10786938795ba9c179660343686d1cb17e7887fcd96,rubygems:> 1.3.1 +1.2.0.pre3-x86-mingw32 |checksum:c6f6cb65ff3b5a2ea386e15272f0b702128f817b490db257a7205cba220ee7e0,rubygems:> 1.3.1 +1.2.0.pre3-java |checksum:0a05fe41c044e4110f9c1fa2d13ace7790eebae1ff30a5b4cbae54ff9ddb58d7,rubygems:> 1.3.1 +1.2.0.pre4 |checksum:4fb67abb16c269e49a44f00f7aef50eaaf028463035ceacec5a90670ec2fad2a,rubygems:> 1.3.1 +1.2.0.pre4-java |checksum:ec1b233c879f94318c0a32c9e4f269b47b4ec09d6f53aafb7cd6910a421bc7a8,rubygems:> 1.3.1 +1.2.0.pre5 |checksum:698695082118d10e26e51c21ef609b692b1b463d9d35c7cf1feb3d36a08dc85d,rubygems:> 1.3.1 +1.2.0.pre6 |checksum:1c83b47b8b21788cff5bea35d0ec8dc652a7e3822b073d8285c85610a8869909,rubygems:> 1.3.1 +1.2.0.pre6-x86-mingw32 |checksum:5b42b81d4e0c4ba3992dcf60d116ec1948f35f1bab64d5d815a9a934ac9aa493,rubygems:> 1.3.1 +1.2.0.pre6-java |checksum:01cfc621fcdaf2ec828e42cc0074ee1af4417de9cc68701c0c66ebe93e44d757,rubygems:> 1.3.1 +1.2.0 |checksum:06356011b9b86a08d1dd456a68e469dc656ac5efe9c6abce33d3c50f1017bb07 +1.2.0-x86-mingw32 |checksum:6e771ae11c40a5d85845ea12896601b13416a55170d1bc02e3280a1126132f1f +1.2.0-java |checksum:05b8de9e4e1ac10ac871561222a5fc3768a2354977501129f3bc285483c52b56 +1.2.1 |checksum:5e5dfac80af8a98f6f87744132927c351847b3e8f3d69cd8c8357ed9da9a8e8b +1.2.1-java |checksum:7827893670afc5e87c8b14b98adc3715a42084f2db619461877abe924b2601c7 +1.2.1-x86-mingw32 |checksum:31e46657bd193028af1c610fadc403845c7effb7b47754e0a554538cfc65eb87 +1.3.0 |checksum:598adc347a34d2a74ccef68f28f1c744dd7de92a8fb53e740642f5547a524b3b +1.3.0-java |checksum:623b7783f1d428cf0baf317e98b2a677658e734229785890cb59869cd21aeb06 +1.3.0-x86-mingw32 |checksum:2112b76f6ff770538d7a304871ed3a48db91646c843fefc05f12a04c88315bed +1.3.1 |checksum:4b830b737c7a3378f389b399fb1bc0403b6bdb7fe96d7ac8aa340eae1e777941 +1.3.1-x86-mingw32 |checksum:506093368d83f21e89c584b55d0117307e7bd295c3c745608e367a94cc521626 +1.3.1-java |checksum:45fdc13d612e896c9fbf039ef71cc3590601c2f459d96153cff2e64c553baa60 +0.6.4 |checksum:75e786b3196c543f87551494a708b33f969c2556678005f61d70256562d08d3f +1.4.0 |checksum:c89c24653d86009875330c3759873eae02708af49f9fe86f9afe20f2364e4219 +1.4.0-java |checksum:5e529d7de5458c4faaaf53fbb325d349d2dfbfbbd0db9fd5ec132f819fcd0f8e +1.4.0-x86-mingw32 |checksum:9e5828156c4b03817a9c276ab122c79d00504a2df8cf1de27cb5e53b47e90b3b +1.4.1.dev |checksum:59e8744c3630e45a8414f7644d90e2ff2326cb83f90e45c62affcaa4cc97487d,rubygems:> 1.3.1 +1.4.1.dev-x86-mingw32 |checksum:b7a29750f296e4918d984fa4a3b759a3071eb7786cdbb350e433ff2feefc721f,rubygems:> 1.3.1 +1.5.0.pre1 |checksum:eb13e5b107f44b91250db5090fc1d1db4ad0af72a59ee68c588294c29239f845,rubygems:> 1.3.1 +1.5.0.pre1-x86-mingw32 |checksum:89f1b05850f1a64b6867ab69f8ce907f3165926827dc1ef6e2cf46e5ac070b05,rubygems:> 1.3.1 +1.5.0 |checksum:7e84f1a7c17ed91247099491b49f7818d4b7ee601c9faa366fc959b0ff8328d8 +1.5.0-x86-mingw32 |checksum:c8b6052fd8a9823b52cf645ae1410b43ebe96802f2a66c45fce721075123e094 +1.6.0 |checksum:7b0430d5d8ac412ab62f90cf5a518760e5897a7e9f1925c69e8a99f590fc124a +1.6.0-x86-mingw32 |checksum:aeaf41fc5db88a305091bbe956dde558de9ee90c92635f1d04ac7c4c192c8c37 +1.6.0-java |checksum:9ae9b57f24ed6ecf68cb1d6ac36008fe591dc3d548e2b022ddddc9e805360fff +1.5.0-java |checksum:2e07dcbe9b620b1f599627def34bb20a949406aaf513dc038adc895ff088be06 +1.7.0.dev |checksum:2f960747cd37f0d14790eeddde3cb116cb57d9ed48ec02f1011caa7b38e28a5a,rubygems:> 1.3.1 +1.7.0 |checksum:2b3a67333a4a56c26b12bbc93f3ac2e314ed6094fbc75459f52647ce137cb711 +1.7.0-java |checksum:48dc783ad69751041e7c9980961fe9626f3ec54ed8a843c7d8d1075871196435 +1.7.0-x86-mingw32 |checksum:64937a4dfcc1b169a3babec16f8054c5a8ac02839aea58ad8127606f0ba91260 +1.8.1 |checksum:8fd33589b4a0a2a347682c9784c68ff4b90c37d5310c9c630a3e41b442ac6766 +1.8.1-x86-mingw32 |checksum:d2fa7e1971a19d65502fca460ec1ae5e291487f38079534b92040f6d87797216 +1.8.1-java |checksum:55ebcddb25d5ad1e1b879a2236d07ec778e9806a6a33f53cd28cfabb590ece3b +1.9.0 |checksum:7e73075fd054440d03e9ebedfe9c0240e24783683ebe5351acedb2efbc4fd066 +1.9.0-java |checksum:352fba5dd1dd4d486202817422fbe1d39e5781dce90b566ac95d3b98d818dab1 +1.9.0-x86-mingw32 |checksum:3f8c21c4d7ad75c32959f10489a6290ad54d292bb11f89000578e81270525820 +1.9.3 |checksum:57977d095c1c324ac1cb134863180b34d5743fed2b6d7528adc5ec71a581e320 +1.9.3-java |checksum:4938414a1c05a2921833f87154ac649dc16fd5d63101667cfc49f8cc33b8804a +1.9.3-x86-mingw32 |checksum:dc884a3e900c6ac5537eec1345deaabb1978405988037e7d452928761a2ebb2b +1.9.3-x64-mingw32 |checksum:fe4522d4eefe4be79a8ff856f0f463d803c8499c3e2c3ceab92d1921db073c5a +1.9.5 |checksum:0d2ef90163eef8545689e8dfc27fb1245a2d82e3500d587de1e38290629e662f,ruby:>= 1.8.7 +1.9.5-x86-mingw32 |checksum:08ff9d374341bb8a4c5834dcad06922c11b52d88695bc5d8c1a7c146cdab4cba,ruby:>= 1.8.7 +1.9.5-x64-mingw32 |checksum:7508fb993d31b375a7b8ab745c7863f6432d49f9fab5dfdfdbf63ae7835a7d9e,ruby:>= 1.8.7 +1.9.5-java |checksum:581eb13f86c8558457ff3b8f4c10c109c6f9b1dd288cb87be482e78bb038f82e +1.9.6 |checksum:12fe4dad27e16fa1b9ee664b0ac93b87448ce7c32418bab74fdbdb6cc6087cb2,ruby:>= 1.8.7 +1.9.6-x64-mingw32 |checksum:12b602ded160511e15a206079154c5a28b3745df282e8e8f6cf2e58b2ff78ca1,ruby:>= 1.8.7 +1.9.6-x86-mingw32 |checksum:d1cc3d75e680458ff322cc60d85e7b4b8d2f1f5521811b38e3603d569e3f5862,ruby:>= 1.8.7 +1.9.6-java |checksum:8b93cebcceb96cfb277a0b465705082aea7b28058492b26c0f0fc6923a444053 +1.9.8 |checksum:e9a01a41814ea6781750177d7d50209b8867c9e250d86c282f368bb4174a005e,ruby:>= 1.8.7 +1.9.8-x86-mingw32 |checksum:158f61ea839d21ee07a944e96c33a49378c80b1336617b639e77d92795a5f8cf,ruby:>= 1.8.7 +1.9.8-x64-mingw32 |checksum:fafed6d111d324a0b0567bc236a53fa3f5c5a2272016354664ad2f80cb804ec6,ruby:>= 1.8.7 +1.9.8-java |checksum:562bc1c28092a6f34fbe4fc777665d13f70fd9aab1e97dbb7151145164eb07f1 +1.9.9 |checksum:192e953d01843f251372eb1e8d38513b971f6c52de91a6739dbc55efcc32ac30,ruby:>= 1.8.7 +1.9.9-java |checksum:2a1ec6392fb58a4d49c09a8efd62c0c71bd08198a1ff57555460a944250378d6 +1.9.9-x64-mingw32 |checksum:96b19a02b5544620df508ca5501c5936ab166d80664d7e0b431e478bf6381bf4,ruby:>= 1.8.7 +1.9.9-x86-mingw32 |checksum:1403f712c074193439b4985d2f6302bebd2f0cf5745a70818c459526bb8560cd,ruby:>= 1.8.7 +1.9.10 |checksum:b2fbef9933e975b0fc850547fca54a086c70a6fea5c659c5ceac037e6fbeb5d4,ruby:>= 1.8.7 +1.9.10-x86-mingw32 |checksum:24487bcf2fe7f43a0c71a3355cda63fd2f8f3b148c7c00a8bec421a1dfaef3db,ruby:>= 1.8.7 +1.9.10-x64-mingw32 |checksum:7d1794c08f4e55cf0867464d16c74ac70ed1d74652b4f88b3582182025e64a80,ruby:>= 1.8.7 +1.9.10-java |checksum:7a2ffe3c2e6f95c3a8b6373251ee8d8323de3c6777862c8e2a2c86848cb47e1b +1.9.11 |checksum:cd4f5f9daf27af815e20e1b85c55d0a3d63ac390b99d42a4c846b2aadb0d9d75,ruby:>= 1.8.7 +1.9.11-x64-mingw32 |checksum:4c81b668cef191ae04780c81ef6368917c3547ad8de887e32028e1fb96e7c95e,ruby:>= 1.8.7 +1.9.11-x86-mingw32 |checksum:75ef832c66a02f1b882d81c36cc4d68ffba046354304a25fc01a2446dcdd36a3,ruby:>= 1.8.7 +1.9.12 |checksum:2f1ce483ac7968f17e7a70212714758c096f2f6bed8950ccc0fc56713b6de5e0,ruby:>= 1.8.7 +1.9.12-x64-mingw32 |checksum:de75f8819c2d787a71855e4402d7991b59a0db28f888db4b403a40031a25079e,ruby:>= 1.8.7 +1.9.12-x86-mingw32 |checksum:9c538c5ab9abf362633e531b3a918b4a91976c9423505a997ad20d6e3d08b102,ruby:>= 1.8.7 +1.9.13 |checksum:6b0e2c6d25188e79e7b3c5f972d7d4ee234eb008d2f1efbc10fd6d29c3e55478,ruby:>= 1.8.7 +1.9.13-x64-mingw32 |checksum:8ea6b6d26139b1ce93fa8d48e32ddcf310e612d55ecbf3fcdb0fd4a395f97d40,ruby:>= 1.8.7 +1.9.13-x86-mingw32 |checksum:be489349097a999ebfb26a2a39a7fa9628504264c67b100dce792242c8b01737,ruby:>= 1.8.7 +1.9.13-java |checksum:3bd893a8629595fa986c0dad62ecf59055152a1419bd3886f564495053ac9478 +1.9.14 |checksum:d77d1ccb9cab032fff7ea2b7db1a895a2a2129a72c529e890f6b838c7bcd6cda,ruby:>= 1.8.7 +1.9.14-java |checksum:f9900fb01d52bdf8152e93c0f81f353c179d1549d7572794bb10d1b523a217a1 +1.9.14-x64-mingw32 |checksum:f78320eea3dac62d4f943e50724d3bcc10c2f53a4074d67deb98fb7917d7f4e9,ruby:>= 1.8.7 +1.9.14-x86-mingw32 |checksum:2341fc4cb6e9bd5bb08a04d1425af8fb500295456b03ce2fff5026391877512f,ruby:>= 1.8.7 +1.9.15 |checksum:caf23716cfabf75cc9122f98d2f7e11ad86ed6933e5baca8a5a561068150fd08,ruby:>= 1.8.7 +1.9.16 |checksum:dd4f98ed2a519b43f52206f3244e1cff0d9b5acdc04d769ce4a8dfbde2b0ce36,ruby:>= 1.8.7 +1.9.16-x86-mingw32 |checksum:944535ac60044c04ea8c06f64e2beaa1addf69b26df957c8c359ff231f57ce71,ruby:< 2.5&>= 2.0 +1.9.16-x64-mingw32 |checksum:6fe5eec5c1172e8e6fc894a72a9d9b244ad256c9933018a0908fec351978a6d4,ruby:< 2.5&>= 2.0 +1.9.16-java |checksum:e7a587e8884796c1df3995aa617db8d8b142293746a409ec51628c5484a3c853 +1.9.17 |checksum:479ff46dcfd8eda62f1bab5564ba4d5d76372a4764c06f9593bad97a48f6161e,ruby:>= 1.8.7 +1.9.17-x86-mingw32 |checksum:b06684a3335afd75f18e10eee1ffe67be6e837cec71f1210b148ce47303896d7,ruby:< 2.5&>= 2.0 +1.9.17-x64-mingw32 |checksum:4482958c08ce2eb9a6b479c905a4cc0cec58ae9bfb063dc5edf91a4d59ee4df2,ruby:< 2.5&>= 2.0 +1.9.17-java |checksum:c5ce955b9b247d5e3932bff5705073744fded4f163dc74ce810049d628264f36 +1.9.18 |checksum:a0df16d6a369a3306dd257adcb2ddef673e91b9740d0c5f77a98fde3ba288e0c,ruby:>= 1.8.7 +1.9.18-java |checksum:390ec00ef411fab2328eb430485698424976b5b2d0300708981eec72f2e3fd1a +1.9.18-x64-mingw32 |checksum:982bef3e2861e1e2ef3bee7dc6f2820d9f59cdb483b86227340f34a6e0891853,ruby:< 2.5&>= 2.0 +1.9.18-x86-mingw32 |checksum:36e36d97e15966695e7b4b5f01ff2a4f8230c653ac57c6562e9e83dffb47fa97,ruby:< 2.5&>= 2.0 +1.9.21 |checksum:685d98a305c038277e9d68ec88485d932c1eb6b8468bbed90443997841a04d30,ruby:>= 1.9 +1.9.21-java |checksum:ba39a6dd64f07d93cce741ad37e3048a2e4e8bbe3bae1ca019334bab53e163bc +1.9.21-x64-mingw32 |checksum:49b49309781d18fb45c138e90e9ef08081a0f49108f0f412ec97580d22d4ba4c,ruby:< 2.6&>= 2.0 +1.9.21-x86-mingw32 |checksum:1df8023ede7cb5f2c213d1f6640a2d8dde5ff648d9781a74dfbfd2b10fe11b4a,ruby:< 2.6&>= 2.0 +1.9.22 |checksum:491452c27e65a746f49a8df34e5bd3d95032bfababd322dca7953c4aebb59b9e,ruby:>= 1.9 +1.9.22-x86-mingw32 |checksum:9e950a5e7ac9e9ee807dce17a7f9351f917b0d874d5dd188ab05fac904ae843d,ruby:< 2.6&>= 2.0 +1.9.22-x64-mingw32 |checksum:3e030be78ebc2e5945f21201bd1772b744969a520232bd9c231f21730b309682,ruby:< 2.6&>= 2.0 +1.9.22-java |checksum:12f7557563b715effd6d08293d5660e89f7194d272511ed3bce97f163be9500e +1.9.23.pre1 |checksum:7a82b358f00da749b01f8c84df8e8eb21c1bc389740aab9a2bf4ce59894564ac,ruby:>= 1.9,rubygems:> 1.3.1 +1.9.23 |checksum:f993798158e205925aa1b80024f2dae1ce0f043fb0d0c39a531cc9bafdba867f,ruby:>= 1.9 +1.9.23-x64-mingw32 |checksum:6679bc81c3cef853621da43a910811f6c09ed901faa08e0d26afd4a3ce4c4fe5,ruby:< 2.6&>= 2.0 +1.9.23-x86-mingw32 |checksum:8f970ea88dc7e697a4e104d40ba285a68e049b2e9469d84eebfb569209bb2e01,ruby:< 2.6&>= 2.0 +1.9.23-java |checksum:078afaf8305610af3f48c02feeaa26759d55dea1f4221564f28702e35b53b561 +1.9.24 |checksum:937152dcd93b03e83ea5c815c1e28eae861033d9e07a70135d7c7546eeea23bd,ruby:>= 1.9 +1.9.24-java |checksum:9ee41e67456ac7aec21d61e8bf9c318b461e54db8a9863d07d8b0f0fe4887a27 +1.9.24-x86-mingw32 |checksum:b3a670646117f4bddc620d04ad106fcd5159e3d6ebed9f20439df871c5aca6ef,ruby:< 2.6&>= 2.0 +1.9.24-x64-mingw32 |checksum:e410e52afeefd67b7bdd597c01b7ee51e71c9fe9b256435488179bf90d57f5db,ruby:< 2.6&>= 2.0 +1.9.25 |checksum:f854f08f08190fec772a12e863f33761d02ad3efea3c3afcdeffc8a06313f54a,ruby:>= 1.9 +1.9.25-x64-mingw32 |checksum:5473ac958b78f271f53e9a88197c35cd3e990fbe625d21e525c56d62ae3750da,ruby:< 2.6&>= 2.0 +1.9.25-x86-mingw32 |checksum:43d357732a6a0e3e41dc7e28a9c9c5112ac66f4a6ed9e1de40afba9ffcb836c1,ruby:< 2.6&>= 2.0 +1.9.25-java |checksum:0c5b7251d26966a020a34fe0dc53c8ae4ff4543c39432ccd4da8f8f9b9c1a644 +1.10.0 |checksum:17001940b28a961c94251a39f0ae00b32c2d0850479b5978c971759591fc1749,ruby:>= 1.9 +1.10.0-java |checksum:8aab2b09a4b8f73b748f1731c8d431e5a8883ef0f34751a12bca9ab08c8f34b8 +1.10.0-x86-mingw32 |checksum:c7172be698174eb99e334e31dda61ef37651528e1e0179555168560177e732cf,ruby:< 2.7.dev&>= 2.2 +1.10.0-x64-mingw32 |checksum:44a9aa0718906f0d6070c358d24491893d95778e9713a664709ecf7ab8fcd2ca,ruby:< 2.7.dev&>= 2.2 +1.11.0-x64-mingw32 |checksum:b234226499dd2af3cce13cf379ef7f9b181063f1c7068aa185c3909aa9f0fe43,ruby:< 2.7.dev&>= 2.2 +1.11.0-x86-mingw32 |checksum:d6f1727e6dddc98b54851a415275828fd8b7e470dd097cac04033553f7eb335f,ruby:< 2.7.dev&>= 2.2 +1.11.0-java |checksum:71f60faea3d92d004f735d2fdcd827da2683430e0b7daf5d82036b95d7f5afb5 +1.11.1 |checksum:90ae2a7fe7ac4c0af30650fba8b75d93ff3611803c4937248118797ae5edbb1a,ruby:>= 2.0 +1.11.1-x64-mingw32 |checksum:5f601b059afb91793efe2aababfe2a368a8a6be1198aa4690fdece9204de9563,ruby:< 2.7.dev&>= 2.2 +1.11.1-x86-mingw32 |checksum:34f00ad25dc047f208eaf643a9f32289c5ce976b1d719f38bebf38b744992140,ruby:< 2.7.dev&>= 2.2 +1.11.1-java |checksum:59404b53c2ee37deb426d6bc9aa0bc7fd240c923cfb65ff567df3983a28aeaa6 +1.11.2 |checksum:7c75b4caa2cbe395b2f102f61cd59cb8e8535a9650bc0ae4585404d58a6e6a31,ruby:>= 2.0 +1.11.2-x64-mingw32 |checksum:9b556b705ab018fbf78fc3d8a3a7d1624d9a6647d06c043b3f955ab2c36967dc,ruby:< 2.7.dev&>= 2.2 +1.11.2-x86-mingw32 |checksum:36ce8d78ce67a71e14c45d22b821ecbc4c13480bd06245958d8b0c711e41cddf,ruby:< 2.7.dev&>= 2.2 +1.11.2-java |checksum:4c8a4b881604202f61d35e0c1b0d0e6d6da00428a7036fbfeb1cbe08cc14f192 +1.11.3 |checksum:6da2eb3c4867e64df28d3e0b1008422dfacda7c046f9a8f3c56c52505b195e81,ruby:>= 2.0 +1.11.3-java |checksum:d5956d2bcb509af2cd07c90d9e5fdb331be8845a75bfd823a31c147b52cff471 +1.11.3-x86-mingw32 |checksum:99e4845796c8dec1c3fc80dc772860a01633b33291bd7534007f5c7724f0b876,ruby:< 2.7.dev&>= 2.2 +1.11.3-x64-mingw32 |checksum:e955342e4a282aeb1eec10319872fc3df333fcbbb31fa03dd97ea13441960d83,ruby:< 2.7.dev&>= 2.2 +1.12.0 |checksum:5603967c3bd1213bdfac0abc2e780c80cb49b746ce2573e175bc825fffe8ce98,ruby:>= 2.0 +1.12.0-x64-mingw32 |checksum:dd1d7933dd15398243169d4f94374d0b0e2474be59129ed2ac3c8c97550febda,ruby:< 2.8.dev&>= 2.2 +1.12.0-x86-mingw32 |checksum:401c69765b481ff6494327a7fb0dceb416a9661c9dbad793c497963d77b5b0ef,ruby:< 2.8.dev&>= 2.2 +1.12.1 |checksum:d16674ae00279a7aeed705fa854af7d721cf5b0a4abf6a802f306e9f87ec5b44,ruby:>= 2.0 +1.12.1-x64-mingw32 |checksum:e7f2dea60d2966ac933d104fb9faa6fe55a47d5d03ffcdc001bade16f1d58ec8,ruby:< 2.8.dev&>= 2.2 +1.12.1-x86-mingw32 |checksum:f8cfbf386fba7be9d72dd6ed23b914293253585e3bd60773c23387867ea3b0fa,ruby:< 2.8.dev&>= 2.2 +1.12.1-java |checksum:4941ff05cd94805679b427b04c2515c70fb1f74cb9b88dfe1f731394b952a65c +1.12.2 |checksum:048ad01d5369f67075f943c16f1058f10663af2a66eedb87d921316ba1828e82,ruby:>= 2.0 +1.12.2-x64-mingw32 |checksum:89389307464a8a363040ab0360b89eeceafc1ade1b2ee6509b06b2594610a7d2,ruby:< 2.8.dev&>= 2.2 +1.12.2-x86-mingw32 |checksum:19a3a941cd3c8e33597d389397da44d2e66970c05d6c689982dda50856642abf,ruby:< 2.8.dev&>= 2.2 +1.12.2-java |checksum:57e8e55e6768afda68b40fddc360476f8b7a033d17fa88257869a0497fccc812 +1.13.0 |checksum:06f9b1eff8608f318a4261dd0b7ad8c82ac6ba2d7fc6dddcb97fcbe5e6253ef9,ruby:>= 2.3 +1.13.0-x64-mingw32 |checksum:23ebbc60b2af78cbd58bf7254141a073496f1454a8af6bec612b24459f3dc4ea,ruby:< 2.8.dev&>= 2.3 +1.13.0-x86-mingw32 |checksum:64a6404cf529d821faf272b79f05a045bccc3dad684f8974e0a6e3b61b6c2dd4,ruby:< 2.8.dev&>= 2.3 +1.13.0-java |checksum:581a9a3b4da882b867325b07eb4b86483687ff5c48e8e83f6058a8850bc8b0ac,ruby:>= 2.3 +1.13.1 |checksum:4e15f52ee45af7c5674d656041855448adbb5022618be252cd602d81b8e2978a,ruby:>= 2.3 +1.13.1-x64-mingw32 |checksum:029c5c65c4b862a901d8751b8265f46cdcedf6f9186f59121e7511cbeb6e36be,ruby:< 2.8.dev&>= 2.3 +1.13.1-x86-mingw32 |checksum:10d30fca1ddeac3ca27b39c60ef408248a4714692bb22b4789da7598a9ded69e,ruby:< 2.8.dev&>= 2.3 +1.13.1-java |checksum:3937c9ce28f0f9ce77e29182ea674ec0d0ff817267222c0967fe5c90761cc194,ruby:>= 2.3 diff --git a/bundler/spec/fixtures/rubygems_responses/info-functional-ruby b/bundler/spec/fixtures/rubygems_responses/info-functional-ruby new file mode 100644 index 00000000000..3d0507f4791 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-functional-ruby @@ -0,0 +1,16 @@ +--- +0.5.0 |checksum:8c4cac351f968800faced55bdac6dfcd118684369e76f50ca44a8ebb953601e1 +0.6.0 |checksum:a8516820a7f1eb6fa19152b3b23d285d694913fa816694126decd989c9ef8f04 +0.7.0 |checksum:4066fe716fd261aff1425e6e201c4447b2c652c3bfa2d00227ca4ae1bad3217b +0.7.1 |checksum:ad84f32b1778b7c0890d3e64507ac86c1880f903358c3ad43f7cbf67f723ee1b +0.7.2 |checksum:8dea360bc59844f9c1c2161f4669446f41aa1896c825932ab8c5622eea845800 +0.7.3 |checksum:c86c95244a198d77941de58e20cd63d742c8b69dd41602d8f8645a67a4b10f17 +0.7.4 |checksum:4f6497d381e123106c04448098e792ff5af2754e2e542e3f451e4b1fc81f6fd0 +0.7.5 |checksum:5cc69052ac8e3ee78e423a164c0d520f4882ba0467b7f656b9d8e247d681ecd3 +0.7.6.pre.1 |checksum:bca209cf06000a88cdcef43c411e3108c33a75ce0cc1f883514d6d8d10a8239d,rubygems:> 1.3.1 +0.7.6 |checksum:8759ee4d03e8c3174703ace607d81468ae24bd5a5a629137583e8418d284583c +0.7.7 |checksum:aaf9e7cab357e412ca19508ed0fc9a558ca7b92e66e50b47288a7f55617c735e +1.0.0 |checksum:4224931f3cb0ea622dd4fcb830076ac717cf6a8ceb808467f96e58b780736436,ruby:>= 1.9.3 +1.1.0 |checksum:193441618a673399ac16b54916bfe0cef14202b2512edda0c4b96c15ad9c0255,ruby:>= 1.9.3 +1.2.0 |checksum:c1526ba7d7b9fc530076aacac43558cbebbc449e36b83272edcfaab9d707828d,ruby:>= 2.0.0 +1.3.0 |checksum:2f562108c355f4a636448546482122e27ca2de4fcfcab0fee74bc4a067aceb26,ruby:>= 2.0.0 diff --git a/bundler/spec/fixtures/rubygems_responses/info-gemcutter b/bundler/spec/fixtures/rubygems_responses/info-gemcutter new file mode 100644 index 00000000000..1abea4c1782 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-gemcutter @@ -0,0 +1,30 @@ +--- +0.0.1 |checksum:466bf31e8eb42d3a5a77fad3ddd81921d817def4b7f0fa58d2c9a9000c80f1ab +0.0.2 |checksum:1b5a36a4064f7bb33ae7b284ee75730ee2fbad103c3b300ef6cf7041ce3ea75b +0.0.3 |checksum:a8aaa07d3376485dbd144fa0664c3595b66d060a6a2421b1191635c5fcef066f +0.0.4 |checksum:48dbd8bd87833fb4b896dd45632ec5328abb73259e71e904b2f146ef5a704bac +0.0.5 |checksum:734e384be9a09257fa3d43f85c23e5b03e6b4217332db27f593487019fc050e1 +0.0.6 |checksum:6b7479b3eeb6cdba283f5c4daaf814b11644e042175ee6d78a7389a1b17efa6c +0.0.7 json:>= 0|checksum:0bfc33e3b6e496017c486af146fa44acecda6ff27a1623518f724edee1daf2a7 +0.0.8 json:>= 0,net-scp:>= 0|checksum:c6ca23cc34a3ba84eb223391f710d6ffe0974667f13f60c97f70bbf7efa85dbc +0.0.9 json:>= 0,net-scp:>= 0|checksum:bcc78af63546f1e3a71ad20a5e54751401e94fb01a8d10acc7461dd6c0d5e6b4 +0.1.0 json:>= 0,net-scp:>= 0|checksum:797468e3331ee167a0a3a580198c457010ca1163db839ba7514f1b0e2177083d +0.1.1 json:>= 0,net-scp:>= 0|checksum:7dc28cb5ae73f6be8b089e185e2d830633ee9dcb5acd0a6d1fd39c556216a3a3 +0.1.2 json:>= 0,net-scp:>= 0|checksum:6761280116e228fda20ef469472b7bb372e657aadaea9ed7b7f3b3a5407f8d91 +0.1.3 json:>= 0,net-scp:>= 0|checksum:d4a0d20120eb83c6f5bff35807998a8524e3abb3a683deecd0849e499189bb09 +0.1.4 json:>= 0,net-scp:>= 0|checksum:be1d0d1290366fa52167c8f7251ef316f85b0ef352ff867cb3457169ff702755 +0.1.5 json_pure:>= 0,net-scp:>= 0|checksum:dfe7b3e85e838b6f2039cb36e925dbd03ffe874e00a9be52c91d2fce88f29c10 +0.1.6 json_pure:>= 0,net-scp:>= 0|checksum:7681bf5b84294fb410e9e599cc7d5c450b821d2f18234861509f1c9a473247a0,rubygems:>= 1.3.5 +0.1.7 json_pure:>= 0,net-scp:>= 0|checksum:fae5554c2a1e54cc1be7e752c5a6ae7337bbc7f21a1a3b99b0a3ca1acecd4e92,rubygems:>= 1.3.5 +0.1.8 json_pure:>= 0,net-scp:>= 0|checksum:3de8de3c6864fc75b85a67cdb613093b775c441fb153a32546bdbb1c857a6412,rubygems:>= 1.3.5 +0.2.0 json_pure:>= 0,net-scp:>= 0|checksum:9bcdce39b31d4955d0e5389ddbcde23462a3840e07a1cbc0a0e04b6e99f41b6e,rubygems:>= 1.3.5 +0.2.1 json_pure:>= 0|checksum:739051c05af2308de86cef1c55c0481a940820895f153a5b6af3b6f4e5eca82f,rubygems:>= 1.3.5 +0.3.0.pre json_pure:>= 0|checksum:72f6700717dd1a26461665c1f3e65e094f2dae4b6f69a9f98615b68381aa04ad,rubygems:>= 1.3.5 +0.3.0 json_pure:>= 0|checksum:33d2a80323ed15cb4d383abbd2fcbc21bf24e7cf07f1e0de4860e5222901351f,rubygems:>= 1.3.5 +0.4.0.pre json_pure:>= 0|checksum:0f12f4ad5e58d1bdd8fac233ccc9754f2323778a8286d029222a8b2924fbb665,rubygems:>= 1.3.6.pre.1 +0.4.0 json_pure:>= 0|checksum:2655f87ba787d7a5075f69d24413a7010fa00edc762579ccb7d2689f05ee3e9d,rubygems:>= 1.3.6 +0.4.1 json_pure:>= 0|checksum:db6e59989fa325d614c5d27dba8e4f33bb24f3cd686a2651de5faed5e5298b1b +0.6.0 |checksum:2352101ef0c1ef7a10aa269c292fa548d95951b222beba57ad00ac4338acd5b6 +0.6.1 |checksum:20b37cdf963807fcd4f04aac7b576196c5a58f3f6ec5089f9ad9684fbe5ecd07 +0.7.0 |checksum:0f0cdca9ded875e0ab8ec350549a63a9cbae6dca67beea56176ce5b213b53e85 +0.7.1 |checksum:e216b37b5e3e2f5e04ee1f772424f023eedf3548edf5628e7793749ed4b70d44 diff --git a/bundler/spec/fixtures/rubygems_responses/info-hashie b/bundler/spec/fixtures/rubygems_responses/info-hashie new file mode 100644 index 00000000000..a65450f9a19 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-hashie @@ -0,0 +1,49 @@ +--- +0.1.0 |checksum:5f20817aab11bcb743037b1d920658ab0e9a2e8a8e6e2ba815229f79508824b1 +0.1.2 |checksum:e0b6e188aa87306ba78da996f9c2334940360abf1c934d1a33d58d321a223702 +0.1.3 |checksum:e7618a611517aa03a0efdbd41775d48e16bc8768890b0c37d12084c5bf770170 +0.1.4 |checksum:e8db7b4693d9c3a251313adf52b852268b7512930dbfd8bec2f8335e16c7a2ec +0.1.5 |checksum:85d4bb6b54c4e210f6f32635964a0d76eadfbbf8474ae9474af6aae797728911 +0.1.6 |checksum:66ddaaf09fff00ab4a899d81806eaa9d471849a0f8920752ed7014898a354225 +0.1.8 |checksum:25c894ae947edc5f94ca69eeb6ed79b659ba93ddf24515ad2ed2b4b3549be4aa +0.2.0 |checksum:434149bfb26ddcf04b66a524de2aba17e728de5c48157d53cbff902379ce2f1a +0.2.1 |checksum:01919802f0294e190af5a2548622eb61e619b9c410c479bf00bf914f955ba26e +0.2.2 |checksum:e4c1ea09ffa59e0af781da4459089fd9df25a41d128b18be15fe0480db7d45ab +0.3.0 |checksum:1dfd4519b3cd5beea40bbcf0c2d76cb329546febefb78886ac49aa61151fd059 +0.3.1 |checksum:8b8c4d1fd7bcd9b22e39cf63032b5de64e848e68806ced1215a2ae50a1a2b4a7 +0.4.0 |checksum:fe3102978c8afc71343fd457bd6bb7347e193d3f4326eab7967339b8b8af571b +1.0.0 |checksum:fac8288383a58b175918528956fd10797d225fb7dba20c884da32bc358252471 +1.1.0 |checksum:687995a459fbf9f88d7336223388ad59b0700514d82625be81b30756870831ae +1.2.0 |checksum:7395526d7a3e2e1e65e7a0437f5ba72dc4f3b47c2ed5d12b98c6d8dfc3d1f038 +2.0.0 |checksum:fddd2d6962f2e9f90215d82cd08f0f510319401963ee59961c9ef689c6c75913 +2.0.1 |checksum:b5dca31fee641cfca922e8870bf9acdd5936acc28b490c1dc3c665943694c546 +2.0.2 |checksum:2ffec408dd851d7e5f07200b78006487da9eef724715bb313b7194cbd3559b2a +2.0.3 |checksum:3676aaa621b1bbfbc5856c2db2ab9f8e422a019df799a967c6a9bb2849c2327d +2.0.4 |checksum:1924adaa9dfc47d74ab20540f7f65c5e8dfa6e0a25fb50e17caea632ee1437a5 +2.0.5 |checksum:77c7ca7616cc3b1f115e749c24b85fb0926d50e94e19d8c75fcda2675152c63f +2.1.0 |checksum:fe2e37f9007a6ce325d93088e1b97bfeae0a0f88ed5d9ed048fb3e440c4df0c7 +2.1.1 |checksum:07cde48eb7b4b355b3139bbefdcb4c4027af4900c3f2cf791113559a2bebaaaf +3.0.0 |checksum:21cfea44d11c002757019107be94a79d2abe29b561fcd0e043e6f9d9d4fbce1a +2.1.2 |checksum:a9e1e4928bf4f5a5683ea9c7ef29e50fb93f72542f9a9550e205fe33a6568923 +3.1.0 |checksum:d043b75b87496d72b2984e27cac868877099b81d2871efb8debd3b39093278ae +3.2.0 |checksum:c18884028555c75b95693f62b6dd12c906d2087d64e0c09d20e3f42bad693e7c +3.3.1 |checksum:682b2e35fdff5b679dd519791dfdfa6bd370e4cf31bb56162118268515bfbdc8 +3.3.2 |checksum:99fad6bb323e965f72c82f08f86162858b97d9b1a4550cf49c180f211e3291a0 +3.4.0 |checksum:5e39f20c0087ff8fc415f378427c17dc8cd21fa282b7f26267a863b073655802 +3.4.1 |checksum:76dc47a37116e8e6be30e37389776cecd3809efa5e4e207f2d02de0f3d9a4f34 +3.4.2 |checksum:b68373c5f6589c5222638433918bc3e256acbaead7f883e5ec18420f507b17ca +3.4.3 |checksum:29213491e9f74158b9a7ec0806b3698039357209a6b24553cfd767f6418365c7 +3.4.4 |checksum:9dd69627730107041421f453eebef585251a50f6ec2720de0bce2443736598e2 +3.4.5 |checksum:1ef4d72f4d6146329f984838af92cd5c72a88451a84cdc063a46cb876cb7edb7 +3.4.6 |checksum:92ad8b7a3d4eaea3b7c858070a2f4d1a6e1e4dd3072c26bce85f439429f8c9db +3.5.0 |checksum:4ef5d299e06d8e6b663ced686c26abc80265f6a6c1bae5c1ecf39d7ee00c7592 +3.5.1 |checksum:a68ec7d09a4fb9b34ee04bbbc4ab8b224296cf5404fba154414bc6c565545b61 +3.5.2 |checksum:d4c8bb9aa91e876adbfdd041a58e250fd355cfb7e7e67e9781441256d41452e5 +3.5.3 |checksum:ddb9b777e2359a827093251ed8882602ed9617f54719aa4659a6edcb6523a02d +3.5.4 |checksum:a4fb1c03602eb8f3f8b0fa65d86c56cc940443c8a5ed5f294f40576feb74dedf +3.5.5 |checksum:5c52426ae505bd7b9a68fb5f134855f726b24dd94423e64f0d243c8b125cd551 +3.5.6 |checksum:27e2a7f7c52b3a927daa928546cce8fc540a16bc2dc4ad8e740cf209459b1588 +3.5.7 |checksum:ab1bfea321472acaf2e4d621469dd01977547787a876a2fb69a742e496a705c2 +3.6.0 |checksum:b097778abd066b5b506a07a226037b45f2f1d45f13f7ef552813b122aefb6d8d +4.0.0 |checksum:41f2a3cc0b7aa6549013e5bca2c92bed2d713f44a0edbe2ccb772a7014da3337 +4.1.0 |checksum:7890dcb9ec18a4b66acec797018c73824b89cef5eb8cda36e8e8501845e87a09 diff --git a/bundler/spec/fixtures/rubygems_responses/info-hoe b/bundler/spec/fixtures/rubygems_responses/info-hoe new file mode 100644 index 00000000000..5e549795994 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-hoe @@ -0,0 +1,128 @@ +--- +1.8.3 rake:>= 0.8.3,rubyforge:>= 1.0.2|checksum:53d565d00ca8882b63c414b6f027dc5938e3492e1c72f4c3b342e841254fdf86 +1.9.0 rake:>= 0.8.3,rubyforge:>= 1.0.3|checksum:c5c554bc5c7ed2a0f2467a3be24a83d75bd2a62a5c56d1aae228720784fc0f89 +2.0.0 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:7ad9470060081dfdb4d647338565500be2b2befeb92eb80f518556cc89e38cd2,rubygems:>= 1.3.1 +2.1.0 rake:>= 0.8.7,rubyforge:>= 1.0.3|checksum:34ad981a2b2244205251d2e282fdc397020f06bfa15915812e33ae1e7877393c,rubygems:>= 1.3.1 +1.2.2 rake:>= 0.7.3,rubyforge:>= 0.4.2|checksum:1bfe3deea66cb1ee65e974e134c47dd044aa1da15df9aa81e6e9fb42a4ecaf07 +1.3.0 rake:>= 0.7.3,rubyforge:>= 0.4.4|checksum:9e3d3858c5b8f66f87ba2b4f0e4e2711df3112b78e2feabcf9a02774eecc97c2 +1.4.0 rake:>= 0.7.3,rubyforge:>= 0.4.4|checksum:c595b84c8eb487041903984b6c8a1e7e31b7ab82aa0a53821ca48ddb05fe8571 +1.5.0 rake:>= 0.8.1,rubyforge:>= 0.4.4|checksum:096e7d7f698ebd1b6468660fb51995f4d0d13fddaf5f248e3665dba10b86b9e1 +1.5.1 rake:>= 0.8.1,rubyforge:>= 0.4.4|checksum:d052cb02b809f45112dca3804f77d66328229615a3f718fa4b25cc893b4e9c4f +1.5.2 rake:>= 0.8.1,rubyforge:>= 0.4.5|checksum:15d521c7017f7a3ba547ec066de85e6b075161478d2ed70c3dcb8d98cac9b77d +1.5.3 rake:>= 0.8.1,rubyforge:>= 1.0.0|checksum:e767e523b8f0f6b938308b865e14697b4c96673988cd27bb75002383098729df +1.6.0 rake:>= 0.8.1,rubyforge:>= 1.0.0|checksum:fa3eddb43a5cf1efacca1d27ebf33299781fb74228ead745376bf7ae95449156 +1.7.0 rake:>= 0.8.1,rubyforge:>= 1.0.0|checksum:ba77b6d853efc69cd04376e33b54c25b031f41b00d632c35e54e92ec7cfe3bcd +1.8.0 rake:>= 0.8.3,rubyforge:>= 1.0.0|checksum:c452d757b83bf613a7db432a9b5e40ddc5da1f1d4f1157ee5c21740753858f3d +1.8.1 rake:>= 0.8.3,rubyforge:>= 1.0.0|checksum:31aca468ff12dc1b2a81e33130ea940062f01d941aacf1a5c20d978d034e8ba9 +1.8.2 rake:>= 0.8.3,rubyforge:>= 1.0.1|checksum:34ccfdd9ee17e199fafcfcfe308d781487afff8202cfd64dfc010b1ad4b67ef4 +1.10.0 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:ca5a1710c3a978d2c30a329a99a275cea1841081eb9e4708fcf2b33ce9681590 +1.11.0 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:ec2a35ea57ca913b4fc469d20c71f09d12ece585a1e2c02a4d5f3246c8883273 +1.12.0 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:2ad56742d6600dbf92b8734b2ee11c97572f355cc38a1ae84e3d149c2796811a +1.12.1 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:2e30e9471b1b846e9b38d9d63a5dac58724b18ff7bd833f56fdda3966673dad2 +1.12.2 rake:>= 0.8.4,rubyforge:>= 1.0.3|checksum:80c46632497aee09fe1fded8c21092d1e57883bf1db67122d746e4562cf46c3f +1.1.6 rake:> 0.0.0,rubyforge:>= 0.3.1|checksum:05d7715b77c84e7ea8f3dfa902b67e002f3a3ff9d2b05d87104fa387952d3823 +1.2.0 rake:>= 0.7.1,rubyforge:>= 0.4.0|checksum:597023845b3400ef35cc8172f996ff287927ee4f9263c62ec2a706a948f2d171 +1.2.1 rake:>= 0.7.2,rubyforge:>= 0.4.1|checksum:a730edefe2f6470d91b60d74f8f864da3c5d19ec267f5c0efb615b9b78c15806 +1.0.4 rake:> 0.0.0,rubyforge:> 0.0.0|checksum:92967785b8812897ee58179a872270c5779d83f440ee991c922e94f07d07125c +1.0.5 rake:> 0.0.0,rubyforge:>= 0.3.0|checksum:2d5dac8706fed50d2a766b6534aa92b529c61e257bec0aa8a2e46247285f56f7 +1.1.0 rake:> 0.0.0,rubyforge:>= 0.3.0|checksum:bf8696ebe310c31642f6919fbbea0b1a55579da48a70d31675716375f44e0a6c +1.1.1 rake:> 0.0.0,rubyforge:>= 0.3.0|checksum:005fe854619cec768acb988841a2972c994c2948ada33636658b782b3a49f81e +1.1.2 rake:> 0.0.0,rubyforge:>= 0.3.0|checksum:c720566ee2df198f16fa860e7a853c116c882f62346c0752ac42a267527694d2 +1.1.3 rake:> 0.0.0,rubyforge:>= 0.3.1|checksum:d8f437c3523cb2304ddbee32790e73ec31d064a22005068121b9cda7c4a9c766 +1.1.4 rake:> 0.0.0,rubyforge:>= 0.3.1|checksum:ad92282602bbbf1c87e70de23672c27be5303bca012cb3eb389e2fa99339a466 +1.1.5 rake:> 0.0.0,rubyforge:>= 0.3.1|checksum:bdc89c967028bdd78a16f0df309d0b4ed93682d116b0f405848c2fe6b6c38826 +1.0.0 RubyInline:>= 3.2.0|checksum:ce495a5293df7fb3fd5ac660a9cc3c5decb8f423141cb815985cb29e99cb2203 +1.0.1 rake:> 0.0.0|checksum:b738279ecafca3ef609b467f79d57f780df04ec6af2288a84d27f36304513a1d +1.0.2 rake:> 0.0.0|checksum:55e2d3803118d2db85d99ce27984c5845d7433c608c724e2631657cafa00ed85 +2.3.2 rake:>= 0.8.7,rubyforge:>= 1.0.3|checksum:3a90318b42ce02a019c8d248dbb42a9ce281f5ef9bf4566cefe6b27128b851ab,rubygems:>= 1.3.1 +2.3.1 rake:>= 0.8.7,rubyforge:>= 1.0.3|checksum:7ba76ed27922ded50617dcb100800734def7c8ddea7e5a49d1caf8c4be13bd8e,rubygems:>= 1.3.1 +2.3.0 rake:>= 0.8.7,rubyforge:>= 1.0.3|checksum:2ec0ba0b06fc31c8d76b5b7247e2ef39c047ba6c27fd0b6600f018ed064316ab,rubygems:>= 1.3.1 +2.2.0 rake:>= 0.8.7,rubyforge:>= 1.0.3|checksum:b070dfd49c09907845e17ec67a47b9cd1fa8cb1ac3ded43936d926ad95b61469,rubygems:>= 1.3.1 +1.1.7 rake:>= 0.7.1,rubyforge:>= 0.4.0|checksum:8ef3beaaa4204c7fc02882cf955acb5b2cf4ca4ebf91acabb1ac1ee558e5a7c5 +2.3.3 rake:>= 0.8.7,rubyforge:>= 1.0.4|checksum:35617a7435805799b5e6e3dabae655341921e03cb52b55a3fdc6e61ae1b2541a,rubygems:>= 1.3.1 +2.4.0 rake:>= 0.8.7,rubyforge:>= 2.0.3|checksum:b4ff616d19eff09be41e8af523d176c6cee4465547b1c04cb2df4627eed1e1cf,rubygems:>= 1.3.1 +2.5.0 gemcutter:>= 0.2.1,rake:>= 0.8.7,rubyforge:>= 2.0.3|checksum:b9476f4c5f6f82314520dbe9ef6e9e2777cf6bcc73ef3ad6197ab5276b369928,rubygems:>= 1.3.1 +2.6.0 rake:>= 0.8.7,rubyforge:>= 2.0.3|checksum:36d7009de42d23162c3c9b3355231906080868c07774db006c2dffd43b6fa723,rubygems:>= 1.3.1 +2.6.1 rake:>= 0.8.7,rubyforge:>= 2.0.4|checksum:7a404c09a998e82b4a7c62ed0c92033cc7632ac3cdfcc9693834e0b39fe7d0ef,rubygems:>= 1.3.1 +2.6.2 rake:>= 0.8.7,rubyforge:>= 2.0.4|checksum:5d0bae8da7731aa4d2964687b398c8453c2d0832e38f3d06cb332ab0caf92686,rubygems:>= 1.3.1 +2.7.0 rake:>= 0.8.7,rubyforge:>= 2.0.4|checksum:06e37c59aee91914245e1bd466467642cb6521081ace91e36bde41a7d695d6d9,rubygems:>= 1.3.1 +2.8.0 rake:>= 0.8.7|checksum:a2094978e0a5659d39266eebc0c56f753b7e25c9a81f633ca029cfc5a2af8b44,rubygems:>= 1.3.1 +2.9.0 rake:>= 0.8.7|checksum:d6eba095aa2fe98c5329aa11f68ab5c6fff8e5608d96cdf7ffd190ff5fa852a0,rubygems:>= 1.4 +2.9.1.b.2 rake:>= 0.8.7|checksum:9524152ca95d845b328aabda376dbf8b1744576066f2dd1ee7676d20c4d7a22b,rubygems:>= 1.4 +2.9.1 rake:>= 0.8.7|checksum:7ded3612e58f7eb0f9da072090d8cb2e9aaac814193db670fa85d67e831163c1,rubygems:>= 1.4 +2.9.2 rake:>= 0.8.7|checksum:c10d143af538e7f89d488c11e6f61bcb64009af72f346d1f965639bb57756220,rubygems:>= 1.4 +2.9.3 rake:>= 0.8.7|checksum:a1365375d230a9b713a27574b98d2bba1bb8a4fcb484025e022d2bcfca4b2b85,rubygems:>= 1.4 +2.9.4 rake:>= 0.8.7|checksum:7f0ada50d1f37f64ab4864c6b79981840dcc34e809b94c7a0dc8f6a5424ded9c,rubygems:>= 1.4 +2.9.5 rake:~> 0.8.7|checksum:94d0786fa8e79da9d51a2cd2d8e1b69cfb97dff394b556c4204db9c8a8361d9e,rubygems:>= 1.4 +2.9.6 rake:~> 0.8|checksum:1e9d353bdc45d5d1e7bd7923fb9831eabfedfd812dae6e456e151755d975babd,rubygems:>= 1.4 +2.10.0 rake:~> 0.8|checksum:e5733c79787defaf34dd41b634b2447bde559acb9c81745936db9cbe3a68b9be,rubygems:>= 1.4 +2.11.0 rake:~> 0.8|checksum:b6a626df859f7cc7a6107fb144ae780a9d21cc06898c473398aa473b377be0f4,rubygems:>= 1.4 +2.12.0 rake:~> 0.8|checksum:4af133b65da7843cbe69355e63f0824248fbe0ccdf643e0f33417ca7fc956e83,rubygems:>= 1.4 +2.12.1 rake:~> 0.8|checksum:20138357c367db4ef5215997a4ac65e4df6b685693a65305164e3c9ab264d36c,rubygems:>= 1.4 +2.12.2 rake:~> 0.8|checksum:f2f1fc512bdf7a544397eb966c9ddc54a4176fcf51799f7a12707a9e2a697216,rubygems:>= 1.4 +2.12.3 rake:~> 0.8|checksum:f68488c8171201a72de14b030180f15c66fc195af0eab16474a52938daf0103f,rubygems:>= 1.4 +2.12.4 rake:~> 0.8|checksum:759ec4e341c2ccb6ae18a62c0e0ebefd8d1e5d4572a57369d763c53d8049db57,rubygems:>= 1.4 +2.12.5 rake:~> 0.8|checksum:600ab263807c229b6ee98d1d1a2b48f46d329ccff30458822729b6d686be10f2,rubygems:>= 1.4 +2.13.0 rake:~> 0.8|checksum:ab1f5d55301a9e92d34e58d9063c7d28abaf61223292ff04c1a869bb57786eed,rubygems:>= 1.4 +2.13.1 rake:~> 0.8|checksum:ec6cf6491d7fd3cb35eaa46d51c634bc3d444916c7cd256a5c3a63a97ce3a428,rubygems:>= 1.4 +2.14.0 rake:~> 0.8|checksum:2cd6e68dc323fd3fb7bce9ad115fbca709c5ca842750a4bcdeea89dc757ad3f5,rubygems:>= 1.4 +2.15.0 rake:~> 0.8|checksum:126f729618d31d4def36d1b7351da6314eee05d6884fd6415d67d825b23da1a6,rubygems:>= 1.4 +2.16.0 rake:~> 0.8|checksum:991e0d0fb2fb64259655f8c308bb4e68bb429dd414a6df5f99638fde4a13fca9,rubygems:>= 1.4 +2.16.1 rake:~> 0.8|checksum:81d7e61d930ee49ce04031fff967dab44aff25caa0f3408823ee26aadce7a4f1,rubygems:>= 1.4 +3.0.0 rake:~> 0.8|checksum:e2df64a24096c13289af25ecbc7d20afcdb94b7103acc4d6eea20c941c9cad93,rubygems:>= 1.4 +3.0.1 rake:~> 0.8|checksum:bca84505b5402cf57cbdea628e6880adc82232aa133ce1a4d5d9965debaeed3b,rubygems:>= 1.4 +3.0.2 rake:~> 0.8|checksum:93a3364bf2c89d51cb7faabbef22b47e7dba1bae0d8a3b2ca544a42ccc944524,rubygems:>= 1.4 +3.0.3 rake:~> 0.8|checksum:9a180a5dd13ed2ff1c23b3a7b7b44fef03e7a211e4cc5a05f52a475f3aa83ace,rubygems:>= 1.4 +3.0.4 rake:~> 0.8|checksum:38086a375f1b2cf5c86957549fd54b6e8b9dc4fa9c81319fc2c52bcef75ab30e,rubygems:>= 1.4 +3.0.5 rake:~> 0.8|checksum:c84ad9f8acb060963baf7ddf79ab28ed3f24744aaa1f1ea932d979e4b5c07337,rubygems:>= 1.4 +3.0.6 rake:~> 0.8|checksum:abbaeb93d68f33f5f47f77c2958df32b7c3e040580f917fce53f4e239d49dc10,rubygems:>= 1.4 +3.0.7 rake:~> 0.8|checksum:12c5fe5395c6c3c98cd269bb25bc77e42ea10275eb9074c60b8ee30e427704a8,rubygems:>= 1.4 +3.0.8 rake:~> 0.8|checksum:dc662c688123bbcfe6d55efeecb49d9dcf4b96f7a52f4daccccae0d8497d1b0a,rubygems:>= 1.4 +3.1.0 rake:~> 0.8|checksum:d7a7a3c6b50b9fa72409f488a8ecc58f180bdb415541a76dd0ceb40c410f2645,rubygems:>= 1.4 +3.1.1 rake:~> 0.8|checksum:17d33e80b6ba0fe4688f14842645d0fc552bb8ae8f3696f87317ca38e137ac93,rubygems:>= 1.4 +3.2.0 rake:~> 0.8|checksum:62565936f799d6f0c3f37b0dc896144d1783a58c306a9cf456f200eab156d5fb,rubygems:>= 1.4 +3.3.0 rake:~> 0.8|checksum:20abaed4db2e79ba891b2362b2d30f0bc1b79c052d13a7256afd39f1a467ac48,rubygems:>= 1.4 +3.3.1 rake:< 11.0&>= 0.8|checksum:406eea71e557810ddf2b4dcb3b34fbebf4a9d7dd1c1a967fa0fc83c37bccfbfe,rubygems:>= 1.4 +3.4.0 rake:< 11.0&>= 0.8|checksum:636dcd4cbf3fa9455647b914ec7df36231a74496fa2f3fbe9c2216af5a0a42c9,rubygems:>= 1.4 +3.4.1 rake:< 11.0&>= 0.8|checksum:faaf7fec12ed1e772c92f4cbcec44b99f6d2a951530d13fc7b596c4a74297c4f,rubygems:>= 1.4 +3.5.0 rake:< 11.0&>= 0.8|checksum:10d6971e7686b92fee8450b95e77e26082489a49dbf1c00e6f1f66d382e05dc1,rubygems:>= 1.4 +3.5.1 rake:< 11.0&>= 0.8|checksum:97e997828693aec4c3a8f57a10e6b73bda821f9aa41ac4e731aa15044630d201,rubygems:>= 1.4 +3.5.2 rake:< 11.0&>= 0.8|checksum:30ff1a281f2faa5a7b2da9fb111e442797ca6b78ba7e978432d1b0e0d6fed2df,rubygems:>= 1.4 +3.5.3 rake:< 11.0&>= 0.8|checksum:97dc6e83d53e521795019a0b392463e4246b091f3dbfd6d221c4960695bdbfe5,rubygems:>= 1.4 +3.6.0 rake:< 11.0&>= 0.8|checksum:c0e07fe162bd12b383e01e9d77cc2ce8fb1b6cd5221c8326c0a1f202a933ccbc,rubygems:>= 1.4 +3.6.1 rake:< 11.0&>= 0.8|checksum:fc29de3ae75857161d7a8382f45b3dcf85fcce47a01b60bc9058971c252734b8,rubygems:>= 1.4 +3.6.2 rake:< 11.0&>= 0.8|checksum:555cbaabf7cccaefb3c1f395016251e20cae132453e0f1b1646dbe073d6a2ee2,rubygems:>= 1.4 +3.6.3 rake:< 11.0&>= 0.8|checksum:e099a7dd352fdcefeafa63bb8ab436f1c5ea7d7089f5966c95e9557b38a56177,rubygems:>= 1.4 +3.7.0 rake:< 11.0&>= 0.8|checksum:b6d87f0c675febf78efc4fffec55b345bfeb2f894b62e91b4ae5e1a5d1b4c6ec,rubygems:>= 1.4 +3.7.1 rake:< 11.0&>= 0.8|checksum:836b4cc2093f70fa73ec215d39f3331cebf402067ca4ebfcef3a12d9ff6ad953,rubygems:>= 1.4 +3.7.2 rake:< 11.0&>= 0.8|checksum:fd1be03e04ca3d0715a721b5762393a52c96a1942a6508ffa4acd918ace02c57,rubygems:>= 1.4 +3.7.3 rake:< 11.0&>= 0.8|checksum:cb3fca1d7d84f77b539397db32510395282ee6b6c303f4e8f0a31fd1306272be,rubygems:>= 1.4 +3.7.4 rake:< 11.0&>= 0.8|checksum:13bca97601872139add4d7d4d1037adc8e45f73df63e6f606be5c81c4c83b57f,rubygems:>= 1.4 +3.8.0 rake:< 11.0&>= 0.8|checksum:1b9db88d8644e512afc0ff31fe99b626cf0b6989d9d971de78fd54664b5219d5,rubygems:>= 1.4 +3.8.1 rake:< 11.0&>= 0.8|checksum:d54095cc9e9c146d6a2247099b1138bfaa32ea791f7e3a2715a23d8afd202e0f,rubygems:>= 1.4 +3.9.0 rake:< 11.0&>= 0.8|checksum:d5d22c31032c1e8d8aeec43a52aa377fb6689ebf835d6b9837786d0a085594f1,rubygems:>= 1.4 +3.10.0 rake:< 11.0&>= 0.8|checksum:9a5ca66801cf9ccd59c98b641ad3fc8901a5dc02074f6aa88662c7581caf7a5f,rubygems:>= 1.4 +3.11.0 rake:< 11.0&>= 0.8|checksum:3d9143316730d7d625336b8a2b0844423b950355fe407b30383ffc5a0c3c1e81,rubygems:>= 1.4 +3.12.0 rake:< 11.0&>= 0.8|checksum:2102325882d9bace24b6c5479ae80cb9a372da1568710dd00dbbde45405a39d8,rubygems:>= 1.4 +3.13.0 rake:< 11.0&>= 0.8|checksum:a74013aa6749ab10f0db92e9ad56e735d407104baa0981bf0d10dc2feacefef7,rubygems:>= 1.4 +3.13.1 rake:< 11.0&>= 0.8|checksum:18414316a39bc828b4b943aed6817774ce23642fa6b51450b25ae596e7084cd5,rubygems:>= 1.4 +3.14.0 rake:< 11.0&>= 0.8|checksum:a90dd0d48dd02cda5b8c0206f09194414f90e7fdb54db7192f36f7e0c944a4a7,rubygems:>= 1.4 +3.14.1 rake:< 11.0&>= 0.8|checksum:dc2a2cc4ce1d856fd57a8e1d87455eae4025c9b1380e362fb75397de8ec323e5,rubygems:>= 1.4 +3.14.2 rake:< 11.0&>= 0.8|checksum:3ae482a41a2f80cd487958b2e4f7edf39e323c26165f30c5daead97f7a835a7f,rubygems:>= 1.4 +3.15.0 rake:< 12.0&>= 0.8|checksum:b2e68ea2fc075b34d73b6a63f30dd9e308f1c67ddca86f0192ba8e93bbffc86d,rubygems:>= 1.4 +3.15.1 rake:< 12.0&>= 0.8|checksum:bffcbb976fd34bbb5e7fef9bd90ff7849c1c388a2f6615fa83b256b0162c7fc7,rubygems:>= 1.4 +3.15.2 rake:< 12.0&>= 0.8|checksum:f76b3503ba8dc1906ccd37e293a979b54dbc43ef49f6c2effbeddc9d64723ee6,rubygems:>= 1.4 +3.15.3 rake:< 12.0&>= 0.8|checksum:4e772892e8f23055adc7f8579153fc37b0636cbcb31e6e57b1e06b7fd55de717,rubygems:>= 1.4 +3.16.0 rake:< 13.0&>= 0.8|checksum:8bee33376af7dacbd0f3440614453589e60df14c13471c938ab6124bb8b6280f,rubygems:>= 1.4 +3.16.1 rake:< 13.0&>= 0.8|checksum:863d49e3fb35dafb1b0037a8e8cf5281ae941a50a1e58e8774b48ee503e27b4f,rubygems:>= 1.4 +3.16.2 rake:< 13.0&>= 0.8|checksum:6a383474035c26284e7a2c77eaf8a13b444279037ae32b57abcae91c856d068b,rubygems:>= 1.4 +3.17.0 rake:< 13.0&>= 0.8|checksum:63aa2e42475eb17a4ab2b9ae5af3797f4dd927bf4f400985dc393df3dded620c,rubygems:>= 1.4 +3.17.1 rake:< 13.0&>= 0.8|checksum:2bec4dc1f287897dc058795a12196914db91061d476823d5a257787be2dc02dc,rubygems:>= 1.4 +3.17.2 rake:< 13.0&>= 0.8|checksum:8eb5d4050ba6033f3b9e6db34683a91f955a004d1d750fb521b4ccc64a6321a0,rubygems:>= 1.4 +3.18.0 rake:< 13.0&>= 0.8|checksum:bd46bafe1e935bc9d728cbe8da1e395ee2fdb3c0f69187680fca51f332781246,rubygems:>= 1.4 +3.18.1 rake:< 13.0&>= 0.8|checksum:a1af446cff7ee955e4bacf5b7a8756c5b7aa4b85111a2bccf08dfc03a080a4ac,rubygems:>= 1.4 +3.19.0 rake:< 13.0&>= 0.8|checksum:1835a3149c5f96e685406d58741854767b10badf002657a17c339f58c89da3bd,rubygems:>= 1.4 +3.20.0 rake:< 15.0&>= 0.8|checksum:767e286f04a1987552ea267218b742deafebcdfd119f3e28b81ccc601526acff,rubygems:>= 1.4 +3.21.0 rake:< 15.0&>= 0.8|checksum:c459d31c794557a984e0fbf11a919f5389b41ed852753d0bde52bf6a8a052d62,ruby:~> 2.1,rubygems:>= 1.4 +3.22.0 rake:< 15.0&>= 0.8|checksum:4972d83b1e2ae0f7012bbb2253794faf79110904898fb2b903d166c17b403357,ruby:~> 2.1,rubygems:>= 1.4 +3.22.1 rake:< 15.0&>= 0.8|checksum:f5c375f03304ab4c3549f424e62fbaa2070f21773fc9dbada72b9e7e5b4ee86c,ruby:~> 2.1,rubygems:>= 1.4 diff --git a/bundler/spec/fixtures/rubygems_responses/info-http-accept b/bundler/spec/fixtures/rubygems_responses/info-http-accept new file mode 100644 index 00000000000..2305ebf204a --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-http-accept @@ -0,0 +1,15 @@ +--- +1.0.0 |checksum:b12756cfc55536a3530bd5765104a4a0c8b09c0962385b6c5322b09ed7919656 +1.0.1 |checksum:4d1b3d4d4365a1413ed92ffcacc52c3c0f928a8c4ca8a4ae7e34fcae072a6eed +1.1.0 |checksum:99cd59aa07ea4393e4842b82f9998da43a889b40a7cfd69c7dfe1f2657f7bcd0 +1.1.1 |checksum:bf24923e14e43b9995b34d73171a749bc9aeb86a1f33be8b4f7764599debf572 +1.1.2 |checksum:e994366473641f09fc88612a1db9d08a0e17876ef6d940e71b9884e4919b04dd +1.1.3 |checksum:d1cc15b0a5519a16e163d292cbb0cf106322359d61f0122a555fade63ce00efe +1.2.0 |checksum:750a8ac88594fa604ce6e3b85a97801c2ed7de4525729b9e850b08f9b51b67ad +1.3.0 |checksum:950155582781292b09b5bc9f326a32d6cda6d3b3db02e9f5ca49300178534730 +1.4.0 |checksum:677be6bd256929616a4455b1aa47f02464c321f898d9937e6aa5de528a4ba7da +1.4.2 |checksum:29ca3873636a6311cb25a689ecda12102fa6de6b08e7713ffc8dc8c6d266e95b +1.6.0 |checksum:0735d99220286d723d2c8589f6aa62e7b6b57b60eb34d4ecefd32b00c2d29757 +1.7.0 |checksum:c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 +2.1.0 |checksum:655093a9d6b27858e2ecec83e5381f064dc4ee5d046bd60ff5602c01be426058 +2.1.1 |checksum:b138d6dfdfe77439e9183850b03671df76b525c6628f17cd47acbce2a0d11f31 diff --git a/bundler/spec/fixtures/rubygems_responses/info-http-cookie b/bundler/spec/fixtures/rubygems_responses/info-http-cookie new file mode 100644 index 00000000000..1bf35733b35 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-http-cookie @@ -0,0 +1,22 @@ +--- +0.1.0 domain_name:~> 0.5|checksum:6f8f0da287845fe8372ecfca118f3ce5688a9d2a724b7b1c7333f65a84c49121 +0.1.1 domain_name:~> 0.5|checksum:a98b42fe94f32886182d304b1dc76812b6e4cb6148a6ce86a65ee8eef827b0e1 +0.1.2 domain_name:~> 0.5|checksum:6dd80bf7a15a970464a44f3b560866ed167b8cfb6ee2e37d3809827c4fc73c81 +0.1.4 domain_name:~> 0.5|checksum:9fe283f9abd8e641a9fb6130eac6b1f4aa09a16140f9b7f6a7ad39e7f8adc650 +0.1.5 domain_name:~> 0.5|checksum:db4b4c59710f6e4b9f59e6b171948d93c6c44c546a8ca28dbc9d25332664e97b +1.0.0.pre1 domain_name:~> 0.5|checksum:c4c793d6f00fdfb9f25bf099eee422c31d22e75754b2faa8e701306113aca89d,rubygems:> 1.3.1 +1.0.0.pre2 domain_name:~> 0.5|checksum:08751b02cb26e9282554c20930d80e736df0daf7d1f1d2d247766d0376697d0b,rubygems:> 1.3.1 +1.0.0.pre3 domain_name:~> 0.5,sqlite3:~> 1.3.3|checksum:d903874cf773fc420ac395b7be5cd531754722a835bb58f3aeb6253eaecd2bce,rubygems:> 1.3.1 +1.0.0.pre4 domain_name:~> 0.5,sqlite3:~> 1.3.3|checksum:77180dd40292b270eb3871de8dfdcd1df1f0a0c85ad6b1c21c53cc25f7b254ad,rubygems:> 1.3.1 +1.0.0.pre5 domain_name:~> 0.5|checksum:63b8c3a43e0c2e333c222509709b948908dbba7aea84423f1c8961218bffcf7d,rubygems:> 1.3.1 +1.0.0.pre6 domain_name:~> 0.5|checksum:a7c031b93a01d582ffcf1740b84d64eebc090a56949eb3b882541c0d6a1de9e3,rubygems:> 1.3.1 +1.0.0.pre7 domain_name:~> 0.5|checksum:7e7f15ff2ec67dc7f383d3c2c8bb07e828959fb92d904f9bfb69a7223261a02c,rubygems:> 1.3.1 +1.0.0.pre8 domain_name:~> 0.5|checksum:40786f3efc6b8ba2d22249f3cbc8396f57bf989e6ffb4a31d9858d054b259ded,rubygems:> 1.3.1 +1.0.0.pre9 domain_name:~> 0.5|checksum:fc1bb2d0bba5f7ef016c7bf06daa262dd94b72abe4e29bfe8c5ac9147981221d,rubygems:> 1.3.1 +1.0.0.pre10 domain_name:~> 0.5|checksum:b9539a5bc46c5d601dbf50f35ff9b760e65ce853171a83e47b3e5c2ec25b66e7,rubygems:> 1.3.1 +1.0.0.pre11 domain_name:~> 0.5|checksum:930c5a2e85daff1b2cef98c4e6b1291da6efa183599130ef1280f181fbaeb87c,rubygems:> 1.3.1 +1.0.0.pre12 domain_name:~> 0.5|checksum:e7d49c735fe1a8392c43d9e86e7412d3073e606613afcea0e94b20fbac9af41b,rubygems:> 1.3.1 +1.0.0 domain_name:~> 0.5|checksum:b2bb95fcb012ce89d0a7b75b0e91bec7e5d610f528415ba2e742d03e436a4052 +1.0.1 domain_name:~> 0.5|checksum:a91daf2f18d3fe9d38f8aca291c578eea1ad621f3807f7ce3b41d4587384ef3f +1.0.2 domain_name:~> 0.5|checksum:bcc1b18b5bc3e9302542c9c7f68f1ac0c3100a65dd2831786172e8676773e233 +1.0.3 domain_name:~> 0.5|checksum:2f11269d817bc52ab2af2721e89a377660a961078de2a3a55fc696d7897e8c00 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-i18n b/bundler/spec/fixtures/rubygems_responses/info-i18n similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-i18n rename to bundler/spec/fixtures/rubygems_responses/info-i18n diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-ibandit b/bundler/spec/fixtures/rubygems_responses/info-ibandit similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-ibandit rename to bundler/spec/fixtures/rubygems_responses/info-ibandit diff --git a/bundler/spec/fixtures/rubygems_responses/info-ice_nine b/bundler/spec/fixtures/rubygems_responses/info-ice_nine new file mode 100644 index 00000000000..c5bb3ffeaff --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ice_nine @@ -0,0 +1,14 @@ +--- +0.1.0 |checksum:deed731a5e49e7090b4b91498e0002e4a91c8fabfdd557d795d419445293f39c +0.2.0 |checksum:42e68f5ece3cfee6128b1dc4bd6546e7040a917969ba08e0692c93c86e76fd70 +0.3.0 |checksum:973a94eddfc36d9d8f1578d75f4cd79f8aff45391af072cd5bf260c91323da25 +0.4.0 |checksum:8d271fbdfc622cde90b95bed4353f17c25c325144510a277cfac023d6de24677 +0.5.0 |checksum:531578fba745f84af81ecc548635cc7176b014c42900b45ad91bef1215db7240 +0.6.0 |checksum:7ec5692067b8bedf36a09c62c2d236e99ba8ceb9f4da424755b11155993b3271 +0.7.0 |checksum:1aefb4ab1c1ed3f19a2f2b9cd1ace59f595c1260e0408e0abc56cae90ea3e579 +0.8.0 |checksum:3a5dc19204514f2b7cba37fdf96c672a0e0dc22091fe967dfd40f8047599a8b3 +0.9.0 |checksum:ffc3c9a914941c32b7ad808a5b70b1ff1a9a98d02222859dfe08ad9784a410f4 +0.10.0 |checksum:108f7538b32819623db949583895a962f5934dcfd183e7fff8b7e6d70db04c42 +0.11.0 |checksum:99679628239977d27c13422d574b3232b9552d8fa83c000c14a84564798657b2 +0.11.1 |checksum:6d56968f338a2c99d52ab30e0f2651d2d948d1885684c63868d95008f027c744 +0.11.2 |checksum:5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db diff --git a/bundler/spec/fixtures/rubygems_responses/info-jruby-pageant b/bundler/spec/fixtures/rubygems_responses/info-jruby-pageant new file mode 100644 index 00000000000..5d006a2ac6c --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-jruby-pageant @@ -0,0 +1,11 @@ +--- +1.0.0-java |checksum:562c7e944d59e42219964b250264773be209762e341bfac0f531ff0300ca502e +1.0.0 |checksum:f5f8d6b8f4a54bebe26fabc612517a5a71b905b4515b75d1792ddb02c119ca0c +1.0.1 |checksum:96abcb7a10f8621f205aa7229e424d0a0d1093e15b0771931f29be80a9e7f35e +1.0.1-java |checksum:a39398b4652a6c02e892f65cfd452575fe7c6157204d9cbb1fe1f05e035abca5 +1.0.2 |checksum:60efb3688bc8cef8dddff148ec548a40c5d17e34882d8b4dcb4e2df79fe66e9a +1.0.2-java |checksum:1a7a1bacbf59696bb4524d2c1c6df63155543c6c9a821edf28ed1f8bb7debcfe +1.1.0 |checksum:25dc42855e4427c43fb15387708f8760379ea59c8779bfe7746a2794b08a761e +1.1.0-java |checksum:b5a3904c7a480486b6f403c5854f87234472926e403119f25e7aa4d64c6d668e +1.1.1 |checksum:942566d306a79d8f496f17d482ea2afa2834f4ea0aaf59dc0b243fb580d5f8cd +1.1.1-java |checksum:d5c7f1d9e6379c38b6f80343eb668e2b1dd37b6e278fafea02008f2bfd95dad2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-json b/bundler/spec/fixtures/rubygems_responses/info-json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-json rename to bundler/spec/fixtures/rubygems_responses/info-json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-json_pure b/bundler/spec/fixtures/rubygems_responses/info-json_pure similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-json_pure rename to bundler/spec/fixtures/rubygems_responses/info-json_pure diff --git a/bundler/spec/fixtures/rubygems_responses/info-memcache-client b/bundler/spec/fixtures/rubygems_responses/info-memcache-client new file mode 100644 index 00000000000..b0567c6c7e1 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-memcache-client @@ -0,0 +1,26 @@ +--- +1.1.0 hoe:> 0.0.0|checksum:a56068df5ee34178cde325e4c53399d4e5f90424811e116bdbf05672cc867b95 +1.2.0 hoe:>= 1.1.0|checksum:6c792f0e6373ff30f79d0d4551b30d33027bee37e1bcf9bc6fb46914a4ad1e0e +1.2.1 hoe:>= 1.1.5,ZenTest:>= 3.4.2|checksum:e04e98b3b9273e002174a276bf2e43bee04254d0f22900fad3800b08225897a4 +1.3.0 hoe:>= 1.2.0,ZenTest:>= 3.4.2|checksum:729457aced6e03e6613794ddb434b1dea11a3e49af742dc969bfdca5119f0c9a +1.4.0 hoe:>= 1.2.2,ZenTest:>= 3.4.2|checksum:ae07f406b1db62e4ec5656dad5d3efe896012a224b8f4f4fc478b03851fb9310,rubygems:> 0.0.0 +1.5.0 hoe:>= 1.3.0,ZenTest:>= 3.4.2|checksum:0617f6b27411890907c7e102c948d557d419539ed5fa5a9c25a8699326dcca3d,rubygems:> 0.0.0 +1.6.2 |checksum:7f2264903553976095faaf433701b8c62743177adea80c1902ce67bd8f323997 +1.6.3 RubyInline:>= 0|checksum:1bbf0666e2775faa12cf8175f6773e7ad1e004fae56d866fb928afd17f2e13b5 +1.6.5 |checksum:1079206cc00ad7e652944acbec98bdadd9ff19b84d0d54d3264f4a945339ca0a +1.7.0 |checksum:09c9a7fdf1c350b8e032c96745ea73e0b2bb8f328a3e4bfa8de9a43d14818580 +1.7.1 |checksum:f9ac217f223e6723b204eacd8c948bc71b1cc99d090f430e85b6f27413978d2e +1.7.2 |checksum:30a0523c0ad5cc2f588415c2dffe4d1cb74a784fb68aeecf2cb837fce3640de2 +1.7.3 |checksum:c2aada686de587129a7133a539e3c5222ebc2b94d8555155a9ed40db4b5f25f0 +1.7.4 |checksum:6d43fb09638af230005cb633913c7ee7eee5f4fa6bcd530fada5aeef36721738 +1.0.3 |checksum:c3b9be59bd70166390675afd33be50cd5636e6e132930a1ad8e25558c6e7abb8 +1.7.5 |checksum:a61d998d745753a0ab8e5bab807794fcaad1130a061f24e9b5983b0f14ab2f76 +1.7.6 |checksum:cdc144883a5abff4c6acdcdbb44ff9f0fa54105054dfc670ccdde7de51eb484c +1.7.7 |checksum:fea3e002c6330dcba74f78c63140919af935e3f045330a94a79dbef955dad34d +1.7.8 |checksum:f67f949bad8db4886d1001815bb6328a5ab049faea9a2ed74aaf2d940e70f9a6 +1.8.0 |checksum:19a420482f9b7e680d1ccb307183bff20a09024ffc2aec428f3ab8ecff653bda +1.8.1 |checksum:92e479510a5e881990e92feb7eff212a9898a8d977b0e4e6eacb837f30b6c223 +1.8.2 |checksum:fce78370c81fa4cd9026960004fc0314eaef809a39fde836bd5ea0b725f3fae9 +1.8.3 |checksum:97b5f0c0221d117f5371bfdd9e95e8b991d3f57790b335c94335075799c3511b +1.8.4 |checksum:9a350cd7feacd3630176eca67e099cb79f44bb1aabbf1776f64404bb2510690a +1.8.5 |checksum:1a2d57e9bc0d00553aef16ee9413e2656f07e53cf569eb6e2d795f0d9c85d285 diff --git a/bundler/spec/fixtures/rubygems_responses/info-memoizable b/bundler/spec/fixtures/rubygems_responses/info-memoizable new file mode 100644 index 00000000000..2c78724016f --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-memoizable @@ -0,0 +1,8 @@ +--- +0.1.0 |checksum:c1e0ef5fc22a4794a04b77b3bb566d80e0a29e12dc998c4b838a9ec53421a19d +0.2.0 thread_safe:~> 0.1.3|checksum:4ca485747a792528d19373593ca32251aa8f7af24af97bcd6c42b3a2f0b0c1dc +0.3.0 thread_safe:~> 0.1.3|checksum:ce4f02e653c7645308251669bef0b5d2c1e5b7ee5a69a9c389c3b92b9d056bb7 +0.3.1 thread_safe:~> 0.1.3|checksum:12da75d99fa627465023a4e37cd3871a24d954550e4c58cc638fe9c45ee8070d +0.4.0 thread_safe:~> 0.1.3|checksum:99e1a341f0208bd3822565741a3dcd66766b35107ba2192e2ec3138e13430f76 +0.4.1 thread_safe:~> 0.2.0|checksum:16436fbe909eb6d94eb6a65dcf2b21b580f9374c29b631ea1257f2d7d4758149 +0.4.2 thread_safe:>= 0.3.1&~> 0.3|checksum:acf4d2280fea019318e61cfc5e69077dcb3c2126817ee596ffd76d0ddf5e826c diff --git a/bundler/spec/fixtures/rubygems_responses/info-method_source b/bundler/spec/fixtures/rubygems_responses/info-method_source new file mode 100644 index 00000000000..296ce300216 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-method_source @@ -0,0 +1,29 @@ +--- +0.1.0 |checksum:031a321bfd84029e3a45b9f5e19692b4d75e00062353abad02d94a5fa4e30003 +0.1.1 |checksum:f58ff0c322f5fb2552c7b083c9f888ae9a6a8a7900eafb621bd0cd4a2cc03908 +0.1.4 |checksum:da786c92bad29841214eb0d5898fe2db3a47ad789b84eeb14fc22991d4f3b076 +0.2.0 |checksum:ab2cbe281d4bec9ff9bb075a0408db910501b59fbf9118ab791549cae170b3c9 +0.3.2 ruby_parser:>= 2.0.5|checksum:42555959e1829a6854a124b4d01f3ea8291a2271cf6fa032b4aedecbcb566c75 +0.3.3 ruby_parser:>= 2.0.5|checksum:1812647ab07d7f1443d3f5a9ab42e10b3858ba672c5fb2099defda3358b93e5e +0.3.4 ruby_parser:>= 2.0.5|checksum:19200170df27a0f2f4d5dd5e003d175c0b346b69ea9dde85e715d5787edd9df4 +0.3.5 ruby_parser:>= 2.0.5|checksum:4d4150c28aaecce2abb74bdda524c3dc7d445a2a7e4a85f88ea219ac6f39a09e +0.4.0 ruby_parser:>= 2.0.5|checksum:755c5ba1eab78ac54198bef6d310f07bc3b8ab54f27c52d16babcc383160c71f +0.4.1 ruby_parser:>= 2.0.5|checksum:59273f2316f6f35c3eaf90d651cc0a872677ddba630048613604308d82027bc1 +0.6.0 ruby_parser:>= 2.0.5|checksum:309e9daa9d75f0954e597c112a42d3e87f66fb9fcfb73b3970f9242ee29280b0 +0.6.5 ruby_parser:>= 2.0.5|checksum:c29bf3173ad848e6e1768d43232f12a3a95a287878b1ac23d3b99c5e75dc7d2b +0.6.6 ruby_parser:~> 2.0.5|checksum:88163260208af7c0ffee227f4ce593fc3b2e8c52fd47e041d2a0d5c5bdcb4c63 +0.6.7 ruby_parser:>= 2.3.1|checksum:a756ec0a61dbedc95048c8acff641d8cb80075044fb67d2d9754a039bc8c072d +0.7.0 |checksum:b19bed636fb1f0bb523c578d0fb045e90c3e218e9014a2c4171b8eb2a0ba6a01 +0.7.1 |checksum:ec4183e5828f6bb97f9fe30c6caa4ec21ad69257eef7a70465dab4a8b336b2f5 +0.8.pre.1 |checksum:90b38c3e06dba83e1f706839326418364480931966d05cc2c52cbf0093e22c58,rubygems:> 1.3.1 +0.8.pre.2 |checksum:83591f863f00af385a72fee2875f9a20f10414e2a35e9a41e946b8431c69c85c,rubygems:> 1.3.1 +0.8.pre.3 |checksum:2a36888b0b978154a02536b692cd30c00fe215f76631f0ec684b6d2c6b425358,rubygems:> 1.3.1 +0.8.pre.4 |checksum:103967d0e940ac0f5d4bb111554399ca44c2d2c0dc91b329997a5f217cec2a4e,rubygems:> 1.3.1 +0.8 |checksum:246c3d1bd3ccf6f4d22a025d671826c722f7cadb24f06ea74f6975557bab2a81 +0.8.1 |checksum:997746b618752232ba6a224cc701161702bca28237520241deabe7d1c128e95e +0.8.2pre1 |checksum:1eb82f81173b51018393afde47032a9cbf980fc719828a653e35f3928f9282f6,rubygems:> 1.3.1 +0.8.2 |checksum:c2e9d0f4ebefd6b37efe38fe2964337b1d315fe198cad850681fd2da0027b1bc +0.9.0 |checksum:f6fd06ba997de0eb6622545b8623a804352c2c9c4a44a362a304bb3d64101277 +0.9.1 |checksum:21e93aceb2c0dbc95b637c8cfca0c50a45975eb8e650351771102728dfde63ca +0.9.2 |checksum:980eba674be3d05dee1889d6cf1ce25735955a6394c6e38d7d2035dcf6e771df +1.0.0 |checksum:d779455a2b5666a079ce58577bfad8534f571af7cec8107f4dce328f0981dede diff --git a/bundler/spec/fixtures/rubygems_responses/info-mime-types b/bundler/spec/fixtures/rubygems_responses/info-mime-types new file mode 100644 index 00000000000..0cad5024981 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-mime-types @@ -0,0 +1,38 @@ +--- +1.16 |checksum:c393a1cb8d6901e89b2eabc6c1ca2cfd46f3067c78848daf62cfa7ddc53b97ea +1.15 |checksum:3a86e71044e47117ae69c863bcfcb6b3155359859949aa072846c33f40d56ddb +1.17 |checksum:669921467139e034cf2c52c5655db4c8ae33818e82770cd2041fba6266b0927e +1.17.1 |checksum:7e86967b0cf64e0ba84da198714adefc168ea79cdb43537e46fd39a6b8d955f2 +1.17.2 |checksum:d768170d4fa10e8e0d1346c02df90e6255fa9cb7f6a7ba16ccd4ae6e50af9744 +1.18 |checksum:f880433aa2aae29df84a6ccb6e58cbf0bc65876571ea5a86906d96f654de4702 +1.19 |checksum:4658ed1c3945625e2b1464061ef5d1163d2fb101a14fa9bc04d1ec347fa684ac +1.20 |checksum:9295c7d7b2fd2d9e1c65163fe7bb7ac06007d30ded747ce92d27ce5aaf385312 +1.20.1 |checksum:60d1af10f6592f02b2ac12af3596c61b1577712400627f3b989f5b22f256878e +1.21 |checksum:3c86d4e828026ab6bb70a7620e68beb16b3e82606bbb25a1b560e229d428bde2 +1.22 |checksum:cf5b89a808b53202bc1622bd08ca3fd021708d5980db0596594ea4e2d646b0d4 +1.23 |checksum:fa29671c5f80a5dbafe3111814f1bf289af91f422c1d1fa4c10bda63fab305b2 +1.24 |checksum:2ad18e0ec707cebd9bf5f46283a2524090b407f538e02b988ff0c55d23ab3cbd +1.25 |checksum:ee2dc47f195959f3b0729e889c3dabfce7ba0cf9e04cfba31eddcb02e885a641 +2.0 |checksum:d3e53ba4162d4ee93ce75e644c7fca5503fad1c512277b9ca80ad43aa8103ae0 +1.25.1 |checksum:88ef3c596481678710ffd4018fa40f1999b02d97babea39682ba7d5badd21f56 +2.1 |checksum:9ab591babcb268cd8ad4a7a6f9ebcfeab5f8c5332b47a587cade7224f921e448 +2.2 |checksum:fb20b5fb6b25c2b8abbf74b21b82c6e14ae1e3ed5146ec23d305333c9c360bc6 +2.3 |checksum:6d13658a740d7ce3cbd285a1a60f7f42db56923c37a33cae8ed5252cf2e71548,ruby:>= 1.9.2 +2.4.1 |checksum:8dab4996ba9e5af58f801c0b57c12678bc927c44831d89ee01eaf71eed102a07,ruby:>= 1.9.2 +2.4.2 |checksum:dd2abe5850102ad0033ff43d3772e92a337495e7fc3b3d142b704f5d045502fb,ruby:>= 1.9.2 +2.4.3 |checksum:38f29a89a273d15bfb99e839c6fe5cf7c463f223dd7ac5ee3c9287b1acd6d19a,ruby:>= 1.9.2 +2.5 |checksum:229fbe5d9682c2b360dde81b92e98e1deec021d88bdb5e51cded8f96b8c7537e,ruby:>= 1.9.2 +2.6 |checksum:60bfc2ea06a51949c770c0e3efc44ae3b661316d67f19beb3a00002cf6baa616,ruby:>= 1.9.2 +2.6.1 |checksum:5b16d655397aa5cd8b4108494f60f64b4e18a2c92dc9257ff74ec64284dbd9ee,ruby:>= 1.9.2 +2.6.2 |checksum:b595583540f1228dd24978c0f87cf1918e4f2c709fe5d517fb6706cbb35ede8c,ruby:>= 1.9.2 +2.99 |checksum:c2edc50e5752ebe1b9d6195804653b896a5fcffeef8dd5575c384ddbe0db2ac3,ruby:>= 1.9.2 +3.0 mime-types-data:~> 3.2015|checksum:2a7f8a73648ee1de0e97eb9692e8ca3761bf420c8df64024f21befa4d060d2ea,ruby:>= 2.0 +2.99.1 |checksum:370e8182e838c7c295d390b3e48ff7ba69e7b87e30dcdbde7bd1a909a0529d53,ruby:>= 1.9.2 +2.99.2 |checksum:7f7629866989706ff69ebf696d212d3201c24f0d6c435ca2a2b4109938d8961a,ruby:>= 1.9.2 +3.1 mime-types-data:~> 3.2015|checksum:75949321c3f55e6618d0596016059841c26168342ec1ee4e641053bb66fa0701,ruby:>= 2.0 +2.99.3 |checksum:899678f8802057a90669a88d0300ac75fb24ea3db35ecaa61457700c7247490e,ruby:>= 1.9.2 +3.2 mime-types-data:~> 3.2015|checksum:2c240b6a71f95742c2ab98f75292bf2af6294e5984bb4b48a8615768ebd4f55b,ruby:>= 2.0 +3.2.1 mime-types-data:~> 3.2015|checksum:bdfdb9b3aea095e63a16ac1ba9ca4bf4e4b7a6d4c8e67e106117ace50f9e81fc,ruby:>= 2.0 +3.2.2 mime-types-data:~> 3.2015|checksum:93f308f0b6754b0ca50dd1982b817f65b8946f6a34bd3db6bd3d8a5265f05d3a,ruby:>= 2.0 +3.3 mime-types-data:~> 3.2015|checksum:933ef7ba38c3e4d5561cbff4aaf92d9d76b97df77b7ab1083e3f2df9220af43c,ruby:>= 2.0 +3.3.1 mime-types-data:~> 3.2015|checksum:708f737e28ceef48b9a1bc041aa9eec46fa36eb36acb95e6b64a9889131541fe,ruby:>= 2.0 diff --git a/bundler/spec/fixtures/rubygems_responses/info-mime-types-data b/bundler/spec/fixtures/rubygems_responses/info-mime-types-data new file mode 100644 index 00000000000..67c555a80be --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-mime-types-data @@ -0,0 +1,10 @@ +--- +3.2015.1120 |checksum:2cc2d944557aacac49d15709247be3fba2028f65762bf474cea0212e80dfdf11,ruby:>= 2.0 +3.2016.0221 |checksum:f6ce9f679d796f4d2647a93ca3d2c3bca4399924a744cdc3f5063a6b8195cf17,ruby:>= 2.0 +3.2016.0521 |checksum:7542bccff06d70c4ad94d1cf10b7dac6bd89958356e5d0d7f6447168c819be12,ruby:>= 2.0 +3.2018.0812 |checksum:ac4553288225756970f0739798ff0f1116988d56e0ac15a525553ec115b89b1f,ruby:>= 2.0 +3.2019.0331 |checksum:8a70976e9e3268e01df23bd8fdb503d80b285548f4754671b0875496c2bb00d4,ruby:>= 2.0 +3.2019.0904 |checksum:ffd104bb350b0620db9a5a08b76cacee30d33cafb0d9be0597ce8a7869da5121,ruby:>= 2.0 +3.2019.1009 |checksum:b09bb0076f4d209d21de5f81569edffdb6e53d43f891e30edfa12433980ba6a3,ruby:>= 2.0 +3.2020.0425 |checksum:90726aa1a94f0ab1fd4109b36d8ed1c0e87a7c56fcd277d63fb7306e040636fe,ruby:>= 2.0 +3.2020.0512 |checksum:a31c1705fec7fc775749742c52964a0e012968b43939e141a74f43ffecd6e5fc,ruby:>= 2.0 diff --git a/bundler/spec/fixtures/rubygems_responses/info-mini_portile b/bundler/spec/fixtures/rubygems_responses/info-mini_portile new file mode 100644 index 00000000000..95ee9cc61ee --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-mini_portile @@ -0,0 +1,19 @@ +--- +0.1.0 |checksum:e34ea72d0fac99a40a5775c4b772df340f1993171e335a7ce329c8e85708607f,rubygems:>= 1.3.5 +0.2.0 |checksum:4ea8c199e3fc5b6c0334482e6b6610a0f31d2b6932725b618e34ac518e3cfb4f,rubygems:>= 1.3.5 +0.2.1 |checksum:9e38605fa3ade344c158c0798469e116aea64eea9aa4cf8197768cee5fd71ec4,rubygems:>= 1.3.5 +0.2.2 |checksum:eb4f46b7311e61afb70d68ee76195277787da8fd910335baf0ae9b957965a3cc,rubygems:>= 1.3.5 +0.3.0 |checksum:e1fdd841dd69a7f2febc35e58e05618d5614076e071249b3998f75aa7bf517d1,rubygems:>= 1.3.5 +0.4.0 |checksum:ba2d79b6b9e764ffed09ce42f16dc111a1de1ba3b0a0007c33b344f6e2a443e4,rubygems:>= 1.3.5 +0.4.1 |checksum:f0a8ef01a6751a9abe09de89e1aef99b5fa35381ef982552ac3b3ca450429d77,rubygems:>= 1.3.5 +0.5.0 |checksum:b578fdf855a7e5b8e4c6906f6a226342835da191b14cc00525c43ba6e372e695,rubygems:>= 1.3.5 +0.5.1 |checksum:efa9058711e1d382b29fd413c728dc2b49c8e6492b558677a17faadf20b54e31,rubygems:>= 1.3.5 +0.5.2 |checksum:8df1e7053a27818aadeb7817ff3c7d7c0e62e2e04f81971dc8ebbf3f01988435,rubygems:>= 1.3.5 +0.5.3 |checksum:4826194ebfee89f41a8592ec88bfb05a3f26de8b460164864165105a3461879d,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.6.0 |checksum:762b3e241362de24b2eb2bb1b98638399b931e9e51bece5f8e2df7611eb16c26,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.6.1 |checksum:7434cd632cfcf6bfd680cd72bec9e17788b1d28d2f6d50504b5969822681ea1d,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.6.2 |checksum:5c60cd85db3df6b279e9a6807954c596dc0ced359a10fcd9b49969a6aa8d7d40,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.7.0.rc1 |checksum:9282c5f85214d6cb7cdfe19a90979db83baf514e04090be9e4853d5562f3b708,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.7.0.rc2 |checksum:d2b9776ed8d1f91d88c10d634d29ce6be9133b356bd17caede9b4bfb328e610d,ruby:>= 1.9.2,rubygems:> 1.3.1 +0.7.0.rc3 |checksum:e8c0e379b370a13b53a9c40e671f0131238afaf9a5b1182c89bcddad55f36421,ruby:>= 1.9.2,rubygems:> 1.3.1 +0.7.0.rc4 |checksum:27efdbdc368d55f261ab1666c4d5e55e941978596f772fb0fd45e0586e0deba8,ruby:>= 1.9.2,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-mini_portile2 b/bundler/spec/fixtures/rubygems_responses/info-mini_portile2 new file mode 100644 index 00000000000..4173c25ea08 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-mini_portile2 @@ -0,0 +1,10 @@ +--- +2.0.0.rc1 |checksum:48844096eac785f79e38a7dc76e0ddf653cd1db2f5ca9a7e705ad6cb9ad48f5e,ruby:>= 1.9.2,rubygems:> 1.3.1 +2.0.0.rc2 |checksum:9678b3a49b566f995434a90078c02c39f1d5d5b21c5dc0ea8ff7bcf4bbe56d9e,ruby:>= 1.9.2,rubygems:> 1.3.1 +2.0.0 |checksum:147d9f63e3dceb4da9e2036a93b9a6d45b12668c55abe0696f70925aeccacd14,ruby:>= 1.9.2 +2.1.0 |checksum:0b0e83fe0fc190640a93c48cef0c8e1f1f40f77840d82c160fefc1b07a5345f8,ruby:>= 1.9.2 +2.2.0.rc1 |checksum:1cce3bc9e4a94f5a606bf37c1c740d4262f148fd1789ff9393c512416dd4509a,ruby:>= 1.9.2,rubygems:> 1.3.1 +2.2.0 |checksum:f536d3307de76d8ec8cbcc9182a88d83bdc0f8f6e3e9681560166004fcbbab3c,ruby:>= 1.9.2 +2.3.0 |checksum:216417b241ff4e7b1c726f257241eaf223e3abbe6ec2c6453352dea6a414a38d,ruby:>= 1.9.2 +2.4.0 |checksum:7e178a397ad62bb8a96977986130dc81f1b13201c6dd95a48bd8cec1dda5f797,ruby:>= 1.9.2 +2.5.0 |checksum:a7a7a09d646619d8efb0898169806266bf2982c70cc131fd285aa25e55bdabc1,ruby:>= 1.9.2 diff --git a/bundler/spec/fixtures/rubygems_responses/info-minitest b/bundler/spec/fixtures/rubygems_responses/info-minitest new file mode 100644 index 00000000000..da23a0e4a27 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-minitest @@ -0,0 +1,117 @@ +--- +1.3.0 |checksum:f71d0ef47d89b413a5afeb6713067ace7a1740ae984d7eeeafbe313be8921c31 +1.3.1 |checksum:4c7f3482738ee3d360d70834177afe9663b4f07ed9efe76882c157a73fadc34f +1.4.2 |checksum:f80732ca1a6fb5648ab3c04016b1230cceb468cda55aa7d4b3eea9b146a385e8 +1.4.1 |checksum:4393f9b09b13117fda872b12ec45ddeff9bde0fad67298b1f0168c71a9dca642 +1.4.0 |checksum:0e403b9de1ca3420e4d56b2f0953114d96156abc3b655407a921344d80b1f9bb +1.5.0 |checksum:f34df58fdac0a9be80733151d94ee0e6d5483ab2a6eeec3915be5a9c54729d34 +1.6.0 |checksum:33a15178c58ed6af7bc8ec9d7f84b0b07112327ce4957d56ea8420fc94736061 +1.7.0 |checksum:e616ca61757efc7df1c1176a69ec29977fef8e3ff22dd91f25dfc925f26dfcd6 +1.7.1 |checksum:13c8b80e5bce8290fa09ceb6a6bcad1d65270200e1d3cad7fb032f1c8bb3deff +1.7.2 |checksum:c2c3d8130a2ee25fba74a897d0f9cbd8ebb602c34ae9d656be1a8646ff40efd0 +2.0.0 |checksum:5c249f6c36c86fe33d7a7eb6c67021c8d63611ae37375ae6217e9ae5f69166c2 +2.0.1 |checksum:0303c4f0323d7efdef2b60d8f12a4d13956c996d0b2e118285dc280864fe9ee3 +2.0.2 |checksum:c0ab2bb4358229f8174079fa741b96368f4602bea810f426cfe03f35e674e9f0 +2.1.0 |checksum:1d30f327e0fe7c83dd8a3efebd78d92cd8a570ba7941e9705ab938260ca48edf +2.2.0 |checksum:d647344449b9cbc178252d774648e1a5bef29d1993df21e87b6f66545939c90c +2.2.1 |checksum:fdc21c3811cb07a1c9a22b8dcf065933677ab25be6a4222e12834288e6460ca5 +2.2.2 |checksum:53b435f3ea09757f1221bc0763c35ed3d4f5f138d8b81d2947a7a3cd050a7252 +2.3.0 |checksum:f4717dd011eebe9a164b6a55af614097dcecafd53adf9fd64059ea4cba0ba864 +2.3.1 |checksum:cc6383e473e7135508d5c2b13ae6af564c520f0e1ac94e42f23c3d54c7746618 +2.4.0 |checksum:9afe27bf25bad3e782a1d6d7decd4e82cb2f203c9dd123cb1a57eb185d09743f +2.5.0 |checksum:fc782be0f81f3a76398df5a0dd2dc71f6b611f824062a4c555526b8bf59310d2 +2.5.1 |checksum:a42461c8063444efdb234b2914422001ccf40f9d15fc2a247922bdfe0d360886 +2.6.0 |checksum:1b486dc0d6c47e35cf1512427165e366b6b04f01a76abdd6d7bc38cdd4ce88e4 +2.6.1 |checksum:49be847b3bcda0a95b2ea9e67ae2896a3bef027ae222656d3c6ab72fd78ad109 +2.6.2 |checksum:967cde3179b1587be242d9d02ce37c8598c7ed1f4ed68c0ef7cfbefbcbbb5a06 +2.7.0 |checksum:120d695466c785486cfc6bf10fa5a840ab247653da728f350abbb15db0bc5c42 +2.8.0 |checksum:2a3a744741995e9063373cb2ae8c0fd288fa816baffab34662fca18450fd26a6 +2.8.1 |checksum:1c265730228f63030c136058d6eb15b0bd05edd1e2f0daaf40dbebc4d187de02 +2.9.0 |checksum:1460114487bacbd64ef8d337a6f9111c88a6b2fb614c3260744013f02500c3bd +2.9.1 |checksum:cd8f271df6e9f0070a20f44f771439e69203ff335261ed37b99b455041d1feac +2.10.0 |checksum:bc3cf29b335655ce2c150e5dab44a701825a59f4dca0b6b4d5522673f81f14aa +2.10.1 |checksum:609e04aa7f6436f1db639a08d21274b2cdd81abd4cd9ef2b005339139f5e9fb7 +2.11.0 |checksum:6961ca5d0dff49d48af09b43320c32b347bc4c7f2aa1eede707e48e145d78880 +2.11.1 |checksum:cb5644134542b5ae2a7edc85f7997d1cd246759a55d75bfa4f695b7c53325bab +2.11.2 |checksum:37918094d9cee91fa4a95f3e429ca2c9c5496501c5b6373d7e33183817889f63 +2.11.3 |checksum:b82690202efaa5c3a6a24e6c7e3842474d2086d90416c06e87dc7bb24b0d1a77 +2.11.4 |checksum:566945ebc3b541d4242942331cef2cd3e9d33b408dcf32126ffd204252e65ffc +2.12.0 |checksum:2374104eeeaa0bbee2793ba138dfac3cac12708e50d0db403d9d940fcac48f29 +2.12.1 |checksum:e370691de6026cd7c0f7a11d0942ee29502cbed4316983d52819484e2abc4e9c +3.0.0 |checksum:56c7bfebca9fed3510e647808c14f861d0087cdba1ff8dc7335c1dcd236c7abf +3.0.1 |checksum:cf09472ccd8fc725717795b87de0b4ce2fa375a3178581758bd2475a04d36b48 +3.1.0 |checksum:4a66e49fa332f224cfe85ffa242458b3af46428ba8e1072af5841dc83a69e90a +3.2.0 |checksum:d403b11dbd4642ece169d7959c1ffd8e11f29671548ccded4c1ab249930f9501 +3.3.0 |checksum:bc549538703261c341a9232ef384481f860ba7bbdc67530fa967c337a8fbd387 +3.4.0 |checksum:39c709b64f44af627ea2cc425f8c04ce726d19e08c94d0892c3bfd70109a7da8 +3.5.0 |checksum:74f1fe409e4e9e9997cd7865bf3e9df9c1452d7abce375120df39bf05e3ddb6e +4.0.0 |checksum:584c315b7d6c501da6fd4e235f4fddc768294e924835ba3aa90ed60ef0c2af1d +4.1.0 |checksum:8e777f715ffb9f324ce3cfdeb1ee53a7273b9e342ab7eb6df22cf3ce8eeba78a +4.2.0 |checksum:9069ceaa9ca8dc5a548c761583831a42a5be67619f233616990b1bfb27800e1b +4.3.0 |checksum:45f2b094b2b84ddf5c59549a50581f007f6d950d8cc2f99b7b530fcacf0ba304 +4.3.1 |checksum:f17c1604161e2c68455ac8056a74afb17ec31df95972387735a3e0e35fabe04f +4.3.2 |checksum:f49fa5aff864d98b6dcf6e8d622297d808e278cd877550093b007517627c3ceb +4.3.3 |checksum:a4cefb7fbfd1d6fd366ad74b269a463eaef9a4c9e605c521b5d22199a58cbb1b +4.4.0 |checksum:53b2d03667a986df34cc7091fb20a2e162d71fbae7b56553174ea566541ad572 +4.5.0 |checksum:a26df2d95efbbac38b4a534f2a293ff45b2205e22ec592782681bf649fe60590 +4.6.0 |checksum:a7cff0bcb920dc79d9e5eab51e141f5d16f775208693d45f456dd6e9f702f1d5 +4.6.1 |checksum:33d8b6351254002c4c5d529d17637a43e809a8a9d04d26dda6823fd9f338daf3 +4.6.2 |checksum:fef67bcecaf130f6b5afe4b43587a3f7bcbdd9d8a265bd9b41d9a5e26929efca +4.7.0 |checksum:b25ea9dceea6de921331ae7ca74158e9878ef5acce05ff3bc3ae1d293f02ccc0 +4.7.1 |checksum:71efde29f6ea975a3f0d8b2063ce01601bd70c6b0221a4e48dfd2cd18e0b9708 +4.7.2 |checksum:1e378b2a10f675cbb1a195085d2c8a8abe8ca725200cc173c21305b0b1aa73e8 +4.7.3 |checksum:c7a534a364d385838083d0478b7a90f1e9883fbac72d9d20cd770ad991b1ed1c +4.7.4 |checksum:0b75963a72a08a60a71f0fd06337e2eea1aaede37961b02305a3b23e1727c662 +5.0.0 |checksum:6bac663079b8a4cd17dc723d193d22e817f8652c1e41b59e99ad5d61a9458a62 +5.0.1 |checksum:3669da7269563f69ae880636f43095b39a7cfa589773d1fc3467f5eef7a1f58a +5.0.2 |checksum:6747df43cb8d1e8dc8d84f130840889a83daa35257c6ee841caf50468be2e70f +5.0.3 |checksum:1d170038c4efd1bb41699b32e62126a35e032edeca9c6dddb0f3ad23d11dfeef +5.0.4 |checksum:f634e8f5680b3b7e9faffe9742bbc634c5ce639f6e324631fa8f922ff5942603 +5.0.5 |checksum:f41afe27ef5362423a09a3df1bea37d7ebfa1bd9af44eaa04eeb526e7016f822 +4.7.5 |checksum:3e0ac720a6d0787b4c822514739319493e187400e993fba96397bd64d58ae60e +5.0.6 |checksum:fbcbad8af9fea0e642e40f21a99f61a0c69c561b7a909ac8adce79af3c615d16 +5.0.7 |checksum:4b386d9f4d437d19c7c6cf2071b5fe452f841d11b0d4a7cbf09c417819632d06 +5.0.8 |checksum:78933441f3f5a6b072e22eddf1ee19c7fbc47987e9bd5fa5444e905ad68b3bd8 +5.1.0 |checksum:95c90b17f5882e738489d082cf5f1032bf5a332a7ad25e427518e94ec1ffb787 +5.2.0 |checksum:96fefffee53b39fb2f72c6cc91faeae92d960285faf6486fcd5e1a8182065fdd +5.2.1 |checksum:15e96e0503a94bd7d7d56cfee5d9559a8d80805bcb20ece5faf9997f70d23cf6 +5.2.2 |checksum:b172e713ff888b1d5938787a4338bbb66870b003596595d46389dba9fec3165c +5.2.3 |checksum:b15c31bb2459c26b961f83a7db093d585211e75db24ff62f9770675c5106385e +5.3.0 |checksum:80683b64a86d06a4830fbfdb1591384327c2e53773a3162feee8eb26eb28bbab +5.3.1 |checksum:734b77d38207eff990f27c5c0180a55e7e1ee9ced03b115f20b2dfb3d9700eb9 +5.3.2 |checksum:b27941a8e09dc91f1d45eb85fe4bddc34a6ba037bdcb5345570f9650de1d325f +5.3.3 |checksum:b17c560235e6ab96ed243d7a821e4370af1316ad7a845188d22c56d7d71302d4 +5.3.4 |checksum:6fa3e70d90534e29b603f516a1fe1a0e99ab54aeb42ea45222955e3f1930ea33 +5.3.5 |checksum:b99fb077a6ace47d496f981041395ec565b9a1a59c45a73a2edd880bb27493a2 +5.4.0 |checksum:3493e7b5d3d47066f42e2cb5f70b2177ca82ab3198f097247b88f2f231755d00 +5.4.1 |checksum:99e83223c69ac3bb98cb2dc2bf857b6839719cb61cfe5b3ee1cf6eb48bf83812 +5.4.2 |checksum:6ce8b3bfc984ee927d8a2c45567ddcf1d28defe77adb5f21ab72ded9345305d0 +5.4.3 |checksum:a41b54b1c6e64b102fe78bf265045896845c38177a10bdb32d04caf4e06542f3 +5.5.0 |checksum:0277c07738303b7184410a561cafb0252c66cb28f3784ea17e5640876811f8cf +5.5.1 |checksum:d63b3136cc48295a1e80b6a3fb3638c3024e632ce53107ad3cc3f3fa32b012c1 +5.6.0 |checksum:3ba2cca0def7429e96e41088a30fe9c0cd47c0ebc1873cc1db615b2c436eff12 +5.6.1 |checksum:c293d497049aa663dc6332b940bdac9dd3052b62ccfe943c4fb5b130154f86b1 +5.7.0 |checksum:08ef10d1e6314fd0dc9a71ea697fd196d153d6bbffa8c6f7b8350973a772b867 +5.8.0 |checksum:875de2784b97b710da76c682e725095ca6c5142093a07474114e52cd6dea0953 +5.8.1 |checksum:c8d2763ef0f3c86464b83ed60876772a1e7ff669c562bb63064679cf51109103 +5.8.2 |checksum:2f72bd7eaa8990730aa190c8f49f28956165f4da400d6169cafb55ef77dc2db2 +5.8.3 |checksum:681b1dffa5af3167889fa23b2bf8860ff516b0fed560f8fb6af8b88c7eafcc4d +5.8.4 |checksum:2ad73ec73ef54719efba24961a36ad3a65c0bff9cb5d9fda4ddaba2a38b8d416 +5.9.0 |checksum:94660b4c3907ec4374a8c6980f63eb26644efe35c05b571567ce6d11c271dfbd +5.8.5 |checksum:7caeb638c82022ff230bea08701c8711a11958dfdc4fe5a3e9cee071c9e7ddd1 +5.9.1 |checksum:78b5e553dd15bb12b3bd0b59c8b4fa7152a6134c51a3099c4eedd2489cb2000c +5.10.0 |checksum:4c46ffababe56f6a89338a52d7816cb27a1d2bf83353374fdb9d8c9a79448689 +5.10.1 |checksum:4bf1fcf3306977f97348ff3c46520191a853c2637628aea20db55c7035aa62fa +5.10.2 |checksum:be02bab5ab57b63520829d42fbded3d00ac420096c583b7db377c3689d41be86 +5.10.3 |checksum:e2cf53a5b01932bfea16a5c76855836ddf2240ad53bcfdb09e99a6c0290ba214 +5.11.0b1 |checksum:2a4882a2f90fce7ce0ee1c0131da2c059d3f2233e680188a7c203a8846cef3d5,rubygems:> 1.3.1 +5.11.0 |checksum:01de5b1f8104b367829ee63c37c331301926e1384f8f068e26014a9f04719d6e +5.11.1 |checksum:e52030d2c215055b15b8374a5e88bd63713f0bd6dcdf31d18500f6bf14efb08a +5.11.2 |checksum:904b62df8e46158eb3192abb9d2dac3b8a3be848e723d3554d91f0a27102c4bf +5.11.3 |checksum:78e18aa2c49c58e9bc53c54a0b900e87ad0a96394e92fbbfa58d3ff860a68f45 +5.12.0 |checksum:6746471653812271dfe9127e0f9db2b6b6765709be698ba0447c10f31eaa45ce +5.12.1 |checksum:7dcf25e783421f1c437cfeaefda1e97739a5cfbdd2c6dc2cff26a39e92123851,ruby:~> 2.3 +5.12.2 |checksum:7c6e3c1a65d79fd3a5017e1d311d3f1ed8d39aa788b37a864d51901f1511557e,ruby:~> 2.2 +5.13.0 |checksum:b1666465cc443e41e03661e17e7e3ebfa076c9934845365a870352bdd9b92670,ruby:~> 2.2 +5.14.0 |checksum:dfe35170edd195c3f32b43c2326a776e687f9efb330f185e43f0ca0a8be9e33c,ruby:~> 2.2 +5.14.1 |checksum:afdc52567e32e275f8e8f825437883803efac2f9658dce0c70ea75fbb54d7f25,ruby:~> 2.2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-multi_json b/bundler/spec/fixtures/rubygems_responses/info-multi_json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-multi_json rename to bundler/spec/fixtures/rubygems_responses/info-multi_json diff --git a/bundler/spec/fixtures/rubygems_responses/info-multipart-post b/bundler/spec/fixtures/rubygems_responses/info-multipart-post new file mode 100644 index 00000000000..419a1a233fb --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-multipart-post @@ -0,0 +1,14 @@ +--- +0.1 hoe:>= 1.5.3|checksum:0108287fc58e79c98f2d5eb30ad7b8f8ef4bb5aca5b1b92a2f193edde55c0bd7 +1.0 |checksum:a2ce87a90cfbc968ad6ac1276d7dc071456f2522986fee14c14aec4ddc800c9b +1.0.1 |checksum:e57150bd2567bc8726f43cbefb49b9eedbc7e2f8df5d7f8c3e76e2632a2daed4 +1.1.0 |checksum:e1b30095f3d10d49ba4b3cc521410323b19b5a6136c61a0bbcfdd51a8c85c975 +1.1.1 |checksum:ab557b48dd700ed10b00908c0b32d9873ca17986f2b81cad235ae7956ced3120 +1.1.2 |checksum:61f9a5d24ba1a606e5d9ce3d152e1196a405ab5c67ae8d393550f3b2cc1440a2 +1.1.3 |checksum:2f4edc0d66c14a842caa5264dd4649d3b9dd6b4eebce90fcabe5eeee248dc928 +1.1.4 |checksum:ab9f0bcec29d8176e7a9f81feebe80c0415b8a2f4d6d217c9410bd6a1b1d4de7 +1.1.5 |checksum:cdb66ff777aa36b378225ae649930ab4c74174db0238cb750c8586c28b40bf64 +1.2.0 |checksum:ccf26a61706f128a2a3f3745aba0f79fde7b6fee068e03490eb189c2aaa5e78a +2.0.0 |checksum:3dc44e50d3df3d42da2b86272c568fd7b75c928d8af3cc5f9834e2e5d9586026 +2.1.0 |checksum:b501e1d42b9f5418dcdda07b0290cf71c3b59cf3fca5a89916c2a4091261424d +2.1.1 |checksum:d2dd7aa957650e0d99e0513cd388401b069f09528441b87d884609c8e94ffcfd diff --git a/bundler/spec/fixtures/rubygems_responses/info-needle b/bundler/spec/fixtures/rubygems_responses/info-needle new file mode 100644 index 00000000000..1c50d744c8b --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-needle @@ -0,0 +1,9 @@ +--- +0.5.0 |checksum:81ac3205c1b7082fd2560a412210fc2c26b51bbdf467028d962fd145c143eaee +0.6.0 |checksum:a157d3fd7718946f9d3476dcbf2696b559fce7b2f9349c074b8d3bac275da5b5 +0.9.0 |checksum:be35b7727f279a9b22558de3191f3313bbc338cfedd1cbbba657fb8394df6fb1 +1.0.0 |checksum:de88daec4c5442d9dd877cc32eb3748c0c950665e5c2389a5587485ade84d0c4 +1.1.0 |checksum:3b1dcd46110fb5c66743b0b735ea8fb598498851ec551be0dcf058dc4b6b676b +1.2.0 |checksum:0cac61610676be01eff82cd3614e3696403025699c3445de4c610e9ff0fb9563 +1.2.1 |checksum:58ecac5dbe8b95b1d460db06a48fae342d7c73812c08e5cc8e171e85ca0ad873 +1.3.0 |checksum:f8d2fc5891f6127021687abf0cdef7c062636604a5547dc5a85c2c62386b2e69 diff --git a/bundler/spec/fixtures/rubygems_responses/info-net-scp b/bundler/spec/fixtures/rubygems_responses/info-net-scp new file mode 100644 index 00000000000..f99cfbaf746 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-net-scp @@ -0,0 +1,16 @@ +--- +1.0.0 net-ssh:>= 1.99.1|checksum:1158bb780a7840707b61ba063fbb8ff66a8f240588fe68b47925549b5e844165 +1.0.1 net-ssh:>= 1.99.1|checksum:7354f2157b21d36fa594cfc24b6ad7a7a13ef282a47879da0315e3d9ead62802 +1.0.2 net-ssh:>= 1.99.1|checksum:63f734630318c90bb4721e1d59ed724674e1fd60ca2c98129bd497f608a36e7e,rubygems:>= 1.2 +1.0.3 net-ssh:>= 1.99.1|checksum:d6040061ce2f5e51cff46449104260a20f96bf0de4e81c574ceb12311ae5eae3,rubygems:>= 1.2 +1.0.4 net-ssh:>= 1.99.1|checksum:548494e245244d7bdc06015b60ca71e8c93574d511120e67eb26115482831f36,rubygems:>= 1.2 +1.1.0 net-ssh:>= 2.6.5|checksum:44f38a78401f60cfa094fff43c2301f48c15b6d6f08aa1adfcd76627c354ef0a +1.1.1 net-ssh:>= 2.6.5|checksum:bef4117672df3009b6bb4da302d2b49f5185fc4f31b78d3300055eeb271770ea +1.1.2 net-ssh:>= 2.6.5|checksum:f3d8848f63f9b7670e57af2e2c308e9bd6fddb7c5440a36e892478a1e62b5977 +1.2.0 net-ssh:>= 2.6.5|checksum:942d38c55686a0fb69ee80d7d006ffffcf22d684146f4f07616cb15dd326377a +1.2.1 net-ssh:>= 2.6.5|checksum:928ca046246bdbfe304313c903bab95e7b711938ceff4a2c896b91ab59c6122c +1.2.2.rc2 net-ssh:< 5.0.0&>= 2.6.5|checksum:b2ae35fdbbcc97e1bb3d12b1f5c5d4758daa860da9b624a0387bd5a0faa401ba +2.0.0.rc1 net-ssh:< 6.0.0&>= 2.6.5|checksum:1717bca2f10557e3be2b562d9cbcd92f51019c55ad15d9f59fc1ee0046e08723 +2.0.0 net-ssh:< 6.0.0&>= 2.6.5|checksum:2f6dc55eadfe410ad64e38f7e213cf960e4604fd8336c0f18fc01d547c1d6e5a +3.0.0.rc1 net-ssh:< 7.0.0&>= 2.6.5|checksum:291aa4a1be2c738fb26974708e4902de2952750a2b3eb9251909a6894b711e2f +3.0.0 net-ssh:< 7.0.0&>= 2.6.5|checksum:8fc6c80365b95230c6bfc529dbea3893d2d81724855bfb01cbf385866e1c902c diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-net-ssh b/bundler/spec/fixtures/rubygems_responses/info-net-ssh similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-net-ssh rename to bundler/spec/fixtures/rubygems_responses/info-net-ssh diff --git a/bundler/spec/fixtures/rubygems_responses/info-netrc b/bundler/spec/fixtures/rubygems_responses/info-netrc new file mode 100644 index 00000000000..8bb869fde52 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-netrc @@ -0,0 +1,24 @@ +--- +0.1 |checksum:f7f4ad6d764b590114645fbd6f6550ad58a5f1c247fa74d836930506fed681c8 +0.2 |checksum:1992628c3e82a198ad783fcc853b8b7b2b9299b17d22a547f8c0f427d9f26aed +0.3 |checksum:f177a8e45511029afea5a019caa9b149dbf2e9132809014e9d6add8120dd5b5d +0.4 |checksum:031deb9d6309be4746a965414600435daf54573370c04c0220901207f93adf25 +0.5 |checksum:1cd89019a9eff379f9403c397bc59f5794acd2a8b2e41be3777764339b32c24d +0.6 |checksum:c812ceff35d45a97b2f16af7707da0cb38ff5512982ee14aa342259194f153c5 +0.7 |checksum:7cb960c71dc4752374373c43e4b7090477ed96b2adab5aac08110a1656732173 +0.7.1 |checksum:4858df4b2502ec1cc15778e45ebf4fbaf836e3166af1d220033bfba4901f4c5a +0.7.2 |checksum:0b81c678beb784cb7afb387747020166c3fbf3ea838db64b0ae19c1cb70fbad1 +0.7.3 |checksum:ca8601a35a05c4aaf06d2d30df8f1811ec8a894a4a1367b0d4b91262b6ede056 +0.7.4 |checksum:d7d959563fa1e3ed34d7233ab4362b91b4563c228ea0db48607ceb58da22df5b +0.7.5 |checksum:9fd5e4e365ae232ef49f60daeb7f3d67d991e067570a8a9471baa08ba59d36be +0.7.6 |checksum:a04d69635d6dd6fb12fe3662adcd33de3f6c94f99b77323ff2142d2527eee2a1 +0.7.7 |checksum:2dabbbc95573f80ff610b136412ad5a1e13fe26cdf4fd7467fbc750d47dac4f8 +0.7.8 |checksum:30f66acb90b915f4ddf866683216278bc317d0156d1bb5a306ed91eaae1d622b +0.7.9 |checksum:e5720833f98f181163741966f2ecd75c2afd6a81c11b3e17a8e1bee01813c284 +0.8.0 |checksum:6bb6b2011b1f069600cc10f9a968f6dcb3cac9c23e741c3b1978a6d0765b92c8 +0.9.0 |checksum:9c8726e3c166cb2f99421639feac44525ce0646c4b01ffb4b41962a63763721c +0.10.0 |checksum:44a9d568b0b7cddc4146b758550b1da73f1693047292f7d273335015facd3494 +0.10.1 |checksum:cc451e9fc77a34a8381a90d428931718dfaeaf06cb04bd0194cdefa67e50ebb8 +0.10.2 |checksum:cd51a5780665bc3978fe2a33e1edd7e902218a7edefccc7a918e39f19cdec72d +0.10.3 |checksum:8fa24558ed46e2b2d9a58baa78fd7d11cb7efa3ec7e2ec89a057f76dc3abcce4 +0.11.0 |checksum:de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-nokogiri b/bundler/spec/fixtures/rubygems_responses/info-nokogiri similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-nokogiri rename to bundler/spec/fixtures/rubygems_responses/info-nokogiri diff --git a/bundler/spec/fixtures/rubygems_responses/info-pkg-config b/bundler/spec/fixtures/rubygems_responses/info-pkg-config new file mode 100644 index 00000000000..222681c7bf5 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-pkg-config @@ -0,0 +1,43 @@ +--- +1.0.0 |checksum:46b241964d293ce01473d67973c7a930df4ce3c63a2a88d8fd7f601aaaf27453 +1.0.1 |checksum:af1fe59529ca43739692a8680b2efd5ff7f8df113b7452e6f1fe768bbe775192 +1.0.2 |checksum:384c0dd1ff3099e267e6ec3a000dc5efd5129c7461e5df1cff18e0ca60177cdb +1.0.3 |checksum:b513f1b5b642b541ef97d781175fbe5d29e11915fcf3e66e495a28004f22db6f +1.0.4 |checksum:f3ada2b5ef73de38c9cac1c873ed9a676512f690cd341b37dc4f922d6066a7cf +1.0.5 |checksum:710e8d9e580d8d2b434038153dbe34171003a55d09efb062bb00f4ddd8e4e45a +1.0.6 |checksum:59b7ba1ac7c0cf148da459ce89388502c8cdf2220232e2c3ff7fdd06082acaea +1.0.7 |checksum:0b4c81d3fb66c0dc6f690f00e05277942eeefc24614d5d20ddda5c1f1bb30803 +1.0.8 |checksum:72777307a88712a5319bfd31d0422e13e670afb06381f9ffdc171bef426d5363 +1.0.9 |checksum:113084f8cc1de6c8552a1ac73cc74cdd1e8d2a63e77d8a6cd13d60706e19e1f8 +1.1.0 |checksum:2807fe2c6ae7bff3d8584403f91296cf080663734cd93cd7936aab1ac3413714 +1.1.1 |checksum:ea038e3948ee8dc176cd4244e7f5ebcea483fb343cfee63af7145d56b3d9aa63 +1.1.2 |checksum:fe47e3f619defe38e6f7edaff4bbf1a43bc2a402a065bb8d5cca0bf0cddcd8c4 +1.1.3 |checksum:4a71fb7e9750bca9e6c2690ce785427201c9b68c5d44fd2dfb2c814caca934ec +1.1.4 |checksum:c08fc6596eeef6f0fcfd4c8433010a143c22142f9cccbc2666f32c67c5af8b34 +1.1.5 |checksum:c821a08679b447e9665639d7c12b6a1d566530dcc9920c2d5dfd5e2e7cab06a7 +1.1.6 |checksum:f89c285286d9bb1607022225d042d8ff96d41d2755d4de80611d52f3ab0f7626 +1.1.7 |checksum:1f3cd171432f4634805ebf7cd187d1d728d732bfead3837c349f2c502d8e9252 +1.1.8 |checksum:e19da2a3e78f39e24db957b57da540924a9532dc0256903912e69d6bfa4171b9 +1.1.9 |checksum:7a0e8b9b99bb6bd1c816d19d3507bffe68116bc2ed387d4233f0b079c4d6e4c5 +1.2.0 |checksum:8fa0d9870bcefc13fe1526f80567b21eadd35989330e553b54a48c699b70743a +1.2.1 |checksum:c53a1ca751e0a2747116fb806dbd0e026afd1f31800f177af1d3f777db91ab7b +1.2.2 |checksum:7b76a116979fc5e721cc875c474480395acf07bc2abf4db16378f9a717e29ed2 +1.2.3 |checksum:bc193fda2ceb83cd0eeca87e1c9eba8e142dcd785699205246e28b1a7f14a84a +1.2.4 |checksum:cf3f95210991dd3e4c54b5e41ac7b7dfaeddb5a0564e437b63a7516c01e75802 +1.2.5 |checksum:59a13066e983a690be2256c00f69df44387370ec203a339eb65f7a021bfed514 +1.2.6 |checksum:f72f321a8bd32338d2e7e5aa5a6dffde4cc5739dd68ac9ba7782a6f2d6943040 +1.2.7 |checksum:fc8ab6f3200cddfeacb8a29168daa38d8f76c0e09af91a00a3d423bc472d70af +1.2.8 |checksum:9aff7ab9d6aea2218dba94791a1b3ba6f149fa57dc9c81634e54f0c59959d814 +1.2.9 |checksum:8880747a35362493a48dd331a40f9dab2e0469fe74a0899bd3559f810046b8d8 +1.3.0 |checksum:c06fb86e46cde092b3f29d6c7f9ea01d27a80e4c492fc6beb18d3f41139a1911 +1.3.1 |checksum:953afe038297f8f34b4a519a27cf7a3c71a03c541366695dd0da7f3be2e43d7b +1.3.2 |checksum:683bb303b84328b8da2d5ef63ff0347c7efd02df5960660b940b243670fa1f42 +1.3.3 |checksum:f2150e64cc594a197b1353e513d02bf40279b2aef53ef0dfe587a05a2e987a2c +1.3.4 |checksum:7042edd0a8cc5856732d014f569b86d6a959a8770bf4557ac318fae9b92dbda8 +1.3.5 |checksum:cbdd64e0f8ebdddbada7e0a0817ccbfadbd11cebba3e6f05c88a77c39e3edae7 +1.3.6 |checksum:fa78f18ee45320b2b6ce5d14825438e97e62159219b832845d883709fd128666 +1.3.7 |checksum:216fdf7ecd753dcc258cf516e1843f8e354c155b0aef2428f36e60c840f5a6e8 +1.3.8 |checksum:cdd626541f1d5ddb1ff5b6b8cb71d3aa5d612ffc24358da0237af88c340c7ad7 +1.3.9 |checksum:fed18718d618565505af031c0df4054c4edc713ec6f37717253b82c9c98472dc +1.4.0 |checksum:9d7501713d98d5213a35794bc4db0edf15d5822200d3ad0e2a2b7dca45beadb3 +1.4.1 |checksum:dca87a58534dfc3ff61c5de1289ed6622a5bd1f5b48fb2dc7a1cc5ef8f6b4ef2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-public_suffix b/bundler/spec/fixtures/rubygems_responses/info-public_suffix similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-public_suffix rename to bundler/spec/fixtures/rubygems_responses/info-public_suffix diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-racc b/bundler/spec/fixtures/rubygems_responses/info-racc similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-racc rename to bundler/spec/fixtures/rubygems_responses/info-racc diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rack b/bundler/spec/fixtures/rubygems_responses/info-rack similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rack rename to bundler/spec/fixtures/rubygems_responses/info-rack diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rails_multitenant b/bundler/spec/fixtures/rubygems_responses/info-rails_multitenant similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rails_multitenant rename to bundler/spec/fixtures/rubygems_responses/info-rails_multitenant diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rake b/bundler/spec/fixtures/rubygems_responses/info-rake similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rake rename to bundler/spec/fixtures/rubygems_responses/info-rake diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rake-compiler b/bundler/spec/fixtures/rubygems_responses/info-rake-compiler similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rake-compiler rename to bundler/spec/fixtures/rubygems_responses/info-rake-compiler diff --git a/bundler/spec/fixtures/rubygems_responses/info-rbnacl b/bundler/spec/fixtures/rubygems_responses/info-rbnacl new file mode 100644 index 00000000000..6988a134460 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-rbnacl @@ -0,0 +1,24 @@ +--- +1.0.0.pre ffi:>= 0|checksum:683b8c095dabe8706fa7bc4671704a00758381dfe3aef529314622f018cc75c3,rubygems:> 1.3.1 +1.0.0 ffi:>= 0|checksum:cc1e0487e2b9e0f23ae8105436915e9d6ac7dc3a6531a542216b60705e76f381 +1.1.0 ffi:>= 0|checksum:d1bbd3b30d90c9cf9b837f12999eb8d626e436143e4c96cf979f4351efef24a9 +2.0.0.pre ffi:>= 0|checksum:8125e0651b575a2f9a11a6b159d0c9a2fbd8437cb3838c051e2cb07af10a2e73,rubygems:> 1.3.1 +2.0.0 ffi:>= 0|checksum:4cb9ae4a1b4cb22e44cc303eb7cab680296dddddeecd9147c5028e142917f9dc +3.0.0 ffi:>= 0|checksum:5c335c0c687775a18a0bf08f5c68d16c5c3aa9a0498ced7404044fbbf648b286 +3.0.1 ffi:>= 0|checksum:b7f15ca9d326a9a5228200e2ab28d859f14a1e2ff45c65441efda4daa0c5715c +3.1.0 ffi:>= 0|checksum:a146b28c0653046010b71428d6592023bc519d7b3dfa107bc4a5545553cdc8e7 +3.1.1 ffi:>= 0|checksum:98d01b6edfab3b2009a3cbaaba26848bf8f911fee71494f0aa98135d49ed98ba +3.1.2 ffi:>= 0|checksum:8fad7e7ef9c855d70c5339a31dba52faaec4e4d674165d8f62c846bccabb62d0 +3.2.0 ffi:>= 0|checksum:1aa853b3d693283b4100395af08df32664fa317dcfc2e6633be99008d15e3a84 +3.3.0 ffi:>= 0|checksum:9609c52ab0f32161268451c9a667e62d40d75b2ee9593d7988c2ccf67da8c5f4 +3.4.0 ffi:>= 0|checksum:402439005321f39d4c7f37b9af2c8827510e14ab4bced7c3ad992ef9e024ab1b +4.0.0.pre ffi:>= 0|checksum:7f7f8c9e0c56644526f35f05aa72dda21f773f0d99cee8401e3eb8a5866db6b3,ruby:>= 2.2.6,rubygems:> 1.3.1 +4.0.0 ffi:>= 0|checksum:19cf3b939154788982973239c0470a60406edc857e66624644b1bc15a4b9113e,ruby:>= 2.2.6 +4.0.1 ffi:>= 0|checksum:8161c789cf6567084b648b480e4c6081546ecea265061376f715887977ba4072,ruby:>= 2.2.6 +4.0.2 ffi:>= 0|checksum:885c5f5dfa23007132df6d34992067f867968fcef8071e371ca5378ef88bb321,ruby:>= 2.2.6 +5.0.0 ffi:>= 0|checksum:3364b6bcd50d716c15d692bcd9e77d22e15927b9e442b496a5a7e1e4f3d2bb76,ruby:>= 2.2.6 +6.0.0 ffi:>= 0|checksum:2bd872d763ca0e5475c670af3554a2b7458fce40647eaa91815d9dce159e7778,ruby:>= 2.2.6 +6.0.1 ffi:>= 0|checksum:167e3ade11835ed952ee0809126891fb008e14ac7228aa1b4f804b2167f15d2a,ruby:>= 2.2.6 +7.0.0 ffi:>= 0|checksum:2c7baee304037c785eb9c73954ed50a76802f680a712b58b15a4550e7b4ba5e8,ruby:>= 2.3.0 +7.1.0 ffi:>= 0|checksum:47756d35710ef1fdfada2aaf079bcde57cc10dac9ddcf6cdb7900d2ae60e7f53,ruby:>= 2.3.0 +7.1.1 ffi:>= 0|checksum:f36f58b13307f7e8267532977bbaf1a07a0f28f21179bcb4e1894d6a55fc1e79,ruby:>= 2.3.0 diff --git a/bundler/spec/fixtures/rubygems_responses/info-rbnacl-libsodium b/bundler/spec/fixtures/rubygems_responses/info-rbnacl-libsodium new file mode 100644 index 00000000000..1916220f753 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-rbnacl-libsodium @@ -0,0 +1,25 @@ +--- +0.4.5a rbnacl:>= 3.0.1&~> 3.0|checksum:fe91d4e5144e81afa92b5cbad6c67a7d090199822c425303135fc9c472f72387,rubygems:> 1.3.1 +0.4.5 rbnacl:>= 3.0.1&~> 3.0|checksum:acef179193684cf59e176f93cded564f2108f3bdad81ebae8705d0da959f7880 +0.5.0 rbnacl:>= 3.0.1&~> 3.0|checksum:348b0c8ebe8e2dfebf272819279ad7e52ef0bd78b443a7cd03f002d91d4f04f9 +0.5.0.1.pre rbnacl:>= 3.0.1&~> 3.0|checksum:c23ef3558cb1620a10c8db59aab24094850278f2f95b3295474a61ea23a6f58f,rubygems:> 1.3.1 +0.5.0.1 rbnacl:>= 3.0.1&~> 3.0|checksum:1914fb7925e518a456d864592fc38cf79089b78404ecda1fb2237800e7745e18 +0.6.0 rbnacl:>= 3.0.1&~> 3.0|checksum:4f8bc528a040b3973f8322819af93aa73dc15e86a66dda7d059000846476edcc +0.6.1 rbnacl:>= 3.0.1&~> 3.0|checksum:cc74cd88ccb76dccb1d336db995507500e8c010bde083bfcc41d67ceae0cb5fa +0.7.0 rbnacl:>= 3.0.1&~> 3.0|checksum:f02663f21f882f860ba89df0bb1c9812c03bf247bf1b501675bf13e58f83017f +1.0.0 rbnacl:>= 3.0.1&~> 3.0|checksum:d865aa3c0f889ef88e44e18f446ad847b881494606c4769f90490afa6630ca82 +1.0.1 rbnacl:>= 3.0.1&~> 3.0|checksum:8dab05ec2406115fb721cf711231cee51d25eee6bb61cc07f8874cd518028855 +1.0.2 rbnacl:>= 3.0.1&~> 3.0|checksum:04f0f3fcb533d5e7c7d08602db5c9775bcab176f22631037e433b5d59a20a361 +1.0.3 rbnacl:>= 3.0.1&~> 3.0|checksum:9db24f1cb4fb029972d845f716ea384e91636e9c7c2a0b3ea9efb9a942065660 +1.0.4 rbnacl:>= 3.0.1&~> 3.0|checksum:27fc6aa9b6694aa11d42656f6e3732fa875173e0eeb1fa6b35b002cd99d4ddb3 +1.0.5 rbnacl:>= 3.0.1&~> 3.0|checksum:5dc36780af8ea957498d67ee4620db630a6417b46fe85128f8c50f8e26e86717 +1.0.6 rbnacl:>= 3.0.1&~> 3.0|checksum:9725444acf9a3925b3a9c081d7efba3c1eb64700a050f00d72cb4c2494a7beba +1.0.7 rbnacl:>= 3.0.1&~> 3.0|checksum:118d89e719c74a15d0651620328e84500a31153f450fe2ed0de3c990d5338e15 +1.0.8 rbnacl:>= 3.0.1&~> 3.0|checksum:478222552ca5b1de5245d453e51260c0512408254a5bf2868b8811f9b3bd2625 +1.0.9 rbnacl:>= 3.0.1&~> 3.0|checksum:edb7e181fab3cf2e03be9d691b1c6190e7c4e42376e55938de236f0d6581ed48 +1.0.10 rbnacl:>= 3.0.1|checksum:2f0589abc8e4e93a0e1b75b4dd9d2be634ee98def52c5e0d81707c60a75966e9 +1.0.11 rbnacl:>= 3.0.1|checksum:aa3d9c96bdad767ceeb12b8d6062d09e0fbdcef8497f0c2cfd219c085ea4b963 +1.0.13 rbnacl:>= 3.0.1|checksum:ed05931bc053007445c384a615a24ee05ba997dabdfc3e825301d4402275438c +1.0.15 rbnacl:>= 3.0.1|checksum:7d8fcc332ddf2db2920107b26568dab3926e82218d1ebbd5235f064790f0b0ab +1.0.15.1 rbnacl:>= 3.0.1|checksum:a809f37282c9aaf845556dacaf737e82a71056ea0e1873e50ce1a66bd14c7653 +1.0.16 rbnacl:>= 3.0.1|checksum:b0556a57a232debb103d9fb818d45246df2c3ceee12c3432de7ede8d75a39fba,ruby:>= 2.2.6 diff --git a/bundler/spec/fixtures/rubygems_responses/info-rdoc b/bundler/spec/fixtures/rubygems_responses/info-rdoc new file mode 100644 index 00000000000..68ee5570553 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-rdoc @@ -0,0 +1,87 @@ +--- +2.1.0 |checksum:ec98f5607bf5694544bc0085daee98a0d37cd3744e03c96fa16b49a42182a884 +2.2.0 |checksum:54f555117e17520f89c6d5ac3d0a999d180a8d6ebbf737308badb80586c16af6 +2.2.1 |checksum:38ee6882b2cdca1343b5ff60b1ed197c736d52194972fe308d86d7bfd2aaf278 +2.3.0 |checksum:9394d9a2711286a39d366b4f2e39e99f3d5becc2d66fe34ebbededf9d728c243,rubygems:>= 1.3 +2.4.0 |checksum:beb05edfa30ae25341993dfc82fa6b56f44ce5036c356fb09ae1b8129e8c14ec,rubygems:>= 1.3 +2.4.1 |checksum:315ce95edac08c05a69eefaae94a91d207208302474045658f7f5fbbb16551b9,rubygems:>= 1.3 +2.4.2 |checksum:cba009b5771cc9ef025ee6f867d8bbce77ac4fbc8c1f7ed9912915235eaab0b4,rubygems:>= 1.3 +2.4.3 |checksum:a3c60e87590144b9f9564447b812bb0b8e4f4e3176c9fd9682c40cbb0158436a,rubygems:>= 1.3 +2.0.0 hoe:>= 1.5.1|checksum:4a1801a890375c69e05cf077fee5bdfb0a791c300b97c423f911f7f596b08d16 +2.5 |checksum:00e86a489a318910c133d94bf280488c3fa1dfbc95dd0214a662e31a0a3880fb,rubygems:>= 1.3 +2.5.1 |checksum:5582ab05847b289579548ea6c681e35cac849a04d92f471fae1db72192257079,rubygems:>= 1.3 +2.5.2 |checksum:3133f79ec174623c8fff1b4260a9f6da8585a725482081b556d14569fc1200d1,rubygems:>= 1.3 +2.5.3 |checksum:a27de3a0cc084c3ccbbb688379f573596da0ee72907700b86a98094150ecc3fe,rubygems:>= 1.3 +2.5.4 |checksum:f7606ebb9f1ab6284ed79ba7b456832d34a6db2a86ebe752e2275f436df3055d,rubygems:>= 1.3 +2.5.5 |checksum:8ef522ec69cabfb757a8778692c2d206090e51d4e9f1d254654f6de5ffb0cd7b,rubygems:>= 1.3 +2.5.6 |checksum:a744a9013449fc52a95ba47fe23899ffc3890077101f44f4c6e75c8f6e3f8dd9,rubygems:>= 1.3 +2.5.7 |checksum:975f0affde92843170f58b489d656dbd0504091a5a9e03104b366eabeed3b219,rubygems:>= 1.3 +2.5.8 |checksum:0bc707198deb6b7e66b11c1462c0518aac49e6f03bc9f85a48ea4ddbe1a27016,rubygems:>= 1.3 +2.5.9 |checksum:b53961cab2547b4912a443876c78928f8baf31c5390f4ab91c5eefedd49b9162,rubygems:>= 1.3 +2.5.10 |checksum:ea0060912adfba39fb4f60f64ab9fcd3c719b3c433a69cacbbef70fa1e679a79,rubygems:>= 1.3 +2.5.11 |checksum:8f45be63d5cd73e97f34427f055cd5ad24ec7c193131c342c529babd98589421,rubygems:>= 1.3 +3.0 |checksum:c313deb6d3475de4be1ac599665945e12afb6fc906b9fca61feb58bac1e7dafd,rubygems:>= 1.3 +3.0.1 |checksum:626b4cce2c8d30fca411509bcbc04b7d66e2bfab4a1383da6c66151b6d3ddc13,rubygems:>= 1.3 +3.1 |checksum:c8dcf6120e975e8446ecbe41a45262ef22a45aa48ed06ba48d554ec712d7e869,rubygems:>= 1.3 +3.2 |checksum:a840b819c9d18ad40cbdecdbd558047c3168ace98765df9c2ae9089d965ea7a5,rubygems:>= 1.3 +3.3 |checksum:d74876e9515e6ecb2250755e8eebc7a43b117395cd290a863a1cf7b38dba1309,rubygems:>= 1.3 +3.4 |checksum:67281755b812b7218e19fb1c39dbf15fa0369f5f2818e22cb5ab07f5a993e237,rubygems:>= 1.3 +3.5 |checksum:663a281f2eca38b4c0ea2bea0aeb4f3e2f9ed9d5301830795b9de396fa6d736e,rubygems:>= 1.3 +3.5.1 |checksum:d7385cd97461114942403ff597641ea02095c7ecfbbed67a673f8188c88a9457,rubygems:>= 1.3 +3.5.2 |checksum:065e00b1e33f37a57557a1a1d6ae49527b91f853e56258a30f4e408e71b14cee,rubygems:>= 1.3 +3.5.3 |checksum:c1f3580cab4089d8327c2893d68abb76498ee10e2e8a20456a185f3c6a937140,rubygems:>= 1.3 +3.6 |checksum:900a50e9fadce88c8af441fb348baa3fb5e74bb7eb79c5acf0311e42b4da46dd,rubygems:>= 1.3 +3.6.1 |checksum:05dd4662a6ef0008de3b13368b6a705a418b53925142e0dcde0cadc168378f43,rubygems:>= 1.3 +3.7 |checksum:87ad861048810a9a606552eb9b7680cf88c1bb64c94a94e90b1eb7b35cef9d7a,rubygems:>= 1.3 +3.8 |checksum:bc38506a7eddd01b3979cf1596c2526ab57777d9063a2dc410d6c649fbaeb804,rubygems:>= 1.3 +3.9 |checksum:a56b0fcb2fcca1cb914b94ddc8a6074d6c864f9c005e4f2dce1d5ff24ef0be93,rubygems:>= 1.3 +3.9.1 |checksum:b0a0c92f8c2ad3ebd7faa5a7a0a9a7988f8f6ee03e7cc797748536b0dcae7483,rubygems:>= 1.3 +3.9.2 |checksum:16257cfdfa57b81262b2c1f458263c2019d08c12956ad8a0be35f09836b0c22b,rubygems:>= 1.3 +3.9.3 |checksum:11d67b615531496712158304f553e75f1e49b9759b4ffd7b4c6a091815f80404,rubygems:>= 1.3 +3.9.4 |checksum:c55589d297a884b4fccfd2f487441ead6cb677030b158dc6ac7750ac752fd77e,rubygems:>= 1.3 +3.10.pre.1 json:~> 1.4|checksum:2a29f852e2d037cceffa753b3e43524f4b19504523b3a85a418b45841ed2d071,rubygems:>= 1.3 +3.10.pre.2 json:~> 1.4|checksum:e25dcfcc615d4d6079e36111814070da1886c436e95704cdb2c7ed49c6b46eec,rubygems:>= 1.3 +3.10.pre.3 json:~> 1.4|checksum:c007c25178eba25c790ed8d9c7a32278fedcf78d9eb796b6eafeeaa631f06890,rubygems:>= 1.3 +3.10 json:~> 1.4|checksum:33d8eb14960b02cf48ed1e34666ab5fc5893db21a9fd8ba89731e9c44f199d99,rubygems:>= 1.3 +3.11 json:~> 1.4|checksum:353b31c71315bb9ceb69185bc9a2d5aa83a5195dd717fbb865fd06b18b280873,rubygems:>= 1.3 +3.12 json:~> 1.4|checksum:77b6deba13ca090fb4608c218ec5d5c05d78e841cb0b53cb31f91fb56686a431,rubygems:>= 1.3 +4.0.0.preview2 json:~> 1.4|checksum:41b4df8523919ddd706a4186369504d671c60a2932e26cab599b503f738b9746,rubygems:>= 1.3 +4.0.0.preview2.1 json:~> 1.4|checksum:d4d2aeeda46f7465e3c78defda50636fd9d9f8a44a0e450304f8834ee13b2fdb,rubygems:>= 1.3 +3.9.5 |checksum:1eb0e14d423a9c5ba4e505671ac9437c4e0ca49c9bbb570aaee324825a8c0a7c,rubygems:>= 1.3 +3.12.1 json:~> 1.4|checksum:8ffc43aa68671ff20615b77eb3e0339204b6a297e148de261add53b0057fd4c1,rubygems:>= 1.3 +4.0.0.rc.2 json:~> 1.4|checksum:aff2b991b171b450ea2e24e87322b464ad53caf85dfb0540f74c1d9c5b3a1916,rubygems:>= 1.3 +4.0.0.rc.2.1 json:~> 1.4|checksum:ac55d7097f5309e9f5b32004bb66fd90b7f9c55e9e92efb976855c25c72d43b3,rubygems:>= 1.3 +4.0.0 json:~> 1.4|checksum:ea9b6f501b973bf3d05f1d906f3967d5b4b98b2a2e20cca5ac9590430f39c4cc,rubygems:>= 1.3 +3.12.2 json:~> 1.4|checksum:a8e2b78f7e5ec4cc4716cd863975645f2f2377dc6db267a15e427e5fae2633ed,rubygems:>= 1.3 +4.0.1 json:~> 1.4|checksum:b712d56c266a8568362bbebcdc385b102b1494ceea099161c71e02f420d716ba,rubygems:>= 1.3 +4.1.0.preview.3 json:~> 1.4|checksum:fa3e80d2e60033135b71d472ce23283ad345c7376527a2b294e5765258bd95bf,rubygems:>= 1.3 +4.1.0 json:~> 1.4|checksum:b06b4391705304a6cc121f81e51e77c7d19008adb0d6040ac6e58d79b9225321,rubygems:>= 1.3 +4.1.1 json:~> 1.4|checksum:fc41a834055ed4de6a2adabb78953f7783cd4d67c2239229a71e09dd308a8725,rubygems:>= 1.3 +4.1.2 json:~> 1.4|checksum:8623c640083f0e06085636a6a719cac993dcccceba5f3f7344ed14c35b941033,ruby:>= 1.8.7,rubygems:>= 1.3 +4.2.0 json:~> 1.4|checksum:391bfe3484a69db2cfa0fa32eed9010a7878b33ae645d67558d1806c847290cc,ruby:>= 1.8.7,rubygems:>= 1.3 +4.2.1 json:~> 1.4|checksum:81207a9d3ef9e60fc42bf3c6569373cb32397a16af370ca6be6dc71b358df839,ruby:>= 1.8.7,rubygems:>= 1.3 +4.2.2 json:~> 1.4|checksum:f3341c252b1547be6ba042f5ca1ce1fc5c52e3c27d8e0d485d0486173edfed08,ruby:>= 1.8.7,rubygems:>= 1.3 +5.0.0.beta1 |checksum:521f09c7a75ebd18e32679e616aa62a18ff0243594bca12b6c68620748096dad,ruby:>= 1.9.3,rubygems:>= 1.3 +5.0.0.beta2 |checksum:9e2076fad1cbd88cde508707c881c8d180b3b0d38612440160f0246b1220937a,ruby:>= 1.9.3,rubygems:>= 1.3 +4.3.0 |checksum:8cd820f70ec4b315ffff8e0653c8ce46cc9e444f3f8e7ed21c57338c61156a8d,ruby:>= 1.9.3,rubygems:>= 1.3 +5.0.0 |checksum:86fae3ac44b858e7abdb8809620232296f9a8cc6815c98b4cc1ed21ca9ffb0d1,ruby:>= 1.9.3,rubygems:>= 2.2 +5.1.0 |checksum:195090065b9afc6d64600e3686b8ab39be7d2eeaa9d98bad5160ce66276e94dc,ruby:>= 1.9.3,rubygems:>= 2.2 +6.0.0.beta1 |checksum:13dc15c9ddc903c25de7fe4bcdf7231f9d2cad3e42e50b916753b295b0969d8b,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.0.beta2 |checksum:75c1b93dd743c8a51c685fb532f64421f27552298f67cab0b6a9a2fcdcf29645,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.0.beta3 |checksum:44b2f54dcfee5e099cd9bd74381d560e18fb17d02452413b59f83d49e5dbd685,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.0.beta4 |checksum:fbd8070901fe6ab5c4174e560e13a73c134a7418074c091f090b74a7ebdb25be,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.0 |checksum:a0655f1dc72c3afc6132575dc88093543570011d8877948397b03ba220f5c706,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.1 |checksum:d2bb4ddd97dc3bbf667cdb9ca75326e349d8f53f0436544457d19c4b09d8f0ef,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.2 |checksum:2782a49fac65d3195cd4e7e620dcf09dd6df03830ff69e79edc98a6b7c69b52f,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.3 |checksum:0af90ff46a89fffaf9ac504a96bd8f055bc0c979cc7a3264127572eb087e4645,ruby:>= 2.2.2,rubygems:>= 2.2 +6.0.4 |checksum:27b33aab87e61bf6fffe7ef82c188865ab578fdab91a342c798635869920db2a,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.0.beta1 |checksum:6e4ae4d7eec1ec08d61c41701f515279bd7fc3b9547c1f56ab2103f143e1573a,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.0.beta2 |checksum:da99d7c6d90312fe9e1285f0e393b26bdee241e6e9e88b0961dee4104ebbf6de,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.0.beta3 |checksum:79e45baf5c9acfbfb492c9bb68bf2cda28878f79f719f9745290170d25461327,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.0 |checksum:ace0c97e0805bfdc3583cc774c38bc0d138c93d22f3e3f3c742e0d1dc9d08697,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.1 |checksum:774ea15fbf4f8284a9bea4530810ed973773e3eb506316d5d45e686a0553671d,ruby:>= 2.2.2,rubygems:>= 2.2 +5.0.1 |checksum:fd33dd346feb97c56db6869a2b568aa9420d70aad25b05f965824e68826d1b22,ruby:>= 1.9.3,rubygems:>= 2.2 +6.0.1.1 |checksum:e510ecb2f8cffe96c44096215f6b50663884d7b18063ba0e7c2f7f79fadd035e,ruby:>= 2.2.2,rubygems:>= 2.2 +6.1.2 |checksum:eb137e70b3dc012cb5550c4dd9d0b8083502cacc4b07b514891052ac6f4b037e,ruby:>= 2.2.2,rubygems:>= 2.2 +6.2.0 |checksum:292ec1e7cc1ac2dc7828bbd66180c53d64800a660105907ea22f93d607d307be,ruby:>= 2.2.2,rubygems:>= 2.2 +6.2.1 |checksum:0c3a458ce536b907839125263129bd9d488ec5be44552ec643b29c1272150621,ruby:>= 2.4.0,rubygems:>= 2.2 diff --git a/bundler/spec/fixtures/rubygems_responses/info-ref b/bundler/spec/fixtures/rubygems_responses/info-ref new file mode 100644 index 00000000000..16c0dc44625 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ref @@ -0,0 +1,7 @@ +--- +1.0.0 |checksum:b424494359a040dfa6865de30d7e5140bc487d9243d69549386039e5d4180030 +1.0.2 |checksum:231d5e7a4bff43dc9674aa9f0a9bc4653a5b8114d933bb1e5a9a4d4b13b82d0b +1.0.3 |checksum:005ab696db41f5cbfe90aef1bbebf2e5f3e338cebfc4eeb8c275daa356d35b9f +1.0.4 |checksum:dd5dfcef66e6c897a05da131eadf8dac3f28c4ad3d84446213f517ab381ab034 +1.0.5 |checksum:8a8ec8f40f1e622c4324055d85300e03d9a78a9faf476ea0d382f1af9dbe0fa7 +2.0.0 |checksum:31cafc3ba73128e3c32791c9c8ddc2ee54d1cb3eac8161f73d9ecea809bee412,ruby:>= 1.9.3 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-representable b/bundler/spec/fixtures/rubygems_responses/info-representable similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-representable rename to bundler/spec/fixtures/rubygems_responses/info-representable diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rest-client b/bundler/spec/fixtures/rubygems_responses/info-rest-client similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rest-client rename to bundler/spec/fixtures/rubygems_responses/info-rest-client diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rexical b/bundler/spec/fixtures/rubygems_responses/info-rexical similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rexical rename to bundler/spec/fixtures/rubygems_responses/info-rexical diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-roar b/bundler/spec/fixtures/rubygems_responses/info-roar similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-roar rename to bundler/spec/fixtures/rubygems_responses/info-roar diff --git a/bundler/spec/fixtures/rubygems_responses/info-rspec-core b/bundler/spec/fixtures/rubygems_responses/info-rspec-core new file mode 100644 index 00000000000..4570bda3604 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-rspec-core @@ -0,0 +1,136 @@ +--- +2.0.0.a1 |checksum:0c21acb331c0b6755ea60f6f0be1eb8b6681f591247c19e76a5f3abd54db9cb5 +2.0.0.a2 |checksum:1814afe7b2cdb07bfd12eb6bf8fa3f0e5b56330e156ed5427fbc30c63a0e3d15,rubygems:> 1.3.1 +2.0.0.a3 |checksum:f794b53c009ee3ba7a6c3fb83aa1239bb15f148a30950fe742b858d6270be591,rubygems:> 1.3.1 +2.0.0.a4 |checksum:ca9e37c21bbe46b0d9c3fd6a1a01562a7d4af1951a969a06feb4ea9715551035,rubygems:> 1.3.1 +2.0.0.a5 |checksum:37e8832075c5a7e95cb9b4892c12c91a21dab1958cf4c1f520a56b181d9fd92f,rubygems:> 1.3.1 +2.0.0.a6 |checksum:6970545850f0206eafde2f9fb447f9d057950ac5247b44d8c3d75131055b7280,rubygems:> 1.3.1 +2.0.0.a7 |checksum:36fa3e230e00b99a2a9b2c0e52b622903e408e4358c0ecb7695ae4e5bfefb2e3,rubygems:> 1.3.1 +2.0.0.a8 |checksum:a3af456d657ad96539d1ad8d158cde02a8cdb00f6241b9952fe880db869818f5,rubygems:> 1.3.1 +2.0.0.a9 |checksum:582263d1844565f940119c6023e9bbda18cd4bb5948528f9f75873d9710aad99,rubygems:> 1.3.1 +2.0.0.a10 |checksum:0785ef94935b32e7a387ec1b9538b3294ffc34206f2fc3b6ad3c76afdf64b4c7,rubygems:> 1.3.1 +2.0.0.beta.1 |checksum:24609a34a2e14283ea4936a3044a0fc7e05a24d0910c99805baeaa3e3105580b,rubygems:> 1.3.1 +2.0.0.beta.2 |checksum:a4830e76deb472f9ec6dfbbe988c0dc5d7506d61e5b36f4cd3ba7961ee2fd2a8,rubygems:> 1.3.1 +2.0.0.beta.3 |checksum:1c3ccfee70afa2fab214c2b2dad79524e205b36a6d8b2ecd4cb4162b8189e248,rubygems:> 1.3.1 +2.0.0.beta.4 |checksum:bf94679f56f20620bee4804273a94a9ae24a1ca29991bf213b4f2d551f9f6b48,rubygems:> 1.3.1 +2.0.0.beta.5 |checksum:0084f07ebffbacf339d6b2b8ca54c00b6b6b5d4b2f8adf5a1b8b7b11940bf170,rubygems:> 1.3.1 +2.0.0.beta.6 |checksum:b6a07e4367f261ffd7293284fd7d4752404a051e663968b41f2f4b45e66b4017,rubygems:> 1.3.1 +2.0.0.beta.7 |checksum:533d4b3107b015e75df40ad7c75dcb662d4b79022b3310857ef2cda7c6d5b194,rubygems:> 1.3.1 +2.0.0.beta.8 |checksum:2f7063ce504cd2239921677e8748822f458b920a2eb204ecb08a64bd212ebe84,rubygems:> 1.3.1 +2.0.0.beta.9 |checksum:95df1d85a53dff9970f204e8b01335fb72ce97c19ec46afc6d0f58336be8df11,rubygems:> 1.3.1 +2.0.0.beta.10 |checksum:fb6f9d2e3ec81b3f214932efd1dd00d8f6c778295755a0b9841137c722efb531,rubygems:> 1.3.1 +2.0.0.beta.11 |checksum:2cac2c3e7314c0ef3697c2a1167b4bbd1c5b60f56e81fa87243f7467cf653905,rubygems:> 1.3.1 +2.0.0.beta.12 |checksum:7c080964524e62c999616784242c63e324c25329bb435332a9a6c4eeb8e47cdf,rubygems:> 1.3.1 +2.0.0.beta.13 |checksum:75980a125234969eccef3fe46cb95ae54d01d98f88242760d1a3523645e28e5b,rubygems:> 1.3.1 +2.0.0.beta.14 |checksum:256e77735865542c00ea10e9db974ae2b647df3cddfcb10652fe56625e14e264,rubygems:> 1.3.1 +2.0.0.beta.15 |checksum:4dbda5ba8d78a291c6b58cbc5ed7ec28ac090b6f9af3d0ec3655461aa9e8f2c0,rubygems:> 1.3.1 +2.0.0.beta.16 |checksum:18a622ceed14e92338a080672e65be4a033265328a13fe3d728a1f172bfb11d7,rubygems:> 1.3.1 +2.0.0.beta.17 |checksum:e011d674c8b4ae91f89090eb19a3d5477b02673dd0440a66f7487417b52b8f36,rubygems:> 1.3.1 +2.0.0.beta.18 |checksum:b6d8935f0593f7f1ad262af2c84e897dc196579384984aa1ae82b35242c68c90,rubygems:> 1.3.1 +2.0.0.beta.19 |checksum:4fed7dc6e5749aa97dc1d5cfec02d472d0028515cee30d4fb435f09fad4bb23c,rubygems:> 1.3.1 +2.0.0.beta.20 |checksum:68507740b50e6a11894cf617399a378e3ec22599b8601585156fd198c710f532,rubygems:> 1.3.1 +2.0.0.beta.22 |checksum:d6b801a553dac38924036b1e566f142aa22348ae5e42cef10c1651dbab072f1e,rubygems:> 1.3.1 +2.0.0.rc |checksum:5e4d940d0ed8ee0572dabc622e76e2bc6f6f89368e16cdeb6406d17040183331,rubygems:> 1.3.1 +2.0.0 |checksum:f857c3a4ceaad4c597ed6e4bf7213abe5410807d58e2c23fcba41656071ed3dc +2.0.1 |checksum:e180c97ef2bfc6cb1e2d40ce715a951d042d3a920ad6c8fae1475089dadac093 +2.1.0 |checksum:b0fe547be943d22c0654d5d3a3b6cc21cb06dc8750f6cf1149fb3ca71a6249bb +2.2.0 |checksum:a43e841df1dddc69eadb1a503c2f72e3486181fb3e854c08fba87c7efd38972b +2.2.1 |checksum:e36b2c8f9aef12191ca5e6f7374a1e4e5b7f9916a912078f886bee673e1befc6 +2.3.0 |checksum:d904c47034f6d2bbd0b310e28355f6a16bfdae8f0a837dd89960e592359ad18b +2.3.1 |checksum:aaf3353a96cd4f7980c2912c6bf670dcbbca5e9625d3ee3a3eacc62b6ee461ae +2.4.0 |checksum:1646db69ec12656027ea1fefe637b9dfe85f108750b3db57fffdefdd3c4693fa +2.5.0 |checksum:3c435115263e593d888d226414e17c6603ff3dfb4219c111c8cbf2eaced1c0b1 +2.5.1 |checksum:84ff9cd12fc4c70ba659b4a23b6a4ff5ab16228fead55030e17bbbf0834492ca +2.6.0.rc2 |checksum:6a43383a33997e3f10246fa0cc12965e0e014b84259fb07faaebbaf9ddf45301,rubygems:> 1.3.1 +2.6.0.rc4 |checksum:f63614aacb5f1b03aeb7318dd0f835df13ef3be403e7d69b5db1c26e13442219,rubygems:> 1.3.1 +2.5.2 |checksum:90053c216e9742116f57333f11f8dd29ad305ca3fed698f834430eb0b1b29e60 +2.6.0.rc6 |checksum:f963e01bd69feca067f5db1c2945e06dc815acc0a61509e476dc57eabc57c424,rubygems:> 1.3.1 +2.6.0 |checksum:41336c746f5a0584c70bf3313107c27da853a2828ae206f794004d257e61b452 +2.6.2.rc |checksum:e3f79bd3877b3b30d53842bc9589fd0e9a61c06454b50923b9d445a36f5736f5,rubygems:> 1.3.1 +2.6.3.beta1 |checksum:e18ff0df99abce938aba787aa7e38bb9666568818a7985b1d07e2cc06a95c1bd,rubygems:> 1.3.1 +2.6.3 |checksum:01d9fa7d7d36e2fbc825cacbf7d2e5f46cdba6a16d949c4af6472d431a5aeef0 +2.6.4 |checksum:9d41146ee85fc8177d54331d72dfcd9ea71df41ed5d62bdbc1a027be496d903c +2.7.0.rc1 |checksum:c06733a7337332cde1c9f69ebcdd66d299926c1c168738908744eb2f1ab9a078,rubygems:> 1.3.1 +2.7.0 |checksum:e425c01691954354b8d84df5d103eb23b41410272c78701585cbbe66f428500f +2.7.1 |checksum:e663a6869621ab5973e185a4d597bf9197807fb684b1f8e82250537a8ef9d90b +2.8.0.rc1 |checksum:7d31c096e87225a665e8dd3f89ab86b2c979531c8ad8b13deb1754bd0502ee09,rubygems:> 1.3.1 +2.8.0.rc2 |checksum:70e12ad79f742ee3a02a0ffb0130b7bce0743634725486bbe69e1725a84fc622,rubygems:> 1.3.1 +2.8.0 |checksum:92639238e84f25851d4b3e3858e7411681075d2a8e1fd77de89483bea77c90b4 +2.9.0.rc2 |checksum:6930b56024e0641e10b4c7d4b299462f3781badc8e4f756f1e7449c34c08afef,rubygems:> 1.3.1 +2.9.0 |checksum:cd4e0fb5196e2aec9d2174fbabc38bcded3012278efb377afe1f509e713d8c9f +2.10.0 |checksum:25b0ecf7fc3599b79ac3da12d1bd3fe0702a9dfd78c35cbfb4eb4ee47574cb74 +2.10.1 |checksum:086ad30a6f26b25ce6fb815134e96f88449e32c0a312523b5a10c89855676d0f +2.11.0 |checksum:7f4d9d38b73d4db9ed99f8611f13b84c9262d4bac4a9a78708a705301a5411b0 +2.11.1 |checksum:245a0928c087be31f4595f59c8bcc8e97209e3ac636f867c01dee71b4c89b30c +2.12.0 |checksum:81112e14044b051477a9b9bb46bfed118dd8c50d9afcf5098a74e6bcdc039498 +2.12.1 |checksum:970aad032b5bc54d43639592a9bb5172c0007e645e02b128dabf5d82e04f7cb1 +2.12.2 |checksum:8edcf37a861d813b7b3a06f984b55d28f07a0ac9b18da2ed020235f9f0273f1c +2.13.0 |checksum:d65564efbfeffe39ed7b3437afbf03473ee42229f76b5068e5ffc3cd959d9939 +2.13.1 |checksum:c724f6987d5f8ab9a6e683a503598b80ac2e848b579773d6e16a48d11448b2bf +2.14.0.rc1 |checksum:bc1eaeb2394fbbd5175271edff83b5dc9e6d8533a27f5aa9f8eb0fdec5b160d9,rubygems:> 1.3.1 +2.14.0 |checksum:e8499fb0f8e2d682caa0f1b5017a688be9bc3d462133e086068b66f62dc3d934 +2.14.1 |checksum:79bfbe328fab222f364386678c51e51ab92801baf05b52e69e3c372d6b5f7486 +2.14.2 |checksum:4b533740e2745c354bddd74cbb9b51602a3a9c6b176c47de47155a3cb8dcbf75 +2.14.3 |checksum:ce0b28358476714a45eb795da448488e1e850dcda53b60e2e2e46276885b88d6 +2.14.4 |checksum:247ab59ae964f4917071a9507e934b6c5da82ad61044a45da2c38178bfe51bde +2.14.5 |checksum:99d51ee6038e43ff500574119119ad0b485f31a332406882be44fea78a17f3a3 +2.14.6 |checksum:a2cd23a2478866dd0840bed70a5dfc6a2cf31239c61428ae63ae5e2dfe12f666 +2.14.7 |checksum:e714621feb592e515c3ca19a685505af1c2bbb2d713b85c0610ab80985624348 +2.99.0.beta1 |checksum:18f13f2aea2615830a83dfeab26715e06ed4d01ad52f31e527c28a00dbb01c0f,rubygems:> 1.3.1 +3.0.0.beta1 rspec-support:= 3.0.0.beta1|checksum:e71cbb28bcddad0da72b776e80cae5fd59cb51b598f700e33a673be331d77a1d,ruby:>= 1.8.7,rubygems:> 1.3.1 +2.99.0.beta2 |checksum:d832787c80ba4d4d2a50c1821a1762ed2ca9574e0857e47a3e7352e8399f540e,rubygems:> 1.3.1 +3.0.0.beta2 rspec-support:= 3.0.0.beta2|checksum:39ee3872448f29748c740489dccf6aa86f44bf1e63078af07237b7413200db4f,ruby:>= 1.8.7,rubygems:> 1.3.1 +2.14.8 |checksum:8c43f4dbc105ca622e72693c8aed533386580c0fa082bcd280777cda66f1525f +2.99.0.rc1 |checksum:dfc81e83dbcbe9c992ab0cb88b9d70811546290808814b63d73a116acb4367f6,rubygems:> 1.3.1 +3.0.0.rc1 rspec-support:= 3.0.0.rc1|checksum:86495681f495c40cbd5ef83d5f17f5f709b570258559a93d622ce6b21439f159,ruby:>= 1.8.7,rubygems:> 1.3.1 +2.99.0 |checksum:32572adb76ece1c57dd77016e25c6d036ad9915b02f22e169a8f54a1d0f29e71 +3.0.0 rspec-support:~> 3.0.0|checksum:2a070dffea392f76ca69dc7b81d45d8ec851fdf8f21b672e45039e39e6ffb85c,ruby:>= 1.8.7 +3.0.1 rspec-support:~> 3.0.0|checksum:51eaccb8e30ec3cb578ae750764ce16ca84475ccf644f051d4d3607aa3b511db,ruby:>= 1.8.7 +2.99.1 |checksum:cedc8f225e9115e96953a69b535ad26a4202a4d0614eb115e9dccdee5b97df70 +3.0.2 rspec-support:~> 3.0.0|checksum:14aa6a5cef00bf635c82e5bd50fce2b71d6d102e05ba102d06f6a0101c91c0e4,ruby:>= 1.8.7 +3.0.3 rspec-support:~> 3.0.0|checksum:f5246fcdfd1c979229eca051ffef8c0fa450f74fa4f43a2a3f08aeeb72a9250d,ruby:>= 1.8.7 +3.0.4 rspec-support:~> 3.0.0|checksum:1f91e70e8d666ceeee8d3483e264337b6ae5bd387a795bf841581f5426c27ebf,ruby:>= 1.8.7 +2.99.2 |checksum:110d5e0f59baa2fbb5d79d1fc7d410fb1c13ecc1fb8acba4689c8acf68109ff3 +3.1.0 rspec-support:~> 3.1.0|checksum:30f540632dd20656ec7597e277bd558e6e2d5798c1b3511433399d5d66fd0114,ruby:>= 1.8.7 +3.1.1 rspec-support:~> 3.1.0|checksum:367eb6183d6c0692a26af7fede2030580f27f571a3fc9225d60a47795b646984,ruby:>= 1.8.7 +3.1.2 rspec-support:~> 3.1.0|checksum:2c6964c828ff04f76a2a9862ad9e766d08b0691facf5433e640ea791f0b8cdfe,ruby:>= 1.8.7 +3.1.3 rspec-support:~> 3.1.0|checksum:6198c0818fad27c63601a99b87b93dba5bc8634ed8f0e61fe1eacc349f0d2043,ruby:>= 1.8.7 +3.1.4 rspec-support:~> 3.1.0|checksum:4e153fc36ba63ef564d076d10aa3c68987dae8152b1e908e07c2158802886866,ruby:>= 1.8.7 +3.1.5 rspec-support:~> 3.1.0|checksum:12ef46438e276128545db7e7b3971f3bf60d60fbcd805274154ae457294e8d3b,ruby:>= 1.8.7 +3.1.6 rspec-support:~> 3.1.0|checksum:a3bb06989213d28674dd307ad9ab0ccc5ec1ee846e667c29bfd612a4e128e21d,ruby:>= 1.8.7 +3.1.7 rspec-support:~> 3.1.0|checksum:89e1aed9b8b1c22d4bc0cbed25e163c10075731df87e2ea9736f1863e9e66a05,ruby:>= 1.8.7 +3.2.0 rspec-support:~> 3.2.0|checksum:e060ec276665518885e445b51b8a3dcdcf6e874abd7a6d7c280edbd45eb142b8,ruby:>= 1.8.7 +3.2.1 rspec-support:~> 3.2.0|checksum:1a5d8ce664cbbaf4325ae681fa83e488df6e8273986c6af9d4daf87f03ae4b25,ruby:>= 1.8.7 +3.2.2 rspec-support:~> 3.2.0|checksum:682891300c0880f341d9a0cdb24a06524b56fa4b7cb1b189dae5ec9de2d2adee,ruby:>= 1.8.7 +3.2.3 rspec-support:~> 3.2.0|checksum:7bdfcaaa75b00151e19850018afad6f51a637aaeaa1db33713ec81c16338444c,ruby:>= 1.8.7 +3.3.0 rspec-support:~> 3.3.0|checksum:a1eba8e9392fc4fb96d338a2a555d827ef6ca2e492c7ab73ae0bbcef27e6a526,ruby:>= 1.8.7 +3.3.1 rspec-support:~> 3.3.0|checksum:a49e26b3c280a175db0abc448ffafc4d00a26eb380855f9feedf4a18b266d5cf,ruby:>= 1.8.7 +3.3.2 rspec-support:~> 3.3.0|checksum:c1c3d34841f906d3b6ff4b9cc6823906103780e755c41e5dfad6483352c48577,ruby:>= 1.8.7 +3.4.0 rspec-support:~> 3.4.0|checksum:b0c12ce992122bffed8da2fde13fee995be8bb130f1e82acc536f64b1636265e,ruby:>= 1.8.7 +3.4.1 rspec-support:~> 3.4.0|checksum:f6d90fe65f1cbff6c269bbb6d8fe96a26a023008694337ec12ef11faf372847e,ruby:>= 1.8.7 +3.4.2 rspec-support:~> 3.4.0|checksum:b332e7bb5a9e8b9375d62a988673e10544c67054832b8ed53a7a336e1519e968,ruby:>= 1.8.7 +3.5.0.beta1 rspec-support:= 3.5.0.beta1|checksum:3c6e3fc14eb9476001271280b0ad566bb918c9054a9914faad4f0c5b8a161218,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.4.3 rspec-support:~> 3.4.0|checksum:fb015a4eeab0f8b6ff022474993e9ea1187a596bd4dc945d64c19f5996d7d72a,ruby:>= 1.8.7 +3.4.4 rspec-support:~> 3.4.0|checksum:d7258c6bc285052e816d86f5b86cce58ec6fbdddb8aae981d80060d587af5ffc,ruby:>= 1.8.7 +3.5.0.beta2 rspec-support:= 3.5.0.beta2|checksum:41059485e75428de0c1ae44f39285ce82d7d567ca4feee5ccc9feb022440ef78,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.5.0.beta3 rspec-support:= 3.5.0.beta3|checksum:6db11ac8215a91774fc8b4d3389b5f2cef6d30c5061d146dc541c98d03fb8a98,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.5.0.beta4 rspec-support:= 3.5.0.beta4|checksum:4fe689b74bf996a734ff232f8768237e1675a2477d75d3b0ab00477de0f60273,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.5.0 rspec-support:~> 3.5.0|checksum:bd06c8e8de0cc3b1c013dc3c2d773977986441d9943b3849023d524e8bbda00e,ruby:>= 1.8.7 +3.5.1 rspec-support:~> 3.5.0|checksum:afc804793cf65b6063958388e8f335e4c6ed8a9f551fbecd2b704eee42c12e2f,ruby:>= 1.8.7 +3.5.2 rspec-support:~> 3.5.0|checksum:c1ffcb9c506c6b523a6c578b136af1f2815635f32aec65c0087a3ce38f6bd68b,ruby:>= 1.8.7 +3.5.3 rspec-support:~> 3.5.0|checksum:471a233a29fe22bfd84638c45f9251b279ec1c21348d328ec1eaaa5e028b520e,ruby:>= 1.8.7 +3.5.4 rspec-support:~> 3.5.0|checksum:d110ed5a57c54423b9db88896d4d495a067b2fdfc17d66ba43292f2c0cd04cd9,ruby:>= 1.8.7 +3.6.0.beta1 rspec-support:= 3.6.0.beta1|checksum:bc54181f9a6f7a86216e9c6638c5556dec82bd969ecd4d29168e619cf67363dc,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.6.0.beta2 rspec-support:= 3.6.0.beta2|checksum:2362e33c53621d0a6665d0eda9c6d499fa2b5d313be109a5a9e1b991d88f48fc,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.6.0 rspec-support:~> 3.6.0|checksum:2dbf3356fa41622081f2cc1ef07a04a69f668d5a4ca94b99e2e93cc13d47d7a2,ruby:>= 1.8.7 +3.7.0 rspec-support:~> 3.7.0|checksum:29a78669490cce51effb71693bbb7910b840dbf50fa91041bc30e9bde3ab8495,ruby:>= 1.8.7 +3.7.1 rspec-support:~> 3.7.0|checksum:526e0b2d22feae638eb99bd746bbb25b18a4869a8f6ce4e8a87dabd1ab5f727f,ruby:>= 1.8.7 +3.8.0 rspec-support:~> 3.8.0|checksum:97d0b30c5687075417ac6f837c44a95e4a825007d0017fccec7a5cbcec2a3adc,ruby:>= 1.8.7 +3.8.1 rspec-support:~> 3.8.0|checksum:f863cffaddb468bacde4638f30fe573053eb81bb2d244b4d805a39b55a6c0225,ruby:>= 1.8.7 +3.8.2 rspec-support:~> 3.8.0|checksum:6ef14fee2731d8a311cec6fe51a216106906e2122383923012d8743f5a7df26a,ruby:>= 1.8.7 +3.9.0 rspec-support:~> 3.9.0|checksum:f8ea89e3c1945d9d2cf1375f4211c3b1c2f8f92d73a2bbcfec405a2f1655f73e,ruby:>= 1.8.7 +3.9.1 rspec-support:~> 3.9.1|checksum:6de3bb5968447225cfd7fe7056a9d80d961f72c021222a6b5c1687251b0fece3,ruby:>= 1.8.7 +3.9.2 rspec-support:~> 3.9.3|checksum:1e68cc2e21963f9554aeca2007a0eb48ff330dc70d9e0e06e4c39ccfca9ecdf6,ruby:>= 1.8.7 +3.9.3 rspec-support:~> 3.9.3|checksum:704f3af166bb8d763199742d94f0be3027c0f26d61a2f2156d99d0444248082d,ruby:>= 1.8.7 +3.10.0 rspec-support:~> 3.10.0|checksum:62fb2683bb961a3bdaddae1a5b966825fbd65e05ac7aad0c43dc1be1d06e5958,ruby:>= 1.8.7 +3.10.1 rspec-support:~> 3.10.0|checksum:ac9abdc9577a3a34e9e92815603da8343931055ab4fba1c2a49de6dd3b749673,ruby:>= 1.8.7 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-expectations b/bundler/spec/fixtures/rubygems_responses/info-rspec-expectations similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-expectations rename to bundler/spec/fixtures/rubygems_responses/info-rspec-expectations diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-mocks b/bundler/spec/fixtures/rubygems_responses/info-rspec-mocks similarity index 95% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-mocks rename to bundler/spec/fixtures/rubygems_responses/info-rspec-mocks index 1e57491aba8..0cdccc62bae 100644 --- a/bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-mocks +++ b/bundler/spec/fixtures/rubygems_responses/info-rspec-mocks @@ -67,10 +67,10 @@ 2.14.3 |checksum:f92faf5e39abc858c8700cde9a40d934e71165c8648e05a50862d5bb7594d0f5 2.14.4 |checksum:e745b215de211099681d3b128fc8af15616eb19101bdd76da47dca1c1dd86b8b 2.99.0.beta1 |checksum:70acb81a45a5bd37eef8cb99ec14d97efa5e3fb387612035f21fbcccb3ef4b9e,rubygems:> 1.3.1 -3.0.0.beta1 rspec-support:= 3.0.0.beta1|checksum:1d7745955f2544d85773c06b1263ada4b87bf0c84dfd1adf5322ab9edf041b0f,rubygems:> 1.3.1 +3.0.0.beta1 rspec-support:= 3.0.0.beta1|checksum:1d7745955f2544d85773c06b1263ada4b87bf0c84dfd1adf5322ab9edf041b0f,ruby:>= 1.8.7,rubygems:> 1.3.1 2.14.5 |checksum:65f246c9353d1fc9f7bc8029cf6ab3c790c233e311b3b47a2dea29b86ff504af 2.99.0.beta2 |checksum:139fa3a51613e9349ebb59bb194c55359f65af886d18f1ccfb6cb3c5eae06581,rubygems:> 1.3.1 -3.0.0.beta2 rspec-support:= 3.0.0.beta2|checksum:51073bae035e96de07b99f157e60497bbe86de5533463ea462470d088bf008c9,rubygems:> 1.3.1 +3.0.0.beta2 rspec-support:= 3.0.0.beta2|checksum:51073bae035e96de07b99f157e60497bbe86de5533463ea462470d088bf008c9,ruby:>= 1.8.7,rubygems:> 1.3.1 2.14.6 |checksum:60eca91c74afd5f978eacdd60f4d81ff669910b6c24f023daecc70d364ac9abb 2.99.0.rc1 |checksum:2751d9f432d2bda1908dc29abf4a55b27c622952ece2128c7fa076d0ebb249b0,rubygems:> 1.3.1 3.0.0.rc1 rspec-support:= 3.0.0.rc1|checksum:a2f2fe16b324e15129eb21d4df3af2ae2e49a12b24010f1da3367fa9874c1f83,ruby:>= 1.8.7,rubygems:> 1.3.1 @@ -109,3 +109,6 @@ 3.8.2 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.8.0|checksum:fb84d8c2910c7ac7a3ef3179a58706fd5a2117a6462270f9fb31df8fc298d795,ruby:>= 1.8.7 3.9.0 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.9.0|checksum:4e76c19071bfeb1125b732472eb7bd6913a24bbca3da35e8169368d8b3452e61,ruby:>= 1.8.7 3.9.1 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.9.0|checksum:b9820ed35afbc552b4448ccb98984ffe20e92bff6760dbd60f4fec503d6e75a7,ruby:>= 1.8.7 +3.10.0 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.10.0|checksum:83578f61d159c3173ca097da836044610cc8eaf4e2bcfc3972260a51824fe8df,ruby:>= 1.8.7 +3.10.1 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.10.0|checksum:1467e984ac20b1cda924430fde081de8b5e0ef0d2147b2668c09118c8b9e8af4,ruby:>= 1.8.7 +3.10.2 diff-lcs:< 2.0&>= 1.2.0,rspec-support:~> 3.10.0|checksum:93fc76e312c3d19cacc1cb2eb64bf82731de2e216295cf2b4d0ce31ba77923b4,ruby:>= 1.8.7 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-support b/bundler/spec/fixtures/rubygems_responses/info-rspec-support similarity index 87% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-support rename to bundler/spec/fixtures/rubygems_responses/info-rspec-support index bc0fad5af26..7123f65bee9 100644 --- a/bundler/spec/fixtures/ruby/rubygems_responses/info-rspec-support +++ b/bundler/spec/fixtures/rubygems_responses/info-rspec-support @@ -1,6 +1,6 @@ --- -3.0.0.beta1 |checksum:f232d90c57b384f4bac7c0bc8e44b1d6171cbbe5afc24b6893e0333cacf5b26c,rubygems:> 1.3.1 -3.0.0.beta2 |checksum:c6f9bc56bb0b2f52fe7e4497597459ec09d9c083f6d9def7e9be246c5511c2d8,rubygems:> 1.3.1 +3.0.0.beta1 |checksum:f232d90c57b384f4bac7c0bc8e44b1d6171cbbe5afc24b6893e0333cacf5b26c,ruby:>= 1.8.7,rubygems:> 1.3.1 +3.0.0.beta2 |checksum:c6f9bc56bb0b2f52fe7e4497597459ec09d9c083f6d9def7e9be246c5511c2d8,ruby:>= 1.8.7,rubygems:> 1.3.1 3.0.0.rc1 |checksum:adcdb1477df1f56a2cf3ba378d6e184262b84972bec846571b0e834fdb459854,ruby:>= 1.8.7,rubygems:> 1.3.1 3.0.0 |checksum:467a90a733a99814150844be38c3823bb383882c50146a5a91e6c2f7c0b9b617,ruby:>= 1.8.7 3.0.1 |checksum:908595f18fb2f0f9f823002ccb8ef1ae73fd575f6f24fa03df2d30fafb2ccd19,ruby:>= 1.8.7 @@ -33,3 +33,7 @@ 3.9.1 |checksum:c8984f32ede2134640b3dcc146d4a335b799c6f826335e5b449d8172a87564eb,ruby:>= 1.8.7 3.9.2 |checksum:83c15ff18b4ff540872c8a6535bae14b2ec76dda42f7cbd4db77086503f697ff,ruby:>= 1.8.7 3.9.3 |checksum:394a0402aa187bb05b830640b8904946d5b5be223b3989a69cae05ef046c5635,ruby:>= 1.8.7 +3.9.4 |checksum:f4333c6df9413909aa652e8460588b36e8bb62e76e51e94c039e1b4bc3e4e645,ruby:>= 1.8.7 +3.10.0 |checksum:9f4e11812aaeaa991a128437d3398583f876906f0b9cf1de9125b26f22121648,ruby:>= 1.8.7 +3.10.1 |checksum:06a16ee6964a0902d8ce544c917253b5b53cc6ae0c712ecc6fae11e772c389d3,ruby:>= 1.8.7 +3.10.2 |checksum:74315f89069fbaf2a710e2117340373b77ee45eceb026de87e0cad9dd5154596,ruby:>= 1.8.7 diff --git a/bundler/spec/fixtures/rubygems_responses/info-ruby-prof b/bundler/spec/fixtures/rubygems_responses/info-ruby-prof new file mode 100644 index 00000000000..3cabb66e921 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ruby-prof @@ -0,0 +1,87 @@ +--- +0.7.0 |checksum:77ff44cc9bf4b1a140c227f4b68ff3db20ac0e49ba595d37f8348cfa8f056462 +0.7.1 |checksum:0817cf94be663000f0db859cf48c341eb19429cdbaf4c11fdf248c21f3b87785 +0.7.1-x86-mswin32-60 |checksum:11788fcae102ef4b87450c18e2da1da1932485fe58f4b67084a18cc6c06411de +0.7.2 |checksum:38847307795bcdcc235a184684e1590d51b3403faa6363e1805ea61208ada8ec +0.7.2-x86-mswin32-60 |checksum:2cba48b80be74029ea5ecd728a3976884ca1ad0aeec49e3d06afa6d82614d361 +0.7.3 |checksum:93057f1d87e4a753558e0dec2bbda2992d7d8bd65defa2ad03a218ee0097c57a +0.7.3-x86-mswin32-60 |checksum:b04dfec527b3ff988ba71191eefe6cdaf84bea020a4afa2e0d8f7bd31ca15228 +0.4.0 |checksum:f0e8fddbbe17d6a7f0cf967e985cf0e973b5932dab06696f92200f9ca6b08748 +0.4.1 |checksum:a71bed146b7641089719db48124b25c76d822dd4f2956e607655d4cd255b5461 +0.5.0 |checksum:86e5df43fd562142f14d7d1f53a762913fb00e5553e18359ede1e3c2bfa512ce +0.5.1 |checksum:d60eb82a14c9888863ed1b4d08eddc25b4987b035d145f2d613b6dc6b0b9c201 +0.5.2 |checksum:b22d86c9d2eff42549c48108dfc9c891d67d8afd15c220379642cb239af6f59c +0.6.0 |checksum:f54719cb7f022669456b2304bcfca129d09ad05078a03881abaec7fab9b0cdc8 +0.6.0-x86-mswin32-60 |checksum:642add9dfcefaed001c2969f7779f600987cbe61a9133933ab6f587e8eea8206 +0.7.0-x86-mswin32-60 |checksum:c9adf7f4b50709d91585d5939f07725a8bbd6f867e600b535dc8f105f4009168 +0.4.0-mswin32 |checksum:8fc30545fd30f747aaf743486e40b1c1542688ef0360927ea1db017bfe489a09 +0.4.1-mswin32 |checksum:10bab317fe1d060e8f1835933d9ae3c34ceea8142bb3815e390ad171d6506411 +0.5.0-mswin32 |checksum:834c75272f389e23b40d8ac8c9d3de41d46c852e4ae7e964fed3304d90dabe3a +0.5.1-mswin32 |checksum:b72519ec2cea75e37d3aa836954abfe29a4ca90f8ba27120ea53e68630ed9221 +0.5.2-mswin32 |checksum:ebaf1bfc807a29e91721ca1568ceb2b67cb4c68dc28c8b77f1e95eae282bc4f0 +0.7.4 |checksum:eb45f9270903134497688b7b3e6bfa9437a078d397fea976ff94f377ca4d832f +0.7.5 |checksum:dce3144596afbfed9aa2d17e7dd8b98b08d28d0a193c7d469978e7a670840756 +0.7.6 |checksum:3218de21571c9a3dc2880cc78051ee5b541fe67be4bbb1ab88cf88d8a93a9570 +0.7.7 |checksum:a1165805fe398bcfc10dc63945342625b960e682ec352913554806f558105280 +0.7.8 |checksum:7f6b7e4d2046d7f16d34eb3f827e0055eaa94924796968cf48e7068595105cd2 +0.7.9 |checksum:a712e448d41a7675303c8e7560c3c6167ad5db470226c4361dcb8260bc74c25c +0.7.10 |checksum:9b8ef8dab67208876fa5f309588a7fd2c322e519c1cd20a7184575238a01e7fa +0.8.1 |checksum:95b20f29420faa16bdd9e34b8792c4f00b8a1289b442829ce4204e0b352ebdf7 +0.8.1-x86-mswin32 |checksum:f2e94d996011b06504d9deabadf0d9b9cf1c3fff8631ae850dfcc154633fa52f +0.8.1-x86-mingw32 |checksum:f424aef9f92f853335e6482560b8ef3d8e1314a3d645fe537ea8b7ae8dca4a84 +0.8.2 |checksum:f622f47be1f6a2d916c6f6a42c21bce591816b264df97c7d83dca3c5441644eb +0.9.0 |checksum:3d230f9ebeb3ba65ba00e2503eb4b809bda09335ea28052111e299caed4f3328 +0.9.1 |checksum:d426d3e01de3491d141731b5e826ac32caa2faee1583ac6ce0f6b421d19473d5 +0.9.2 |checksum:785550e0451bf0fa280dea837560d7327ad8b496e4fa7cf1368d8c46da200d48 +0.10.2 |checksum:148d407b5cc136b651c30fd14e5dd49ae58facb0868780108f2a05144151c3b4 +0.10.4 |checksum:16ac08da1b4462b43496e4e533cf58ebe480452b35d6f924a4b1a98c7fca2b3f +0.10.5 |checksum:2ea24f12e6462386471bb062b52620282d0a23d3482ac25ef308a8092c801a36 +0.10.6 |checksum:56e0fb09ad279de623c023a704ca333594d3d115566657831bb482f701ad132c +0.10.7 |checksum:c45b8c54a74fb17ff90708d3049a5dbaf15f1788ae70137c542c79109489a3ea +0.10.8 |checksum:354876497284da44dfd69e2f6362fa99060b5cc540aa05b9ca04e636bcaed066 +0.11.0.rc1 |checksum:8406cddc90bfc149a91cba5a3f47dadf5f801fd557ce5ab5c0f605cbd4bbd9cf,rubygems:> 1.3.1 +0.11.0.rc1-x86-mingw32 |checksum:ee84835c3fdbce9f8db6f72a0a473fc9d4a55b4b94465d89da05a48af525f84f,rubygems:> 1.3.1 +0.11.0.rc2 |checksum:d73544c747eb3e5b5cbc23e2c0dd969c810966c44e5792e3203609983ce298a3,rubygems:> 1.3.1 +0.11.0.rc2-x86-mingw32 |checksum:380450f225c147984e8a0e14b2886f1d78c5460c5f19f81ac7a6d0f27605e675,rubygems:> 1.3.1 +0.11.0.rc3 |checksum:c8b67e119cb045c070a7bb41711fbcdc6b5f41dc2025a2e80fde0ad7b7ab9f15,rubygems:> 1.3.1 +0.11.0.rc3-x86-mingw32 |checksum:553b5a6a9ff4eb7034e7ef70ef15c51db0adf1f044383974a76444b6b906b3a7,rubygems:> 1.3.1 +0.11.2 |checksum:3275c9afd5e222c11a3f485e6f5ac0444ea794bf597294c8b1a4f018a197b007 +0.11.2-x86-mingw32 |checksum:29aa0b27801a0cdeb7284d8bc2c3ef0990f16b3b82626fe155c98ed42de97c32 +0.11.3 |checksum:97e66c70cf93c6895773da4cee0f6932c81902f0374d7d5e87737060a34f6dd7 +0.12.1 |checksum:332f32ebe6129b8524743c740164f8a15c2b788e67edb2f92246451d80a4b116 +0.12.1-x86-mingw32 |checksum:4e31a425b8d855927d374efe4177896cdf82f9965eb32f1ebbf3432dd74d8a8d +0.12.2 |checksum:08802dadd83f04b83fabefa220feaa9cf52941edf559aad2b7b7e86f4ff50687 +0.13.0 |checksum:b914c792a4d9fb6ff6978bcca8e9bb3a3e2c379328ad636af22ba32045e965ae +0.13.1 |checksum:f1f42552c511ae01d3aaa0436b2e170222586176d2acd7acadbbe878f5f01795 +0.14.0 |checksum:496546402d7b08f14705d33c9973625252b69fe6e3fa47ecd8db3cef4e023ad4 +0.14.1 |checksum:c4020c027472deacd164f7d823ffab823a39a9b6d94de5ee2225d039dcd9574e +0.14.2 |checksum:e6aee639bfc2c0a88cc136eb892258f7941b8a5049515b42e50b9201c40a97aa +0.15.0 |checksum:14249b82ecc830b890bbd4e517b4533a887cfd14bb14481c0b60ea583d7a7cc4,ruby:>= 1.9.3 +0.15.1 |checksum:e09f3a9554d95954ef739ed51cc1bb71ac63266f2f89c70c7df63979df23c2c5,ruby:>= 1.9.3 +0.15.2 |checksum:9466770f313ef3d668a298be691cfdb25d9d938c7c78a873467c0dd896d87631,ruby:>= 1.9.3 +0.15.3 |checksum:47058c367513bddb529e3709f4afb37226dc3bc2ee302450e9114b9d0a21db70,ruby:>= 1.9.3 +0.15.4 |checksum:e024151af60b61917ece774b07c21cfb50a63d76ac7e2aaf8c97264f1f85c7ab,ruby:>= 1.9.3 +0.15.5 |checksum:1fd5644752ca4157df9a6259d3ec46f4ee1662e615b4bc76bab3e0167a09dee6,ruby:>= 1.9.3 +0.15.6 |checksum:1a6a94b9d48a9d64e66994ea686a9a0ef015eac8a0b1e1f0f7db7d0afb491a27,ruby:>= 1.9.3 +0.15.7 |checksum:2132b4205a30fb4e1b4fd085833ea446da16f5a8f95e6920483a4313e2a7c938,ruby:>= 1.9.3 +0.15.8 |checksum:c249f42be037b0e672aea16ade483a9078fd9df445a3a8d8a9a259bc60657688,ruby:>= 1.9.3 +0.15.9 |checksum:e200a6856677aa2c25498ee12ad1aa4b4b04cbb2951fc8eb1a90f54d99477f63,ruby:>= 1.9.3 +0.16.0 |checksum:54dd3fdc8dfb578f9af0e2439f00c831573d67198660da3a3ac2974459da21ae,ruby:>= 1.9.3 +0.16.1 |checksum:30eb7606c9327f43c028821d251889b4354212af6152f5ba3742fcf34cf2fef7,ruby:>= 1.9.3 +0.16.2 |checksum:4fcd93dba70ed6f90ac030fb42798ddd4fbeceda37b15cfacccf49d5587b2378,ruby:>= 1.9.3 +0.17.0 |checksum:4c3838e460d6af672861983c80dc0be6d6c41c24d9d0a04239a8851d03a4e40b,ruby:>= 1.9.3 +0.18.0 |checksum:63c348bb67a7c51f9afae2ecef6800422cee2a09dacdf55fc76b417bea1531bb,ruby:>= 1.9.3 +0.18.0-x64-mingw32 |checksum:f7f9936716a34a9bdc8f5613390f4254bd0d43c4161090f65d7d301d36ea40cc,ruby:>= 1.9.3 +1.0.0 |checksum:a8585be7047755a40e79b2554e082a3e15fa212fd772e380401a19d2c7ae8329,ruby:>= 2.4.0 +1.1.0 |checksum:b61de70a7b37f1b64c80a3498ae5c0743c46b8bd1384043bb0dcba00892beaa1,ruby:>= 2.4.0 +1.1.0-x64-mingw32 |checksum:8cc60a783e01672d3daee8e4bbf944f20e441c6039ff2a253396953c04bc8e2a,ruby:>= 2.4.0 +1.2.0 |checksum:71f6a8e85d2d240bf88ae136ce5c02250c87daf9de2f90ca1c9012232124188b,ruby:>= 2.4.0 +1.3.0 |checksum:dc73b8beb563d0b039806affbf055fdfbe0155e1c9eb9e58d42214a8439b8d76,ruby:>= 2.4.0 +1.3.0-x64-mingw32 |checksum:75a3c2e81db58214aaa23eaed05fd5a39a2274cb065979d6bbe05d45d67c01b9,ruby:>= 2.4.0 +1.3.1 |checksum:e735d20c92954e1fa2a4475539c99dfc8d0166b4cc6915ca309e8ee2dd19323c,ruby:>= 2.4.0 +1.3.1-x64-mingw32 |checksum:a97bb6ff0abb01131ecba88799222d492d9124e057535db8e5bd47119f2a58ba,ruby:>= 2.4.0 +1.3.2 |checksum:fde14f356e08c3c8261e2935ea6601d5f434af8ae45dd5a6c82c26f7a43c9a8f,ruby:>= 2.4.0 +1.4.0 |checksum:213fe9289b74fca989d1780bc95452d214241fa120d4526e2078cdddf1cc89f3,ruby:>= 2.4.0 +1.4.0-x64-mingw32 |checksum:8c1962e718c43d8d1d9c21f14c2ef0f17a425f73ba886e1bd25e522d01c90953,ruby:>= 2.4.0 +1.4.1 |checksum:4734e32c517f6a06455f468524be87953488823968127f5d8d0046046a488d89,ruby:>= 2.4.0 +1.4.1-x64-mingw32 |checksum:44b5d11e15c3f2a77ece4eaaf298a3b6b1bc45867befea267c2be85f5ace273a,ruby:>= 2.4.0 diff --git a/bundler/spec/fixtures/rubygems_responses/info-ruby_parser b/bundler/spec/fixtures/rubygems_responses/info-ruby_parser new file mode 100644 index 00000000000..187fb5c97bb --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-ruby_parser @@ -0,0 +1,65 @@ +--- +1.0.0 hoe:>= 1.4.0,ParseTree:>= 0|checksum:2b9a143881836e05e505e68c237ac90fd5d9a5104921f3fcd3ab5fb960f0ef96 +2.0.0 ParseTree:>= 0,sexp_processor:>= 3.0.0|checksum:64958f659d2fb38e6f33d6572d172ca44ae8024491347ade0291abe2f70ec347 +2.0.1 sexp_processor:>= 3.0.0|checksum:dc6ff66e4c233a3499bcebb4f8f6d06dd59953e66f13c508856dbbe855a28cc0 +2.0.2 sexp_processor:>= 3.0.1|checksum:86fe4369d48f6347893b9062171be9b6a79c7ccab5bd2c1c36c779e17e132a15 +2.0.3 sexp_processor:>= 3.0.1|checksum:911cff4c99d6fc08f79c1a531ba35dc543ead5e30ca692b667d18fabc1206cb4 +2.0.4 sexp_processor:~> 3.0|checksum:61c9dde61254aa1a4efd6d5880042448a88904559e8d7f97e2f64533321e3b61 +2.0.5 sexp_processor:~> 3.0|checksum:aa7cac9cbce1f494c2007957c67c4f126e3b586864718c9c27ae7869f29573b1 +2.0.6 sexp_processor:~> 3.0|checksum:9d8b193efff041f685ceac205570aab93553aa30c6d83055afda9167d547907d +2.1.0 sexp_processor:~> 3.0|checksum:39346cba4bc7db864469696aa0fca5d6a3bdf32bc39b74a131551e0a0287aa45 +2.2.0 sexp_processor:~> 3.0|checksum:cf1e4ab41012219c170815d519038fc1a6294d28eddbf486369e8a9172e71cef +2.3.0 sexp_processor:~> 3.0|checksum:03d00e10a8c0ceaca51deaeaddd804335a7e20a40fe634902c82f4765a979efc +2.3.1 sexp_processor:~> 3.0|checksum:d9a4daeb41da89db62c6ba4d31facedac7b181fa5c3ba20b4256bad8cb4fc434 +3.0.0.a1 sexp_processor:~> 3.0|checksum:ed78b7fd5f1a2aa3cf139d03ef437006b73a4a0cb248a686661bd4e2f944dac8,rubygems:> 1.3.1 +3.0.0.a2 sexp_processor:~> 4.0|checksum:5108f52187925d1c802e11383ea56c30780c1dff8d40584e3aa679cd8660ed7d,rubygems:> 1.3.1 +3.0.0.a3 sexp_processor:~> 4.0|checksum:059d7055e47938db89a152b7dcdf87f4d7cea664be8cffd759d30fa83fa9e83b,rubygems:> 1.3.1 +3.0.0.a4 sexp_processor:~> 4.0|checksum:ba7e79fbfae5996dfd3f961f81c8029ea5bf2412cb2aa82e8754c3c70db6f4ab,rubygems:> 1.3.1 +3.0.0.a5 sexp_processor:~> 4.0|checksum:94419fb62fdc3ffc50c889ca3b23b21fa4f06d7ed340fe0ddc4d5c26db3bc4ec,rubygems:> 1.3.1 +3.0.0.a6 sexp_processor:~> 4.0|checksum:9ede56ab8974188ce4cda89478ed53eabff40f032703b7e278038f6d56dd515a,rubygems:> 1.3.1 +3.0.0.a7 sexp_processor:~> 4.0|checksum:d1c1a1463a2f42c343db3ad0082a480803893d13814d77b7b2ce5b0a15626ffd,rubygems:> 1.3.1 +3.0.0.a8 sexp_processor:~> 4.0|checksum:1debc498ff2f73e3560ab79ed17746641b1a31a5476dadc7735373c639ed6fac,rubygems:> 1.3.1 +3.0.0.a9 sexp_processor:~> 4.0|checksum:e40f8b28895eb01db5c03cbcf881a6938622b4106e26ebd02e04145fd9f667c6,rubygems:> 1.3.1 +3.0.0.a10 sexp_processor:~> 4.0|checksum:13c5a67fd439fce2f975c3c7800e43217973adc4b971d3a1a2c1ff8351a08668,rubygems:> 1.3.1 +3.0.0 sexp_processor:~> 4.1|checksum:552e94fa448b9f8e2fe95b28ecd7365d2d839ba33039b232de8a5c57ec1cae38 +3.0.1 sexp_processor:~> 4.1|checksum:a344b9834b61289e454dfe47c14692000655b11e9b5e70d6b65feb4ca2b1c411 +3.0.2 sexp_processor:~> 4.1|checksum:898475c12d457a584deecb19873ad030e9a0a6fdbb0f5b12744f756ebc186a4f +3.0.3 sexp_processor:~> 4.1|checksum:2deb7cb7aabfb07285a83605594b9d3acb15f2d4ec7ba375336c16a69941150c +3.0.4 sexp_processor:~> 4.1|checksum:f5ba8c07f8495d77b63c87d575ca5727ce46b375661c6aaac3567398ee9ac7be +3.1.0 sexp_processor:~> 4.1|checksum:2feb82a8e69c5b0378938b1e64a91423728aad210094d137d719b955ebc15cfa +3.1.1 sexp_processor:~> 4.1|checksum:dd036aa67f973404a3264364831119c8a67867676ccabb47ff4356908993ac4a +3.1.2 sexp_processor:~> 4.1|checksum:5fc5ad8c8df874c5bdf566f1a7284aeb64c4fc7efba091a852a12a47622f1c27 +3.1.3 sexp_processor:~> 4.1|checksum:602b23bfde88e1cdcef113fd013ebf3735b06454372b3c9b5a5c14a5b161fa34 +3.2.0 sexp_processor:~> 4.1|checksum:dd8aca14078adc35b93d84cd8d2e8aef05c62cfe1dedba9fa5098a33b3511004 +3.2.1 sexp_processor:~> 4.1|checksum:709387ea73ceb080662dfa8ab669a88ed7aa10d5167764d4e4d66025fc9528e7 +3.2.2 sexp_processor:~> 4.1|checksum:117d814b406876a8b6a85a28e2745de524924edefced9233d597bae6fefd7fcb +3.3.0 sexp_processor:~> 4.1|checksum:1a4d3a0eb26d33dedacc1e3d125ae7578d23e6f4d98bdcdf7c2f5a55569d5578 +3.4.0 sexp_processor:~> 4.1|checksum:7dd9189122d3bd7963a98b99d97f0ec8e568e63a1805ba4889ec83e2244de4bd +3.4.1 sexp_processor:~> 4.1|checksum:b84fba8fea75d83354c9cf35609a3df7d74669e49f05b654577ef85a27d6b8ab +3.5.0 sexp_processor:~> 4.1|checksum:7e703bd90e8fc0a45581da62b9673401855b0259bc6f862a7ada715fecfa34d0 +3.6.0 sexp_processor:~> 4.1|checksum:23b1829af77083b5242fc47c100332704b4eb2e39fd2051d98c53d2490337817 +3.6.1 sexp_processor:~> 4.1|checksum:3026f95839cbdd4002fd23572181cd93764127bcf339b1d9787fd1972fbe641c +3.6.2 sexp_processor:~> 4.1|checksum:d113015e56063e8c6f454886e69570b5dbedb9c80f2a822e6f874db6e4d2b346 +3.6.3 sexp_processor:~> 4.1|checksum:926434eea57cfd15e0554fe0ae8e769656fc18e75024b0b3f44e166711540d88 +3.6.4 sexp_processor:~> 4.1|checksum:f4ded7729953ade0779ed970d58cbbcc421a2123b193a6517f1b3c20ae2ed472 +3.6.5 sexp_processor:~> 4.1|checksum:9254b52b8ef3a56aa0af050066c7c815027d699af5620bf26896363691f34d3d +3.6.6 sexp_processor:~> 4.1|checksum:d3a3ff8e472f85d769e848caa94938e5c4a7b5d9df75384056431bade8bd2cf5 +3.7.0 sexp_processor:~> 4.1|checksum:95d2036b753f399706e3478c1033a81520b27ccf8702e8de076cdfcaff5f1de4 +3.7.1 sexp_processor:~> 4.1|checksum:7cba241552f03f2db4911013fa40bcd925425f713aa712ebdf34431f1d15ab5a +3.7.2 sexp_processor:~> 4.1|checksum:7f639194041e51680b530480990c0ca3632507e3740a8ef4516592550e3037e6 +3.7.3 sexp_processor:~> 4.1|checksum:fdcbe21874bfe584ab329bccbc1fc0c2bde9d3c7d0b076b10de18e645117f1ae +3.8.0 sexp_processor:~> 4.1|checksum:f2d68be328136242b29025cf3f21aeedc1df1d61755405841609b7ea72612ec4 +3.8.1 sexp_processor:~> 4.1|checksum:bccf48faf69b90f4fcb587c86e3cdf3215a9aa30dbd092f09a4c8033366bcb19 +3.8.2 sexp_processor:~> 4.1|checksum:0c600cdf79a9d925d8c06b65bbefffba34ce7177520d1545659ce03d252f2173 +3.8.3 sexp_processor:~> 4.1|checksum:482d5eb7ae48dd054d840fcbbddf162fd8beca6c3e666bb6c8166ab82b872a77 +3.8.4 sexp_processor:~> 4.1|checksum:fe65c8fb428692818c9f693ece50a7d994e1d19b5d5bd50ccbcf6b26ee2f89e6 +3.9.0 sexp_processor:~> 4.1|checksum:76e4888893b75e563a6f60547d91e759469504b9b37607990eeced58ab5e57a1 +3.10.0 sexp_processor:~> 4.9|checksum:15b284c9bdf310a41114287e462b63025d64ef1713b05200d62ec5a96df1de68 +3.10.1 sexp_processor:~> 4.9|checksum:454806d4e1b2c606f36f7f4cc9cfd981c8bf6c7485b4e1963850ccdee6e20b38 +3.11.0 sexp_processor:~> 4.9|checksum:419239c3b8d6c015f86eb110dee7c85a2527cce1be3ba86133d66fd87dabda57 +3.12.0 sexp_processor:~> 4.9|checksum:bd7c7dc8de3b27665246b182061b83f81d077435b2bd77a1b8c753577a9fe059 +3.13.0 sexp_processor:~> 4.9|checksum:9731d322ed8251d325602e6b82c647c667a263090593f9be6f331f73ab231311 +3.13.1 sexp_processor:~> 4.9|checksum:273f1d203a7686d7945640a92e8f65d5b1f4109da1e4e1a16039e6aa19d37068 +3.14.0 sexp_processor:~> 4.9|checksum:0b6f6534e4ffec35097e34bcbf4d68cc16a3ece4d70ff4e16c7076bb622cb2ef +3.14.1 sexp_processor:~> 4.9|checksum:ffb4dcf7707c7ee6edb53039f8394e5741a94eeb17a75d0d1cc76333ab19cdbe,ruby:~> 2.2 +3.14.2 sexp_processor:~> 4.9|checksum:cc28083336412b4604f7c7c766cbd8b6075d27d7a9962a9979e70e2ea56f0c27,ruby:~> 2.2 diff --git a/bundler/spec/fixtures/rubygems_responses/info-rubyforge b/bundler/spec/fixtures/rubygems_responses/info-rubyforge new file mode 100644 index 00000000000..0dd67104866 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-rubyforge @@ -0,0 +1,27 @@ +--- +0.3.2 |checksum:559911a9bc63b346d5d67eae9f17c4799d896af359a1cbe185a598c56298c21b +0.4.0 |checksum:06757bf86e22d52f4876512114e26df81c002ab6d01a981f68a2c5c0299dd853 +0.4.1 |checksum:0af4e40935404f39bec14af04b223b6219a708a07cad7610e0ebe7757f9e687b +0.4.2 |checksum:5bf2761c82d78bcf99799f5c27c3c0e62d4e5b28c40d8937b85f4c7e9b8330b2 +0.4.3 |checksum:b01a0498e80ce02a91803417b7bae0abff4d43bad6b9a1a5a2397b657ba3b6a8 +0.4.4 |checksum:5cf63172076cfa4feaa7e7f5510c0368dd400ebef7b0f673b9e3e4ee4d22b34b +0.4.5 |checksum:46608d6aeaff698e66642d4e8f56518f6d52a63ad11eca7949b9d92105627a5d +1.0.0 |checksum:84fc56eb13573a18d291fc9cb9181143c95f928e7b1dbaf44a64c72effc94345 +1.0.1 |checksum:5778fb7bff9ec48e8c9e3c60c98b29e27861dfca29a6d56c83ddb2d06a3b7b96 +1.0.2 |checksum:32a2b1e67d89f8cbf215aae013e668bcde4b0585bd748f93ad9cdda394eb324b +1.0.3 |checksum:dfcf9cf95eac205b472d92a3937cc841a362acd36c04b8bc2f99559b2b5a905f +0.0.0 |checksum:2fdaa0bbbf9337c6c209c70a2b6a0356335f1b030c23a2bde4715f3fc6806972 +0.0.1 |checksum:2f93ee4681072548bf0e16f2761b637674e57492570d1d504b1deb1148df0436 +0.1.1 |checksum:10cd6e4ebf873653a8401cba95c785bbc9f5e0302499a41fea54afe346c578bb +0.2.0 |checksum:c68b9ba325050e7511da38c23c20ced56d46fbda5cfe0457f830db8ee9687890 +0.2.1 |checksum:b94513ececffcac307cf328e465eec3bee4759abcdd36a8dd8e4ff7d70df7d1d +0.2.2 |checksum:34aea32bf3ccda183b71a0742fcb203b7f7923131ae03ddc1850f6c1280aa307 +0.3.0 |checksum:a9095158c144d03038e6ecae9611bfd3d073c32a68dc117b2cb3838c36a1efcf +0.3.1 |checksum:1fa3b4bdd7d63d9979621737055c6bb203e7c24175f22d519691f53952622997 +1.0.4 |checksum:0a379c4710432c3ecbb106eb4fb00857c45e1a0de0b5f070fe15c1047624b521 +1.0.5 |checksum:7b40847170d5a26bc559342ac0cf7aad8dcbee22c91a8d1bbb1695456a916cf2 +2.0.0 |checksum:d4c211c07fb7b955ef347ff0df657a5cd675717d7ebc4aa5e29dc1a28096bbfd +2.0.1 json:>= 1.1.7|checksum:83399e3d13a7d5f8c8a48fec57297adaaa608599535ff54011ad4a4b688b6e75 +2.0.2 json_pure:>= 1.1.7|checksum:047739ca7306e247ea4f503a77c05ecf4ce73bffe3f89eaef3cfe449455b1be5 +2.0.3 json_pure:>= 1.1.7|checksum:b7bc7e31c24606380083e35a12c7ca6c5f5b6d688fec145011be95d2d48469b2 +2.0.4 json_pure:>= 1.1.7|checksum:017207028a37a77e79523944b893f3148b1397cf41394490ff3e0dff2d51aaf1 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-sexp_processor b/bundler/spec/fixtures/rubygems_responses/info-sexp_processor similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-sexp_processor rename to bundler/spec/fixtures/rubygems_responses/info-sexp_processor diff --git a/bundler/spec/fixtures/rubygems_responses/info-spruz b/bundler/spec/fixtures/rubygems_responses/info-spruz new file mode 100644 index 00000000000..152740093e8 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-spruz @@ -0,0 +1,18 @@ +--- +0.1.0 |checksum:3c55414d5113f223105e984323bad0c95c7eb251e9008dc61939802890b0e0e1 +0.1.1 |checksum:c791030d74796c644885ded5144041c7f11c084b9667fbac907b7017833b5fbb +0.1.2 |checksum:e06ac3eae22edcdd1e36fc0ca61f2ec4b0680001adf454b5aef3412dd58c35e0 +0.1.3 |checksum:3f1345337caea86cde11c0004f784409dca38f2dadb030c0cc71fc97f977688f +0.1.5 |checksum:3b6a4c44b2e4d417fcbed6ba3557de4feb9064283a8d3d7899bf206a57162ab1 +0.2.0 |checksum:5cfcec01628a7af246f4f0d58807be701cd46bf166ba52957402f8f0568ba207 +0.2.1 |checksum:6d631df56ead6f0d60121f192090f72c675e8744d344713c64bc7f156a6d8493 +0.2.2 |checksum:fbd9f760f8be38f712cff3f561da2eb0d313ea7da46b95c9ce163e57f6326852 +0.2.5 |checksum:29a44843bc30223cf87b7082c86ea644a6cedd4a48f93b68ffc0488cbd5a343c +0.2.6 |checksum:b92b0d8f355547a10aefaec1cc30c5672c04457314a44b08dd662bf23c3d74fb +0.2.7 |checksum:d8692bbd5d2dd625a98536a5af0b0bac26d636247cdedd4f0c1bc6fbdb30e4ea +0.2.8 |checksum:e557ffdc11a369eea2602cf07986d4aea7cb4297d6d3d9e9c4e6f5d9545950b4 +0.2.9 |checksum:5711201458067f85253990b030495306ec441c8ffaf9013cfc326a0a47ba499a +0.2.10 |checksum:d1a4c6db0efc74a432c4346422109947a0b04d012ee4fea285b4ed1d98230f2e +0.2.11 |checksum:712adf1a9699b8c7fa6264236d892d58389da507ff5fbaba37df9c9ef6affd62 +0.2.12 |checksum:6e0853624f5cf1d8766c7b553305764e30b2b74727ba695f0c7f094b94e2ee03 +0.2.13 |checksum:c195d5f7c4199f289c88687cfe3561b15367ec262a7767374eb2d969b9fe2e7a diff --git a/bundler/spec/fixtures/rubygems_responses/info-sqlite3 b/bundler/spec/fixtures/rubygems_responses/info-sqlite3 new file mode 100644 index 00000000000..26e77e7572e --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-sqlite3 @@ -0,0 +1,55 @@ +--- +0.0.0 |checksum:6e7a3287eaf757fcdc1abcb5b7179510171383adf1e8ff2e4e3186a7de9bb3cc +0.0.1 |checksum:a27415af0ff7214ec39c09fd5438aae64e411e7dd3b6129e90b09984aa1d283b +0.0.2 ffi:>= 0.5.1|checksum:3364873fa06cf0cf675dcfd80e794fe81c09aeaa5a5224efb91544dcfae1c621 +0.0.3 ffi:>= 0.5.1|checksum:634aee5e932ae68b7ed5bf20836890530228e0d73f21c7d0d549b5f54dfbeac5 +0.0.4 ffi:>= 0.5.1|checksum:7f00c82723705c480c971c72eb966b8d6cc58c62beb57406617debde735b68a2 +0.0.5 ffi:>= 0.5.1|checksum:697dc9687ed10807f2400624dd5b24b2877631f726389538e92c3741996fa42d +0.0.6 ffi:>= 0.5.1|checksum:cc043193c43d07523d70c29315e009931a502a948e1826cb29b337020c65c346 +0.0.7 ffi:>= 0.5.1|checksum:2dca1c4538373c47fd9f53f3d20b4ac18d9892f1068a36404d8ce4e0e7ef3099 +0.0.8 ffi:>= 0.6.0|checksum:a96b89d1e239c0acca5a290e5fa84f8fa1e04fae8b07ab6b89715c96784b63e1 +0.1.0 ffi:>= 0.6.3|checksum:f19f400cc38843f0826e679a0346571a31b01b43ef721b5623fa81ca52599e9f,rubygems:>= 1.3.6 +0.1.1 ffi:>= 0.6.3|checksum:94d8cc80b075f0e9177f878074588dc906cf97b6b872b74772a0b9db44228056,rubygems:>= 1.3.6 +1.3.3.beta.1 |checksum:f2d9e5416e91bc8d9ec8e4b789f77f3c4d189842e9d39e478cce257dd028bf8c,rubygems:>= 1.3.5 +1.3.3 |checksum:294f92e8eae56b45ad2416bb929046c5b8024b7f73addd80963ace5d909503be,rubygems:>= 1.3.5 +1.3.3-x86-mingw32 |checksum:c56069d8b615c84ea61079eaad3998e2653f7da040d9e6bca407a8fcd575ba2b,rubygems:>= 1.3.5 +1.3.3-x86-mswin32-60 |checksum:3c77d2290c9ce5ffe3b9e0a176de4c62713a57492cff6075c99a2f9b0d93271f,rubygems:>= 1.3.5 +1.3.4 |checksum:2f16a663177a53a2f5b62a6adf59f59432081316f44670edb8576c010badf3aa,rubygems:>= 1.3.5 +1.3.4-x86-mingw32 |checksum:d0f9f52a0d39b90ff13ba61ad26db1db25a5638d8f815a2d787e3af8e5e3b567,rubygems:>= 1.3.5 +1.3.4-x86-mswin32-60 |checksum:22fdb956c428f159134c1e763844a4c13c3cb052be8e0c911c342e2639b07f01,rubygems:>= 1.3.5 +1.3.5 |checksum:8ff3956eadcd24dd1dd83de09c3594a5cc8a8400a6edeec3236dcaba605a017f,rubygems:>= 1.3.5 +1.3.5-x86-mingw32 |checksum:d70f46f991b1a66163e0b827e13d7371903a1a82e60a1231519a2e75d3de3552,rubygems:>= 1.3.5 +1.3.5-x86-mswin32-60 |checksum:eb0f6d7afd1153b437076e2acf83222bcca628d03085a3a1d179a5f0a43b87b8,rubygems:>= 1.3.5 +1.3.6 |checksum:b0063859dd46819dd228f9629adfbc16649dfeef35b90eba9757537c0be1ecdb,rubygems:>= 1.3.5 +1.3.6-x86-mingw32 |checksum:938f2a69820299cf52658ac0ee9d6b66de597796d6c25d9ae5d01ca1adbbe53c,rubygems:>= 1.3.5 +1.3.6-x86-mswin32-60 |checksum:bb805d4c2fa354c749662ea155cd8736b960b83768852979a0e8980c5f349082,rubygems:>= 1.3.5 +1.3.7 |checksum:7e1115e569aa9e993eceda01087d10147586d38d5cb7678c638b9d42894b9962,rubygems:>= 1.3.5 +1.3.7-x86-mingw32 |checksum:a4e7f09be6a6451de8ea0727c9c2ec2e91426fd7eec2945992edf80b11c86673,rubygems:>= 1.3.5 +1.3.7-x86-mswin32-60 |checksum:013629564e28bda827e9148cf233592a95d5fab8256356b2478643aafca54d99,rubygems:>= 1.3.5 +1.3.8 |checksum:6a97b019e177d33472bac1aab199d9ae8c24f18eb63461cadc3223607a82287a,rubygems:>= 1.3.5 +1.3.8-x86-mswin32-60 |checksum:5a4ca80302d8db00d2846e61aab63c92bb3aaa833c08d1e0ea38f52dcdd2c77b,rubygems:>= 1.3.5 +1.3.8-x86-mingw32 |checksum:f9769182e878a7f9d8c464b9d90d93365a99f24c35da9ebf50c261c1c1e01702,rubygems:>= 1.3.5 +1.3.8-x64-mingw32 |checksum:276fb078cd58caf96fa7c0bc96703b154cddcc72d4861045b862a2612f1c558c,rubygems:>= 1.3.5 +1.3.9 |checksum:9984744afb5f44ca4a82aec66e257ff60783920afd48f06606d1fb4a9d51a61e,rubygems:>= 1.3.5 +1.3.9-x64-mingw32 |checksum:df2b87185ce915dfd2e6e0274f2250bf9179553bb2ed7e7ca9e1c28829b86778,rubygems:>= 1.3.5 +1.3.9-x86-mingw32 |checksum:e4611d774c70d0fb88ef62eefcec60026a94c407afc08e80cf3cf5d83eb68d4f,rubygems:>= 1.3.5 +1.3.9-x86-mswin32-60 |checksum:b27b6892205f16a12cb96a5a80b9f1aaa0492628b287154bae50e281253386c2,rubygems:>= 1.3.5 +1.3.10 |checksum:70d815be84bd9630a0b68b236fd2811eef4297a8e4b53e3df89dd39f2d39efe3,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.10-x64-mingw32 |checksum:ce0caf40b9de641939cc4b2a3483f9f07e8c4ca6f25b720fefd8578d2429b377,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.10-x86-mingw32 |checksum:b33a03b057466651eec78d753a9fae781a2309ab4f30e49624290cee54d25ea4,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.10-x86-mswin32-60 |checksum:b138aac785316c72513cdd75509b351c796201cdbc8dadf48ec966aba7af0ee6,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.11 |checksum:de8ecdcc00a7af0cda98661ed94ce442964b9403b425e95c3ac4544b1f3720a7,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.11-x86-mingw32 |checksum:ad2642c0d4784b6bc5849b4cdbb34369c989f0674be4971dff7487a55a43aa98,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.11-x86-mswin32-60 |checksum:9eac9bedb5b9caa715fe01748b14891e66f506dabc01de53a688075d4dcca946,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.11-x64-mingw32 |checksum:7acf1ed8b4cc38f65f3b3558491137013655dac44bf3e770c6733bbb076e9f1d,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.12 |checksum:7d912f1b53d4bc11f84c4076c7ebae73bc21a9d82cc2df750fc37bbef3418d42,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.12-x64-mingw32 |checksum:ff7ec641442bf9a91f796cd2204fa8eab4702bafbd70ba3bac70b29d199766b9,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.12-x86-mingw32 |checksum:2b032c8c8e65ca74466ea9473b5514010a425dde9b5c12daad4ed4ce1cbf9dd1,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.12-x86-mswin32-60 |checksum:de94e26efd7b88bf7e4a18df3cc79dcf2fe69df485955425885d38043d67476c,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.13-x64-mingw32 |checksum:7acc8d8b7eb9a408b872100bafb1ae3cb5d65e7fb0af7124ed8c1c202105215f,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.13-x86-mingw32 |checksum:09c26c2c82b580c8262b74742caf6ac8bd554564e7f087cb4110ddeee95d2d21,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.13-x86-mswin32-60 |checksum:46b4edd6af3c9be97a2f4389ace8741787fb04ad863d4c4d66b003303626c4aa,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.3.13 |checksum:b138a22e0dbbb69be08540671dabf602599437e389a54054bb177f6ed1fd2e06,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.4.0 |checksum:dd8d2991c7acadf79c00ab1e175e105c7389bc94f3cc4c8aae173d2d3abeaf5e,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.4.1 |checksum:2491f5af05d6f9456135c1c54547170f07fa2e732d772b4d757168ce961d20ed,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.4.2 |checksum:e8b8ef3b0f75c18e1a7ee62c5678c827e99389e53fa55eb7a9a5f57459004a52,ruby:>= 1.8.7,rubygems:>= 1.3.5 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-statesman b/bundler/spec/fixtures/rubygems_responses/info-statesman similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-statesman rename to bundler/spec/fixtures/rubygems_responses/info-statesman diff --git a/bundler/spec/fixtures/rubygems_responses/info-system_timer b/bundler/spec/fixtures/rubygems_responses/info-system_timer new file mode 100644 index 00000000000..fdbeea30b57 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-system_timer @@ -0,0 +1,3 @@ +--- +1.0 |checksum:31818879b01ef34a4821f80febd626e5af797686b10caa5cd239ac8a991029be +1.2.4 |checksum:2827ef2ce9e6404f0bf0bbaab3b0f4ade51fd808cd95c9e04f00737184ace4e2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-tenderlove-frex b/bundler/spec/fixtures/rubygems_responses/info-tenderlove-frex similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-tenderlove-frex rename to bundler/spec/fixtures/rubygems_responses/info-tenderlove-frex diff --git a/bundler/spec/fixtures/rubygems_responses/info-thor b/bundler/spec/fixtures/rubygems_responses/info-thor new file mode 100644 index 00000000000..0d4c81c70a0 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-thor @@ -0,0 +1,50 @@ +--- +0.9.7 |checksum:e40868b5d8ad462641561a574fd85dba18665c477e1354fb2b90b91e52082599 +0.9.8 |checksum:a8f3d8e6e811594eb04e0547ca1c06065a6963440dbbdec8607c5ce8fdc16dd0 +0.9.9 |checksum:37f6c3a9321d85c444c0a7e9aee6fd789575da2b9b785f4d41a6a959de32c73c +0.9.2 |checksum:d44909764d4f6a312e3370324062b39a5548575d99cb81f3cd8f68fa5315d133 +0.9.5 |checksum:5869e92a1c32e7cddf694e27f0f24f301a1a8a001ce3712c282504fa658c5c07 +0.9.6 |checksum:d0ea6643ffe3b9cb77b09dbff5fc0614ba9019e981b6de63a26eb31fb41436cb +0.11.5 |checksum:fb4efb074a784f4695a8c853e3e95b66a9b5fd516c8330341b98d467f2ccad96 +0.11.6 |checksum:45bdfeb7efbeae4cc4e92466e7e65774002954d7f3406d5d7c5b493cd9f334bb +0.11.7 |checksum:18c5c0f500c831e0167eae7f162c70260c70aa2bb4976e6dc1c2388b38bf9e94 +0.11.8 |checksum:c2806f502e883918ee4e1fdd37d7d09674fba8cb44a6788682feb6fdac5f489e +0.12.0 |checksum:a97f63a7878fdd53173edef11111982c99cbae31cd75003acc986d893d15ea09 +0.12.2 |checksum:fa4e19b68a0755e2f16cb7111c8264549e3e597cbf8c4bced4ce2afeeaa79d14 +0.12.3 |checksum:5121139404d9b9b9679a2b2abeb24ffd1dbea629432beb73469d98971d38653a +0.13.0 |checksum:ef3be5c56224de66b1116026a4ca690ee6724f79f948df61693921d0e6531df4 +0.13.1 |checksum:8a224c971cb7da8cc952a340755a1952c9b41244662cfa138779d7a69d831f40 +0.13.2 |checksum:5a36a9de203bbd12b7c8b7aca31988e137a10cf6ed31fb48ad2c97b275137dfd +0.13.3 |checksum:452696887b261648ddb34a012707408e6b44ade05e8633915cd91912cd5a374d +0.13.4 |checksum:10b95910a02169f162fb411614d905b341176520767919c3b968b99ee69b3ee1 +0.13.5 |checksum:b8e139e77b94eaa60f71a1ce749c8fd930355bb45ead402610d7ad4e4e6b6056 +0.13.6 |checksum:7870dde29f00382ab1aaecdc38458307d0fd3f35830b22ccb2dbd0ebd07ba736 +0.13.7 |checksum:45d34c2189a66e3f572512c1d3182a9c36039f66dff1225a73d6ce4a74ae2a9c +0.13.8 |checksum:ebaf56b01731ffac855505d7eee664c14101748654f00dbb99506cf1c155da3f +0.14.0 |checksum:41e64fd5fc06a751200df72c6c0cb88a9cf67b0a4e301da6d4b54214c8efbf84 +0.14.1 |checksum:a3e82e0396d30c9131cea05526ffe866d3f9cc882d6b249685ee693e8a5fb600 +0.14.2 |checksum:3fb1da45fc959f7905657f5d67f2ad92dc8077e0b4ffdf0ff34310effe29ff28 +0.14.3 |checksum:011e58fd92548eb3afdcbfc1bb4c8534ce5c8d73e3e1dfd5af66c7d8f8577755 +0.14.4 |checksum:8905b304fb9aecef0dd884b5873009e36f93055c290199fd654bc4f17c800252 +0.14.5 |checksum:5268f292e4c1a3b98661145e3cd271207622c5a53a86a98024b9b5fe98e3b702,rubygems:>= 1.3.6 +0.14.6 |checksum:c7c5abd6b7dfb331efb8740276724773cece66e1fe6b83216589bb87c67e15a3,rubygems:>= 1.3.6 +0.15.0 |checksum:b42d32f337140635f27fcc47369c16b559bbfe0b8abcc3da4fc66444ee2e3e2e,rubygems:>= 1.3.6 +0.15.1 |checksum:02242905e2acd27638e2205fb764c894a507bb29844dd07d2fac17d810e929f7,rubygems:>= 1.3.6 +0.15.2 |checksum:193a7447b2cd69c640117b086c07f247c7c38bcf77b00b5225aed77201c4bab0,rubygems:>= 1.3.6 +0.15.3 |checksum:186e682750ec46bd3e2eb75d74e355678235200185a8f2b39c8ef47deb2e3440,rubygems:>= 1.3.6 +0.15.4 |checksum:8845d634e9dfb5958fa681adc8e4cbda3b5e8335cc325ebec937824d2e199ee0,rubygems:>= 1.3.6 +0.16.0 |checksum:864aa9842885f554d9750a4df3c2869afd20a2914b24f421c8bb3e4d00a982cf,rubygems:>= 1.3.6 +0.17.0 |checksum:42d12e3f91aa9d33c081426028fcbbdaf8d4261fcb56a18088f539e61436c43d,rubygems:>= 1.3.6 +0.18.0 |checksum:5675373bff6a940dccd163cc5f17af804c73a5eb26eada5ff501178942a1f754,rubygems:>= 1.3.6 +0.18.1 |checksum:8321c57da1b142327ce802227fde78fefd04f9a81467e45a9cee306de4192f34,rubygems:>= 1.3.6 +0.19.0 |checksum:090a51ab8ceb4a48cfa1c4a545f7653161db0fc7e95399ba8293e80f2f87bc0d,rubygems:>= 1.3.5 +0.19.1 |checksum:9ff834f031b5550c743bb8a3139317fefdae9cdebd02d60de376658f427fe522,rubygems:>= 1.3.5 +0.19.2 |checksum:5badafca51443e02db479e623a02e17c6a7d72158e4bca3bb7bf04983562aa48,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.19.3 |checksum:b7aaedf8373dc5ef218d94906d1562e3f305e0f25b05a36866ac9a1bea724404,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.19.4 |checksum:da8aa62e197c5c203d9dc3db06314abdab2d8dc9807d0094a9c0503cd36ec506,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.20.0 |checksum:b47dad86e151c08921cf935c1ad2be4d9982e435784d6bc223530b62a4bfb85a,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.20.1 |checksum:2c8f1dfd23b6aae4c10ab31d8e815813f5e0e76ae54b094cbd156710962c071f,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.20.2 |checksum:50f3e8479d53c39db05899a349d8a319fe7c9da323b406a0f87e0902b22083d0,ruby:>= 1.8.7,rubygems:>= 1.3.5 +0.20.3 |checksum:49bc217fe28f6af34c6e60b003e3405c27595a55689077d82e9e61d4d3b519fa,ruby:>= 1.8.7,rubygems:>= 1.3.5 +1.0.0 |checksum:1d81e6cd805a9e5ba8f4c2e25f7ec09e299dba48443b4a16422c14df9bb32601,ruby:>= 2.0.0,rubygems:>= 1.3.5 +1.0.1 |checksum:7572061e3cbe6feee57828670e6a25a66dd397f05c1f8515d49f770a7d9d70f5,ruby:>= 2.0.0,rubygems:>= 1.3.5 diff --git a/bundler/spec/fixtures/rubygems_responses/info-thread_safe b/bundler/spec/fixtures/rubygems_responses/info-thread_safe new file mode 100644 index 00000000000..d74908cecb1 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-thread_safe @@ -0,0 +1,25 @@ +--- +0.0.1 |checksum:b1f7dfeb8bc765e421a90836c6a7e7dbe587abe238b2f660a89c6ad6e8e4975d +0.0.2 |checksum:bd74ee7ad95567721f7cd5757d6fb5a6cbf21e6613cf6f187ad3d72c245c2b39 +0.0.3 |checksum:d4fac31142dd3262bcf4e66f730e8ef5d0f058e4f5bc43d510fc4db92a4085e9 +0.1.0 atomic:>= 0|checksum:4ee7605080ea11b1bfd8a5d7ddeef97a73609d1ad8355e648c91d00842201d3a +0.1.1-java atomic:>= 0|checksum:787f8084a847cbe26a9aad685a6e7b46ae113cd87aa144d78a9c3e4f631161db +0.1.1 atomic:>= 0|checksum:3102637a5f58ebb8adfbffad76acd9d40b2f0889c3fb4959a9b5e45b6f82942b +0.1.2-java atomic:>= 0|checksum:d31bb9b0cafd67510f9d5d026064e00c99dcd2935fe310a9deba987788146da7 +0.1.2 atomic:>= 0|checksum:7e2b957c28f2676b0a5ba5c0ad3a92988887922edfcb7be66acac6106881beaf +0.1.3-java atomic:>= 0|checksum:24905e6433a692412ddfeb2105c4768266ef693b7e51d9b9dcdb789141b5a7e1 +0.1.3 atomic:>= 0|checksum:f8b9f8db0889aa97676b4a1efe919b1e76601ed9c9662a986825755bba305c38 +0.2.0 atomic:< 2&>= 1.1.7|checksum:a85f7f14c3269fd6c77514aa4fdeef20bef19eee91839762b3b4a4f8cf323145 +0.2.0-java atomic:< 2&>= 1.1.7|checksum:a184903697075973c6959e48ab28b8f6c3ad628728bb2817c2b0d0bc6aa67433 +0.3.1-java atomic:< 2&>= 1.1.7|checksum:d71d0686a011d478562460c7734694c750afb03f769445bd46c6da740e869020 +0.3.1 atomic:< 2&>= 1.1.7|checksum:aff0cf52e87876f46767c5327b8c4332381c6f6f832dff36679e928c30b82f3d +0.3.2 |checksum:e66e8c03414aa0e1982a5f505d659ed5fd1a411fee71b8e852ab57e0eb9e4853 +0.3.2-java |checksum:a475303101015f279b2791ddcb821e275d0f76cbce46251359a15d39dfb69117 +0.3.3 |checksum:f0f4307ea85d6eff7f9c304587073e3465da58beb198ea686bf69ec87f2ddb7e +0.3.3-java |checksum:e8122caeee98b9294f36760ca1fcf5589b4e27ead202296ffef6854b01693731 +0.3.4-java |checksum:903716024d787ea90b6647c81f3ff3710721279f1ed435fc0e219582ca851ba0 +0.3.4 |checksum:16315baa971c48d00104bcd35e8934e3f9ccfd3b8f429e3fca7ee2dfd81734b2 +0.3.5 |checksum:993da065f98b8575c537ebf984ffb79eecdb6064559a3b9d2a9d7aaf313704c3 +0.3.5-java |checksum:52976573c9934c696a0c577ea57f51e38714191cc6bd0fac499f9ad5843e060c +0.3.6 |checksum:9ed7072821b51c57e8d6b7011a8e282e25aeea3a4065eab326e43f66f063b05a +0.3.6-java |checksum:bb28394cd0924c068981adee71f36a81c85c92e7d74d3f62372bd51489a0e0c2 diff --git a/bundler/spec/fixtures/rubygems_responses/info-tzinfo b/bundler/spec/fixtures/rubygems_responses/info-tzinfo new file mode 100644 index 00000000000..7f3e5b9b005 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-tzinfo @@ -0,0 +1,83 @@ +--- +0.3.2 |checksum:c322b0a666986e19d046363cb5aea644380723a225a1ab9f592f8ab040537d4d +0.3.3 |checksum:f9222a8050410b8a035ca65652010771323f8178ccb4c9046a05216a939d017a +0.3.4 |checksum:b6e89f588a478067b511bb013e7184f6ed4247f4a37315466b75f7de82154a62 +0.3.5 |checksum:05cebcf8784ff2b3ca96bb610bbbbe877f712631be7fd8d610044aac0ffaad8c +0.3.6 |checksum:323bd84db535687dba17c866ca1cbbfa23e630ae9bd2a1233e8fa2d331d7f64c +0.3.7 |checksum:20b6713ae44c4146f998a564dc19cff824f090d35566f1bdb7bb56ed7315ae91 +0.3.8 |checksum:656fe8f6444bedfc1a9e4ccb11c7c9c2a030a76610ec92363559c958625ea884 +0.3.9 |checksum:cc2c9816b7130e5096f9c377ad8f014295b2394529446a7b20a614fa7abcd886 +0.3.0 |checksum:f7b3e4e125e96457167101e223c5bf481fc7172703fed4a8834b0eef1226b45f +0.3.1 |checksum:21d199e0c2c7eae3425ba754e0f8c9b215dde2582d6daa818d51e85a97542d32 +0.3.10 |checksum:3f01fc1b08ba4eb874e01be32f063e2540a24574ae44271b7eeb88d5d49c0678 +0.3.11 |checksum:6ed99c3b2fdd10629acf9f1b5a5a2895f8f69af28019e256ad6fdaaeface28a9 +0.3.12 |checksum:509f647f6874c0852b7b9227592860e34bd3b506cfebca8b85fa392efc5a76df +0.3.13 |checksum:5921930f55a19bbb80d2319479177c18aa4ea70993ece92f584206791dcecd7f +0.1.0 |checksum:bbc4b7284f6795b50d5bb1b0b092b7621821761b8a1e025c1e4a6c7ecb7c3623 +0.1.1 |checksum:cff8552c1f45ac493003b32955ab2f188402b5f77d8885694eae32ab9a51a76c +0.1.2 |checksum:9483b180f0d9a3b3c65ff15b3006c67679a91e4212aaaffc12d3058c7f1016ee +0.2.0 |checksum:2f56eb348dae07ee35340c215f8413479d5d0878a179e199ca1ba78dd52993f0 +0.2.1 |checksum:50deb24ece072659b946993ca2d1e1c3b286ceef9a6ab6a56a71eb70eb75ca7c +0.2.2 |checksum:bb04510c88413365158a29ffee7032c7e4699623894d4d2862923689b9e2a432 +0.0.1 |checksum:859413ad1026e079713dbf097cdd329cea09db6ef3ba10fc012718c849d09f33 +0.0.2 |checksum:5da51b81c85cbe7bd5728756e4ed735cb024cbd06b277f4a108caa22fbd1a96f +0.0.3 |checksum:9affb2d9c084add97908800388fb5ef8c4f31733abb9c0b867936e1487e0cb82 +0.0.4 |checksum:7fa5815927035b2fae0a6843073009ae3420ed8ab999dcd1582039414e6e74eb +0.3.14 |checksum:cf04d428eab63c85d622689da9f889ada0512a8239916930c3088d6c54b2a007 +0.3.15 |checksum:9ebdb9d5ece5e2bf4bca461ae00cd26097a51b56dfe0efff17ce05d7ffeabd02 +0.3.16 |checksum:13ffd39dc065714fe054acf350ef4346a59c979a2c529d84a2a0704938287800 +0.3.17 |checksum:482b069c53ceacf2549704a6f9bcf181d3537a1a0e1f089f5a3c9d2545f0b21e +0.3.18 |checksum:fb11182d0a9019209484c1da17a96f18c795e4be0650e81eb50c369a830c9671 +0.3.19 |checksum:e8c439eb7ac84bef58c97f9bb61c7d18a2374cf66cb19baaf69122168d39e2ff +0.3.20 |checksum:176afa57e9cb62f77e7e1ff82463f4a0531b82cf8f6317ee1a6887e6b3b9df88 +0.3.21 |checksum:958e0f02f7371578afb1de32e4214605529c366279121419b174a823329edf5d +0.3.22 |checksum:2cc82336ee43e4b3d974305d49bfa7b9d01e95f7b4438c397027a10b73fa192d +0.3.23 |checksum:eddd2989374c115b8f1fe8c43ce8988fd9054f4e5647224cac4513e67c9a1808 +0.3.24 |checksum:a44418ed8b2422dd554d68a5d55d5f15b0777ae4f0a31745a638b812ade6d761 +0.3.25 |checksum:a87a3809aaf94d7dd941db63450fccac1910ed886e61833269d0bb02e8f4d072 +0.3.26 |checksum:37288f4ab4148855b1c3e25e1a53573d8785d44a615383f12907ceec02146d2d +0.3.27 |checksum:80c2feac5ecc7eaf2033e825519816d60edb1164c5f9bf7fd49aa4e660867e95 +0.3.28 |checksum:9e0be2c610006e2232b5e7590a72839a7662d758e080ffec5543d3b535e806f3 +0.3.29 |checksum:32e6ea4fbab70c29796ebc49b9de014b60203b10a92d6c45786f07123223a080 +0.3.30 |checksum:522d7bac90426926ae80639d512f2ed6f2152ee5b58719cf4eb0fcc9d762ff8f +0.3.31 |checksum:0b06e23121052135d228f750fdd24b10b5bc81e81add0ba5cf9ba11e58118ccf +0.3.32 |checksum:eb1c6d01783d17abf88229ca29676f930f6ba0cc05c6946b6defd6c4d26cc4e2 +0.3.33 |checksum:376cfdc347e0776348e20743e13edeaadeb908f737bce0aa328fb2aa445dee2d +0.3.34 |checksum:ae9b5377a1fb01939a7751b4378a3ad36eadf93af4d3f2af431bad2712e30392 +0.3.35 |checksum:b72ee96326a85fd2d8ccef97d94d10d15e46194aae2fca28ecef768665b3a2b0 +0.3.36 |checksum:1b72a19f2dd29c4937c9932c3c42db4722ffba37701dfc26838b969ca19567b6 +0.3.37 |checksum:6c8e551f2067b64c4edb00da70b1b85ac761e611cd73c7c937709ca797da225e +1.0.0 |checksum:d43f3ab61e465a958782b4490f9a0b0a73bef8352945ba5eb5c6f12a92bd1c70 +1.0.1 |checksum:438297f420d1c48d55fc2a8df08e0b7ba47311f60fe02ad8212256612c505a42 +1.1.0 thread_safe:~> 0.1|checksum:715a47c25f8e4c2f106c92d5a97e612f84eb7e85f5822bf3d6cf615b44492abc +0.3.38 |checksum:c8c8525a056b7e26228cc8fa1cdb969fe980a207346cd84ac519ccb7554e63e8 +0.3.39 |checksum:f0ad9f7936aa6f8fd2222fbd33adc7e3e3c21800d36d46fd04edde9692e255d2 +1.2.0 thread_safe:~> 0.1|checksum:d8c9aae397ecef24e04fb1acbe46c5dc45b1f42049407ade3f521f7e6f58d79d,ruby:>= 1.8.7 +1.2.1 thread_safe:~> 0.1|checksum:52787314a74eea6d20b0df2fb0034fdb83b04415ff493cc39b4d4ad0cb80b6a0,ruby:>= 1.8.7 +0.3.40 |checksum:4010840329184bc05374f108bb09bd99a0278aee9474c0f5c7e7d009ae502640 +1.2.2 thread_safe:~> 0.1|checksum:fdb1d3fdf2776d490c82a0e589a08e7cbde70ac1ae7d2b1f0b7e77f3e6b801b0,ruby:>= 1.8.7 +0.3.41 |checksum:381b22fd1744a35d0a0239f563f505773681e626e6d900063b14cb9b1b68e98c +0.3.42 |checksum:37452ed65ed2b1ff4bdb6d488313f833da85a00c426e23845ccf62ceaccac168 +0.3.43 |checksum:4df52124b359789ac13aa12f46b9665d562b189fc6e60c44b9aa6d997b100a70 +0.3.44 |checksum:a717f358872144fabf762da0f8a6ba23ce764550230ff0b831957247c8484ca8 +0.3.45 |checksum:936bc317761a47b7e0858bd7ce875c0e7f19b1eedf024b876a3dd6f799172ce7 +0.3.46 |checksum:c5db7ee29ad295e98efc45b77c03912ebb005c851a96cde86794acd07a101789 +0.3.47 |checksum:99c573c72a36070217cd88b90aa3333c450ac52207e44c2f231a56802c42e069 +0.3.48 |checksum:f57acf2e8c433ba5d853d4505a7ef7e5e705ddb5908db5c076e649e4e3f7a537 +0.3.49 |checksum:1fe60be515209f3cadcb096c1b701fe37980bbb0b7935fb2aa0a3dc4acff0703 +0.3.50 |checksum:3e74ebcd0ba9ac2f0c5f0f48fe2dfc205fedbc094a1b2221c599781c59c4fccb +0.3.51 |checksum:92541efbd7fc48da746e34357adada9fdba9374d85a57441f36a584735b85c5e +0.3.52 |checksum:8354497af5f03549fbca9880074b6fa3f33c842accec0d8e5d5f19c3bae43c17 +0.3.53 |checksum:7e16e6ed8c0c44c0d1e581f3b21bbaae9c8ae206c243dc1cba4368270d8fb83e +1.2.3 thread_safe:~> 0.1|checksum:9469862963cf5e8f12bb7d1cf89e681ebfee417537f6835b2e471c7c260d2817,ruby:>= 1.8.7 +1.2.4 thread_safe:~> 0.1|checksum:f7e79ceee9d0a9f64558f865b9ddaf471c31ff6d6c2dea04b1951400635eb725,ruby:>= 1.8.7 +1.2.5 thread_safe:~> 0.1|checksum:7f144179fa25bd3ac21f3b532e0925f148cc911a7456de699bf3f623864c5dba,ruby:>= 1.8.7 +0.3.54 |checksum:b51cd99e3ed8622ee2ed1f7d15d26d2455a53a4d151b824b528a3d6a43c12e55 +0.3.55 |checksum:41a7a6e77cdac2d1db45691a76d07a3be63861671c78071e8e322c3eecad2069 +2.0.0 concurrent-ruby:~> 1.0|checksum:6b2ebc114edce74eb6b56cb1c02017d49b67acb529f0c209c2e62b204271e94a,ruby:>= 1.9.3 +0.3.56 |checksum:d230fff7c38562d4f838cbcd925629f9b4207bf49cb3d00952271b7d17987e76 +1.2.6 thread_safe:~> 0.1|checksum:d711660db66a9fda6310ce3a71d6953f0e69cbc03883a2f6b07f7cb39b44c111,ruby:>= 1.8.7 +2.0.1 concurrent-ruby:~> 1.0|checksum:a889af0cbd4972376f8237515070747c68f71330bbaec2d1d50fba9f3f7f6bfb,ruby:>= 1.9.3 +1.2.7 thread_safe:~> 0.1|checksum:3945d8a57c62a59e691d527ae4daaf562d6e07a3c0d032876c6b066e108072c4,ruby:>= 1.8.7 +2.0.2 concurrent-ruby:~> 1.0|checksum:7459a7c82ba838260cb2d9fa701113bf0c18c20f6ab927c4ab9639c05ff5277d,ruby:>= 1.9.3 +0.3.57 |checksum:a1c625ae58f5c98517f444a535220bfa305a6c9bcca155d66309b274d76f29f2 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-uber b/bundler/spec/fixtures/rubygems_responses/info-uber similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-uber rename to bundler/spec/fixtures/rubygems_responses/info-uber diff --git a/bundler/spec/fixtures/rubygems_responses/info-unf b/bundler/spec/fixtures/rubygems_responses/info-unf new file mode 100644 index 00000000000..16ea3e5b0eb --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-unf @@ -0,0 +1,16 @@ +--- +0.0.3 unf_ext:>= 0|checksum:77a91261252d5c98b74ee5ff480183783bea71fed777e8627f3ce50631ad9b59 +0.0.4 unf_ext:>= 0|checksum:25e89f0d8eb106781e1d6e826e8cddbf34ea943e34d6dd8789f5f9fbce5f8dee +0.0.5 unf_ext:>= 0|checksum:27be496f67bbb460d581ce2ad113c6766a609b2781c170c232d8f074ef79e37c +0.0.5-jruby |checksum:4f6026a27f134cc87d5f99e034857a523b9d8bf3ab8c48b1f4bd1faa73e45040 +0.1.0 unf_ext:>= 0|checksum:847e49e3b2d5a7983d8264e98b146863004b13d21c65aaef67946955dcec1e90 +0.1.1 unf_ext:>= 0|checksum:ee54b0166568bb428b5128af446955b3109621f99aad35ab5b73011edc3cefe0 +0.1.1-jruby |checksum:5ab6176812a9732dcbddcfc7980d48ab9030e367b9923b3b3e5668b77fb63cec +0.1.2 unf_ext:>= 0|checksum:3a444368d8e0c8eb6f34981d9a246e3e7ac7fb65cfc5d43857d47b125a7bcabc +0.1.2-jruby |checksum:04c490745eb07f4b829101f877ae49a04016b3ffd5096f16aa013a8679243082 +0.1.3 unf_ext:>= 0|checksum:550bc894b05a85a769f0668ca162f83fddace095aa9b8c80c1e83ddb7b4558b8 +0.1.3-jruby |checksum:6e36161c215af5c98fd739c1612a62fe581abb2221e344e02f72ddf395559b21 +0.1.4 unf_ext:>= 0|checksum:4999517a531f2a955750f8831941891f6158498ec9b6cb1c81ce89388e63022e +0.1.4-java |checksum:49a5972ec0b3d091d3b0b2e00113f2f342b9b212f0db855eb30a629637f6d302 +0.2.0.beta1 |checksum:8ed051301b5bd4058fd861704df06a87ae17cba890184df2a56c85e45456d9c7,ruby:>= 1.9.3,rubygems:> 1.3.1 +0.2.0.beta2 |checksum:75e1839c5c8c40ff66bb30859cd05a7b4108b1676532e9e956c65bc754e88da8,ruby:>= 1.9.3,rubygems:> 1.3.1 diff --git a/bundler/spec/fixtures/rubygems_responses/info-virtus b/bundler/spec/fixtures/rubygems_responses/info-virtus new file mode 100644 index 00000000000..b5bceb6bad6 --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-virtus @@ -0,0 +1,37 @@ +--- +0.0.1 |checksum:b2b29827845f78f2eb78a4205cf709b0aeac2ecd8e90540a705e519884876468 +0.0.2 |checksum:e68caf6dbe05f72490067c57fe7ef343c74eecb357cd674c68d79ae5a3c28809 +0.0.3 |checksum:0f6d87115573bb1b4a9f26f7a6edf70ce998977ae9f0aa905195d6f2f5d3d941 +0.0.4 |checksum:cf4c7bea46f36ae4934fea88e6fbe67cd502664210ac78c9c28cc200f99ac0db +0.0.5 |checksum:2458f9df87f3794ddb621b5537edac47fca5d93a49de71fd22bef0d4a2341eb3 +0.0.6 |checksum:67883d12661ef87bfd637c0d4a8a2fc527228412808218891a3c8a80971459bf +0.0.7 |checksum:6d3b381a3f8b4b81d98b6fce9101dce35b7874ead7a1997a46cf6897dab74022 +0.0.8 |checksum:af9632bd134daf6ae8871af66474a5fb67d0a8356d90124ef4f3e026fd69fb27 +0.0.9 |checksum:896f46cbc92106249fec420af44b84a858714c0841de39a633a83033f5353de5 +0.0.10 |checksum:6025e8a57f826e9519e773a7daac0d7f6bb636eeec1e8c5a1756db06cfe5a349 +0.1.0 |checksum:990196ea6e5929f86f4e23f1ea9e3238c8b4b7eca2055d832a7b946447c83c04 +0.2.0 |checksum:323ecee2a34418658abf9b85c0984e18953fb9c5d1bb534a0258220dce57ad23 +0.3.0 |checksum:443d7031c10e0f008edbcdbb0ea49d567b92d06c6eff16b9680ade5f0fb343e9 +0.4.0 |checksum:395e46298005b709e263c3b98868e5be69b717559b20beaddcf41071c8287615 +0.4.1 backports:~> 2.5.1|checksum:3377af41176f1d440fd072fe770cefd4850768d2d0c697bdabafd985ac9f8ac6 +0.4.2 backports:~> 2.5.3|checksum:9a4e6e83c2db25f1ca1e28329a082c8832ec0f55251dc777b3416bdd3b292ee2 +0.5.0 backports:~> 2.6.1|checksum:4c7e238f972662e55a5abb829b3fc7e74295e41f8ba1ba41b7e5883fc6027a71 +0.5.1 backports:~> 2.6.1|checksum:228b9c101ae1f2f49f404b58332933a052b1fc1a7cb31aa1d1be890b86d7628e +0.5.2 backports:~> 2.6.1|checksum:2705581cf404bf40e2a6236f2c0385689756b8d751ab0eddddd4b7144d64c7c2 +0.5.3 backports:~> 2.6.1,descendants_tracker:~> 0.0.1|checksum:933f80bf4c0b73ef17c64129bd9684e25bc978c16a3822547095f3428675d494 +0.5.4 backports:~> 2.6.1,descendants_tracker:~> 0.0.1|checksum:a86e4fe65687fc40173275f2689746ea710d0b4621933950b93cd0553a295191 +0.5.5 backports:~> 3.3,descendants_tracker:~> 0.0.1|checksum:b7de2f3be82838065033e5d1b7e93dc5ed913f1acb78a920badb8e0eb696c54f +1.0.0.beta3 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:68502436d669008c37c5c48e4911a4dec8abe2af31b27d9ba641bdf024de9b5e,rubygems:> 1.3.1 +1.0.0.beta4 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:a5675b22131a5b1dc7e2175612cbde05a7c6b8bd5a12afa59c1d82b02d69f5a2,rubygems:> 1.3.1 +1.0.0.beta5 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:4673ddf40574c7ea2b2e5e021c7776fcb4f63bb48f549f588232aeb7adfdcb7d,rubygems:> 1.3.1 +1.0.0.beta6 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:348a508ad659278b9ce386957b04db996b397b60aad9501595948042d84b374a,rubygems:> 1.3.1 +1.0.0.beta7 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:ee7d067eedb94900312e8f63cfbb2950bb0ba4e2d4065f6e0fb8d5fbd6b847db,rubygems:> 1.3.1 +1.0.0.beta8 axiom-types:~> 0.0.3,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:f768584b82034b911f730781d1d7dbb38ec4764c471d29aa722efafdad8ebd8c,rubygems:> 1.3.1 +1.0.0.rc1 axiom-types:~> 0.0.4,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:4cc9ad8817f2e46d31b1263000429722805cd9c0a9793b0303c6017c599df024,rubygems:> 1.3.1 +1.0.0.rc2 axiom-types:~> 0.0.5,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:2e1821c975d2c605ca57107e7c24c5836232e9255e3897c57a4ec8898c52d92e,rubygems:> 1.3.1 +1.0.0 axiom-types:~> 0.0.5,coercible:~> 0.2,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:662a8cc0b28059b60dfb32a2e35a64f0dae3769c1371bf09e41795282faa84c8 +1.0.1 axiom-types:~> 0.0.5,coercible:~> 1.0,descendants_tracker:~> 0.0.1,equalizer:~> 0.0.7|checksum:03d81d65377a603894b058c0ee78130dda1c3e6d56918d40444f11dba5d644a6 +1.0.2 axiom-types:~> 0.1,coercible:~> 1.0,descendants_tracker:~> 0.0.3,equalizer:~> 0.0.9|checksum:024c5bfd65d7dfc4cf5879ae17492075031102bc1bf1f95f0cf774d330c4f3ef +1.0.3 axiom-types:~> 0.1,coercible:~> 1.0,descendants_tracker:>= 0.0.3&~> 0.0,equalizer:>= 0.0.9&~> 0.0|checksum:5e110caf5e226b74afe9ded416d0cd9e160989bacb6f7d51edef5a0a9da080c5 +1.0.4 axiom-types:~> 0.1,coercible:~> 1.0,descendants_tracker:>= 0.0.3&~> 0.0,equalizer:>= 0.0.9&~> 0.0|checksum:be6d6da340711b3912971883325a0314c0b6cfcfcdc6142961c42bff2ebdde18 +1.0.5 axiom-types:~> 0.1,coercible:~> 1.0,descendants_tracker:>= 0.0.3&~> 0.0,equalizer:>= 0.0.9&~> 0.0|checksum:d3053b9ff62d3f8b7b233f7e1aa9530b73ed7e541bee2c62f2c711362287371a diff --git a/bundler/spec/fixtures/rubygems_responses/info-weakling b/bundler/spec/fixtures/rubygems_responses/info-weakling new file mode 100644 index 00000000000..610df71a39f --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/info-weakling @@ -0,0 +1,5 @@ +--- +0.0.1 |checksum:92e35a78b8c85ae81b9e5a89754a61de5d10583f0a0be820606582edbcd14a1d +0.0.2 |checksum:b59ee95bf74e0cf0fe24de5ef4739bfd8101e8f295f2de5877359c830e2f84c8 +0.0.3 |checksum:4810d67d4c2ceef4ea1c21a1349925bc7dd4620f56048635f902a0d5d673a937 +0.0.4-java |checksum:f1f6c45b34fa1d465c16a06d731a9fc159acc190ac4a44c915b84c0a8a761aa9 diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/info-zeitwerk b/bundler/spec/fixtures/rubygems_responses/info-zeitwerk similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/info-zeitwerk rename to bundler/spec/fixtures/rubygems_responses/info-zeitwerk diff --git a/bundler/spec/fixtures/rubygems_responses/mime-types-data b/bundler/spec/fixtures/rubygems_responses/mime-types-data new file mode 100644 index 00000000000..67c555a80be --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/mime-types-data @@ -0,0 +1,10 @@ +--- +3.2015.1120 |checksum:2cc2d944557aacac49d15709247be3fba2028f65762bf474cea0212e80dfdf11,ruby:>= 2.0 +3.2016.0221 |checksum:f6ce9f679d796f4d2647a93ca3d2c3bca4399924a744cdc3f5063a6b8195cf17,ruby:>= 2.0 +3.2016.0521 |checksum:7542bccff06d70c4ad94d1cf10b7dac6bd89958356e5d0d7f6447168c819be12,ruby:>= 2.0 +3.2018.0812 |checksum:ac4553288225756970f0739798ff0f1116988d56e0ac15a525553ec115b89b1f,ruby:>= 2.0 +3.2019.0331 |checksum:8a70976e9e3268e01df23bd8fdb503d80b285548f4754671b0875496c2bb00d4,ruby:>= 2.0 +3.2019.0904 |checksum:ffd104bb350b0620db9a5a08b76cacee30d33cafb0d9be0597ce8a7869da5121,ruby:>= 2.0 +3.2019.1009 |checksum:b09bb0076f4d209d21de5f81569edffdb6e53d43f891e30edfa12433980ba6a3,ruby:>= 2.0 +3.2020.0425 |checksum:90726aa1a94f0ab1fd4109b36d8ed1c0e87a7c56fcd277d63fb7306e040636fe,ruby:>= 2.0 +3.2020.0512 |checksum:a31c1705fec7fc775749742c52964a0e012968b43939e141a74f43ffecd6e5fc,ruby:>= 2.0 diff --git a/bundler/spec/fixtures/rubygems_responses/statesman-1.2.1.gemspec.rz b/bundler/spec/fixtures/rubygems_responses/statesman-1.2.1.gemspec.rz new file mode 100644 index 00000000000..f3770ea25f6 Binary files /dev/null and b/bundler/spec/fixtures/rubygems_responses/statesman-1.2.1.gemspec.rz differ diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-bundler.json b/bundler/spec/fixtures/rubygems_responses/versions-bundler.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-bundler.json rename to bundler/spec/fixtures/rubygems_responses/versions-bundler.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-business.json b/bundler/spec/fixtures/rubygems_responses/versions-business.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-business.json rename to bundler/spec/fixtures/rubygems_responses/versions-business.json diff --git a/bundler/spec/fixtures/rubygems_responses/versions-guard-bundler.json b/bundler/spec/fixtures/rubygems_responses/versions-guard-bundler.json new file mode 100644 index 00000000000..b2d3014b7ae --- /dev/null +++ b/bundler/spec/fixtures/rubygems_responses/versions-guard-bundler.json @@ -0,0 +1 @@ +[{"authors":"Yann Lugrin","built_at":"2019-12-23T00:00:00.000Z","created_at":"2019-12-23T16:51:50.100Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":140267,"metadata":{},"number":"3.0.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 0","ruby_version":"\u003e= 2.4.9","prerelease":false,"licenses":["MIT"],"requirements":[],"sha":"c59d0bf0f65e6f800e4bbeb26b89a7b45cd4f17c170d67c50a8f3a097446ce9c"},{"authors":"Yann Lugrin","built_at":"2019-01-16T00:00:00.000Z","created_at":"2019-01-16T07:30:43.466Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":1357227,"metadata":{},"number":"2.2.1","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 0","ruby_version":"\u003e= 1.9.2","prerelease":false,"licenses":["MIT"],"requirements":[],"sha":"c2f8ad69d7c38775f0e60ff3a8a97df3e1b925a51553916fcd97f8c391435152"},{"authors":"Yann Lugrin","built_at":"2019-01-10T00:00:00.000Z","created_at":"2019-01-10T14:12:15.900Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":23197,"metadata":{},"number":"2.2.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 0","ruby_version":"\u003e= 1.9.2","prerelease":false,"licenses":["MIT"],"requirements":[],"sha":"db3494f840dd924a13a4f2f79ee67eef92b5555ab155cf33cbb278777a8b0d25"},{"authors":"Yann Lugrin","built_at":"2014-12-11T00:00:00.000Z","created_at":"2014-12-11T06:27:24.372Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":2531805,"metadata":{},"number":"2.1.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 0","ruby_version":"\u003e= 1.9.2","prerelease":false,"licenses":["MIT"],"requirements":[],"sha":"e0a1f96893866677ecf4238f524ca11602f70592afd0fb83d02df09867073898"},{"authors":"Yann Lugrin","built_at":"2013-10-30T00:00:00.000Z","created_at":"2013-10-30T11:00:19.545Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":462483,"metadata":{},"number":"2.0.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 0","ruby_version":"\u003e= 1.9.2","prerelease":false,"licenses":["MIT"],"requirements":[],"sha":"533a74e1002ea461b8a44c1a66f7783b4d9967bacc2d34342975246180bdebd7"},{"authors":"Yann Lugrin","built_at":"2012-06-15T00:00:00.000Z","created_at":"2012-06-15T09:22:13.404Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":762985,"metadata":{},"number":"1.0.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 1.3.6","ruby_version":null,"prerelease":false,"licenses":null,"requirements":null,"sha":"1ace3f43d27368b72f403226828dd6f4b1069cb25794800ea6d8afe4ad317869"},{"authors":"Yann Lugrin","built_at":"2011-05-13T22:00:00.000Z","created_at":"2011-05-14T14:01:16.218Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":169523,"metadata":{},"number":"0.1.3","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 1.3.6","ruby_version":null,"prerelease":false,"licenses":null,"requirements":null,"sha":"34e1fddfdcb3315eb99ce7bed8fb1b9cb3e722c8de196a91c4ad6948ed4aca13"},{"authors":"Yann Lugrin","built_at":"2011-02-17T23:00:00.000Z","created_at":"2011-02-18T12:44:59.013Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":10477,"metadata":{},"number":"0.1.2","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 1.3.6","ruby_version":null,"prerelease":false,"licenses":null,"requirements":null,"sha":"bb53cf08f60f587fcf9eb0a119046556e48e259ca5cf557ab98f4e1e701973f8"},{"authors":"Yann Lugrin","built_at":"2010-10-26T22:00:00.000Z","created_at":"2010-10-27T10:18:03.430Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":3608,"metadata":{},"number":"0.1.1","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 1.3.6","ruby_version":null,"prerelease":false,"licenses":null,"requirements":null,"sha":"4823bccaa8c62eaaed60a1d654a554893a9ca616d48fe447c0489c03136b8b69"},{"authors":"Yann Lugrin","built_at":"2010-10-23T22:00:00.000Z","created_at":"2010-10-24T12:11:15.715Z","description":"Guard::Bundler automatically install/update your gem bundle when needed","downloads_count":2880,"metadata":{},"number":"0.1.0","summary":"Guard gem for Bundler","platform":"ruby","rubygems_version":"\u003e= 1.3.6","ruby_version":null,"prerelease":false,"licenses":null,"requirements":null,"sha":"1f3d254b9ad6f6a71a60a9d22e43b6316aa5421c31300ec72cdd84f5f58c6519"}] diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-i18n.json b/bundler/spec/fixtures/rubygems_responses/versions-i18n.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-i18n.json rename to bundler/spec/fixtures/rubygems_responses/versions-i18n.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-ibandit.json b/bundler/spec/fixtures/rubygems_responses/versions-ibandit.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-ibandit.json rename to bundler/spec/fixtures/rubygems_responses/versions-ibandit.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-onfido.json b/bundler/spec/fixtures/rubygems_responses/versions-onfido.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-onfido.json rename to bundler/spec/fixtures/rubygems_responses/versions-onfido.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-prius.json b/bundler/spec/fixtures/rubygems_responses/versions-prius.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-prius.json rename to bundler/spec/fixtures/rubygems_responses/versions-prius.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-public_suffix.json b/bundler/spec/fixtures/rubygems_responses/versions-public_suffix.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-public_suffix.json rename to bundler/spec/fixtures/rubygems_responses/versions-public_suffix.json diff --git a/bundler/spec/fixtures/ruby/rubygems_responses/versions-statesman.json b/bundler/spec/fixtures/rubygems_responses/versions-statesman.json similarity index 100% rename from bundler/spec/fixtures/ruby/rubygems_responses/versions-statesman.json rename to bundler/spec/fixtures/rubygems_responses/versions-statesman.json diff --git a/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/is_empty_when_all_dependencies_are_accessible.yml b/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/is_empty_when_all_dependencies_are_accessible.yml new file mode 100644 index 00000000000..f8abab44eab --- /dev/null +++ b/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/is_empty_when_all_dependencies_are_accessible.yml @@ -0,0 +1,230 @@ +--- +http_interactions: +- request: + method: get + uri: https://github.com/dependabot-fixtures/business.git/info/refs?service=git-upload-pack + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - dependabot-core/0.153.0 excon/0.82.0 ruby/2.7.1 (x86_64-linux-gnu) (+https://github.com/dependabot/dependabot-core) + response: + status: + code: 200 + message: OK + headers: + Server: + - GitHub Babel 2.0 + Content-Type: + - application/x-git-upload-pack-advertisement + Content-Security-Policy: + - default-src 'none'; sandbox + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Cache-Control: + - no-cache, max-age=0, must-revalidate + Vary: + - Accept-Encoding + X-Github-Request-Id: + - CA05:74D3:13C470:1B15B2:60C8F0D6 + X-Frame-Options: + - DENY + body: + encoding: ASCII-8BIT + string: "001e# service=git-upload-pack\n00000156799cd60c8cd51c9f379b423d506fc02c3a68e895 + HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since + deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want + allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter + object-format=sha1 agent=git/github-g69d6dd5d35d8\n005066c6e104155ec10701d5e6a6f6f1563c05d59994 + refs/heads/joesouthan/denmark-2021\n003f799cd60c8cd51c9f379b423d506fc02c3a68e895 + refs/heads/master\n0040ace90dc4d34136a5d9570e54288c505711fb93ce refs/heads/rubocop\n00412e8e26df5786a5d2a732fd37a9ae085682c1089a + refs/heads/try-rust\n003ec5bf1bd47935504072ac0eba1006cf4d67af6a7a refs/tags/v1.0.0\n0041df9f605d7111b6814fe493cf8f41de3f9f0978b2 + refs/tags/v1.0.0^{}\n003ea58ed2ef16972597b6ddf99357d1a56cf98cedb2 refs/tags/v1.1.0\n0041f6203eaf657c4e1b69315d43083804d818aafe23 + refs/tags/v1.1.0^{}\n003fd31e445215b5af70c1604715d97dd953e868380e refs/tags/v1.10.0\n003fe39e059fe0d1632b95e5800cb8a594d49599654d + refs/tags/v1.11.0\n003fc170ea081c121c00ed6fe8764e3557e731454b9d refs/tags/v1.11.1\n003f37f41032a0f191507903ebbae8a5c0cb945d7585 + refs/tags/v1.13.0\n00427bb4e41ce5164074a0920d5b5770d196b4d90104 refs/tags/v1.13.0^{}\n003f3b5a0ff1ef12081d30fb4e782e3d558262469ea8 + refs/tags/v1.14.0\n003f71083639645603d3bc25f7f5b11c96f0d07bf252 refs/tags/v1.15.0\n003f155d9aad3daa870612c06be6316817faeb4c98a8 + refs/tags/v1.17.1\n003fb12c186ca6fd4ffdac85175742ff7e4d0a705ef4 refs/tags/v1.18.0\n003ee540fac7b4a958612e051842aa1ace69ba95a6eb + refs/tags/v1.2.0\n0041b9c932dd543261c7fe6afc54f8c51a99bbc2bdd8 refs/tags/v1.2.0^{}\n003e58266f176afd655faedde8726e5bce17edd09a4a + refs/tags/v1.3.0\n0041469dacb70fafd72ed9571748036642df0d0857fa refs/tags/v1.3.0^{}\n003eda8b496c60593b72680454334588a753fcf2c0b6 + refs/tags/v1.4.0\n004126f4887ec647493f044836363537e329d9d213aa refs/tags/v1.4.0^{}\n003e55d39bf3042fac0b770bca2bfb200cfdffcd0175 + refs/tags/v1.5.0\n003e444606ddc1a6543ff37199c072c829564a9a8a65 refs/tags/v1.6.0\n003eefb29a3cab92c962629d4728400147b60d88b6eb + refs/tags/v1.7.0\n003e20984b51291e25782bb55ef72008bed592c4c2d7 refs/tags/v1.8.0\n003ec878eaa4dfcc38a2b95100f79dedc63f34755473 + refs/tags/v1.9.0\n003eb7bcef49295db54092762ea4f637663c5877e2e5 refs/tags/v2.0.0\n003e624341fe34a8f103a736312831a79cd821ac79c8 + refs/tags/v2.1.0\n003efc9d4b87e5c06741efa356ee9859653068c7553c refs/tags/v2.2.0\n003e2db744653e5cce3f77ef59bbbb7ceed5e206b211 + refs/tags/v2.2.1\n0000" + recorded_at: Tue, 15 Jun 2021 18:26:30 GMT +- request: + method: get + uri: https://github.com/dependabot-fixtures/prius.git/info/refs?service=git-upload-pack + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - dependabot-core/0.153.0 excon/0.82.0 ruby/2.7.1 (x86_64-linux-gnu) (+https://github.com/dependabot/dependabot-core) + response: + status: + code: 200 + message: OK + headers: + Server: + - GitHub Babel 2.0 + Content-Type: + - application/x-git-upload-pack-advertisement + Content-Security-Policy: + - default-src 'none'; sandbox + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Cache-Control: + - no-cache, max-age=0, must-revalidate + Vary: + - Accept-Encoding + X-Github-Request-Id: + - CA06:6283:4A767:89FE8:60C8F0D6 + X-Frame-Options: + - DENY + body: + encoding: ASCII-8BIT + string: "001e# service=git-upload-pack\n00000156786656cc97ca6d8b613e4f41495715296290d07f + HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since + deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want + allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter + object-format=sha1 agent=git/github-g69d6dd5d35d8\n003f786656cc97ca6d8b613e4f41495715296290d07f + refs/heads/master\n003e76e239c47af14300bd917016c1f5fdabb43b9274 refs/tags/v0.2.0\n0041b2d076022d73a9bb95471b6c42213e80fa738bb2 + refs/tags/v0.2.0^{}\n003e99093f4e72c049fcb750ae2ef2421688fda0afac refs/tags/v1.0.0\n0041cff701b3bfb182afc99a85657d7c9f3d6c1ccce2 + refs/tags/v1.0.0^{}\n003ed111425fa31a95dac3174e2dc9003553b9293bd9 refs/tags/v2.0.0\n0000" + recorded_at: Tue, 15 Jun 2021 18:26:30 GMT +- request: + method: get + uri: https://github.com/dependabot-fixtures/que.git/info/refs?service=git-upload-pack + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - dependabot-core/0.153.0 excon/0.82.0 ruby/2.7.1 (x86_64-linux-gnu) (+https://github.com/dependabot/dependabot-core) + response: + status: + code: 200 + message: OK + headers: + Server: + - GitHub Babel 2.0 + Content-Type: + - application/x-git-upload-pack-advertisement + Content-Security-Policy: + - default-src 'none'; sandbox + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Cache-Control: + - no-cache, max-age=0, must-revalidate + Vary: + - Accept-Encoding + X-Github-Request-Id: + - CA07:768D:24CDA:5D4F4:60C8F0D6 + X-Frame-Options: + - DENY + body: + encoding: ASCII-8BIT + string: "001e# service=git-upload-pack\n0000015661e1805deb8161e5c1502e518a9a44fa464d308c + HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since + deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want + allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter + object-format=sha1 agent=git/github-g69d6dd5d35d8\n003cf0b75334a2f9450ff51d91c8bebfe33098c3209e + refs/heads/0.x\n003cfb94321b40f763fb48db1a63f0c1084bee961388 refs/heads/1.0\n00419f59433d38d2dedf6d5d7d11c6c9c57537f7bfa6 + refs/heads/1.0-docs\n00507ccb256ef604ce273445aa5043e47f3846d9101b refs/heads/configurable-log-levels\n0054d7a5aaf26b1f7df1e52772818a3b037cb776cc73 + refs/heads/dedicated-locker-connection\n003f61e1805deb8161e5c1502e518a9a44fa464d308c + refs/heads/master\n003e6f8eb86cd480bda87d10b37750a6fa476bf72e02 refs/heads/ruby3\n004163073c67650222f68c45fbda1ed15b74dfd2096b + refs/heads/spec-fix\n004d0293fd2eb954c03ea71ebe91093be8a0778b6a43 refs/tags/aborted-jruby-attempt\n004a6563fd63d0b9ae32ee6d5dcdad10bf46d124afe1 + refs/tags/aborted-rapid-stop\n003e2c198ef576ced1e891552f4bb7f31d77051694cb + refs/tags/v0.0.1\n0041234418aa9f6df09f88b7714c7a0508e049ec1d54 refs/tags/v0.0.1^{}\n003e21287e8ec53dc2db5840e5c30e2cceb3998ec9c7 + refs/tags/v0.1.0\n00418214fdde4d34e2ecc7ea962486eefc6686a7ddca refs/tags/v0.1.0^{}\n003fedda2f2b6849a23093b83dab143efca9487609e2 + refs/tags/v0.10.0\n0042ed5732f17ae23a7e0e24c1f3e3e3ea4fb726796b refs/tags/v0.10.0^{}\n003ff84210a83e528c521700b505466cb06ab23b1b8f + refs/tags/v0.11.0\n004259ac77c970cd59ed1a4bfa21f7c84729ca98de6d refs/tags/v0.11.0^{}\n003f2ab78d7bc8076076e3e39fe32a870dcb418ddba1 + refs/tags/v0.11.1\n0042181a15c9af7c841295515d98c3d2c0543df51f66 refs/tags/v0.11.1^{}\n003f52efff3c6ff9aaac3008f7f654206167c6542e3e + refs/tags/v0.11.2\n004286d3e9008cff8c728069f9690dc5da5098a068fc refs/tags/v0.11.2^{}\n003f5cd0b77ef8cdd94aaca31f3859c756dabd6d49f3 + refs/tags/v0.11.3\n0042e253e36627cb59c75edbbed2d1c1565a81bcbe02 refs/tags/v0.11.3^{}\n003f0a09d96409329cefef56b101ccd79ab124bdaed5 + refs/tags/v0.11.4\n0042d211c65a6e5eee00bb93e6af0779f5fb5b1134cc refs/tags/v0.11.4^{}\n003fe14280c42c80fccc20ae6c43a194dc4eb259f1d9 + refs/tags/v0.11.5\n00426364df2576e1e93ff11f22df4ad33a9fb66cdb78 refs/tags/v0.11.5^{}\n003ffea2725a0988c5367a1b8a833961564d87b03b85 + refs/tags/v0.11.6\n0042997d1a6ee76a1f254fd72ce16acbc8d347fcaee3 refs/tags/v0.11.6^{}\n003fa688c8a97eb7865a06c8b0e58d486e5dc547edf5 + refs/tags/v0.12.0\n004207f74f25cc1432acc84a857d2b356ec5c9a37d48 refs/tags/v0.12.0^{}\n003f0950b37a5d1010242236c90fafc119194564ae7f + refs/tags/v0.12.1\n00427a329c550906b3198fde165ec4a66d8635892fa1 refs/tags/v0.12.1^{}\n003f69ef0e3f771bb0e442bacc74e59903fc1853dda1 + refs/tags/v0.12.2\n00426af388f5caa1ecaf6e04122ebbc952fcd2bfc3c3 refs/tags/v0.12.2^{}\n003fdc1f1442f2a981e5b64e222f5767a86c9e1930b0 + refs/tags/v0.12.3\n0042468bc5d126b11de3e2db08f893a8a944f6fcfb58 refs/tags/v0.12.3^{}\n003f2036fa3908a80fa7daea7e64434f2b52f07fb852 + refs/tags/v0.13.0\n0042b05b505ca488885b1c7c72a3a2f7c593bee66f0d refs/tags/v0.13.0^{}\n003f81a334cf15a07a41506aafcc8aedca50faaaeb56 + refs/tags/v0.13.1\n0042b128db21ad60a3fbebd30abcce2d8bbbab519a20 refs/tags/v0.13.1^{}\n003ffbe5ef33cc2dc3e0963cbe57f7e6925363c3a542 + refs/tags/v0.14.0\n0042496aa68453a6a08c27a8725ae4e3c34e0b74c3b8 refs/tags/v0.14.0^{}\n003fc0461b88e67e7ce77a18838a113e2af92ddd4dc9 + refs/tags/v0.14.1\n004284775a90a1b2116631baf7394670eddb7d3cd7a3 refs/tags/v0.14.1^{}\n003fac5e4331a55318b1d6dbe5bea81deefe55a5df94 + refs/tags/v0.14.2\n004214b4769dc9f5b1d77e3f53b5c3e8a353965f14cf refs/tags/v0.14.2^{}\n003f5bf80f3f86304963cf39f848dee8c33af0825901 + refs/tags/v0.14.3\n004245e68691f2599c13b401e2d70cde6f6fbfcac708 refs/tags/v0.14.3^{}\n003e3f7c0212126ccdd963b1ea78df8a2716be4e220f + refs/tags/v0.2.0\n0041e25d7b7fc996532aa265c73e0f279bf6c3c593e2 refs/tags/v0.2.0^{}\n003ec216bcfb7a57bc2ad8b7fb28a0adb21b77d7df1b + refs/tags/v0.3.0\n0041c2c7c0a94c6e3e7873aca29452494bb0cc79c639 refs/tags/v0.3.0^{}\n003eef029158d833eb6bf4754ef6607c60bbc4b2ac07 + refs/tags/v0.4.0\n0041c6f178b9a1269bea6001e8cd07dc074d40ee776d refs/tags/v0.4.0^{}\n003eb931db37ed5e0ece53c374f02a29421fc6cf5689 + refs/tags/v0.5.0\n004134b1082638b1c0500f8ff8f063bcd1806b5ec5a1 refs/tags/v0.5.0^{}\n003e4f2bf169992ac55a26180953f22e3dc485379542 + refs/tags/v0.6.0\n00413d44e0198fac91a4e853bf726f0de0f687a78af3 refs/tags/v0.6.0^{}\n003e2fec544b8b4d950d8cbc002bf43d77058b6251f2 + refs/tags/v0.7.0\n0041b6946e9cc4226ca97ba2802a262322931db15d31 refs/tags/v0.7.0^{}\n003e41d31b2a8dc279ae013b745a34baf4db8468e6e3 + refs/tags/v0.7.1\n00415cd30686d996bc45669eda8b7838b492bbcb5e7f refs/tags/v0.7.1^{}\n003e97afe83636ffae054d53ad5618986b8b53346d46 + refs/tags/v0.7.2\n0041628040e43702a056f84fc5c5deb43e845aab5542 refs/tags/v0.7.2^{}\n003ea8e16ad972fe73f4c02650a3b86cdb6f1441bc15 + refs/tags/v0.7.3\n0041c71c0123cf5b1685a1e4aab83f74d68ae21da1ca refs/tags/v0.7.3^{}\n003ed37d6c482c4da36a891d7579a69b7ea14d151d04 + refs/tags/v0.8.0\n0041a7df15952b2c7602b20cbcbc764d09560789360c refs/tags/v0.8.0^{}\n003e5f17bfd105981595af21b752286e54811ecb8a09 + refs/tags/v0.8.1\n0041f677acf34683a281c0915757e2f9566a07c903ad refs/tags/v0.8.1^{}\n003ef1a240956628dba55e866c27bb2d4e8233855083 + refs/tags/v0.8.2\n0041dcb71276d967f670ff5d0f46edad2a48e418beea refs/tags/v0.8.2^{}\n003e87741f3537fdc3f08f00b134ee7c0fe9590438d1 + refs/tags/v0.9.0\n0041a5dee3727007f2e1ddeb49bafeb87f466c29211f refs/tags/v0.9.0^{}\n003e7c73900a675dbce41bd35b8b201584ac25d1e6fa + refs/tags/v0.9.1\n0041948f26e4c649923bfc9e73d5c624cb7e3ce19672 refs/tags/v0.9.1^{}\n003e4602c41e73bcb5d07a79ed22b5f430a576cba29a + refs/tags/v0.9.2\n0041cd68575fafd2f781fa02313607900c8f1a386646 refs/tags/v0.9.2^{}\n0043456dc8663ed805bbedc9251d995f70019021382e + refs/tags/v1.0.0.beta\n0046267d985082eb11b27f721ef1d1bb0d1b0d4d21fe refs/tags/v1.0.0.beta^{}\n0044252436b31f631d6f45b3688bca34f66d5e54cf32 + refs/tags/v1.0.0.beta2\n0047b7c360d418d127f0bd30f28f5ec7ca83341783e4 refs/tags/v1.0.0.beta2^{}\n00441e187ec6eec6853d94d8f44e28887484be5bee8a + refs/tags/v1.0.0.beta3\n0047a2c9a2d7a11debee4ce5bd6121a4a5e0f6fd3323 refs/tags/v1.0.0.beta3^{}\n00447004dfcffebe5917896e7f59960ca39b9b6c4869 + refs/tags/v1.0.0.beta4\n0047fd819a010ec797b189983b012ffcab0b9ed25c99 refs/tags/v1.0.0.beta4^{}\n0000" + recorded_at: Tue, 15 Jun 2021 18:26:30 GMT +- request: + method: get + uri: http://github.com/dependabot-fixtures/uk_phone_numbers.git/info/refs?service=git-upload-pack + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - dependabot-core/0.153.0 excon/0.82.0 ruby/2.7.1 (x86_64-linux-gnu) (+https://github.com/dependabot/dependabot-core) + response: + status: + code: 200 + message: OK + headers: + Server: + - GitHub Babel 2.0 + Content-Type: + - application/x-git-upload-pack-advertisement + Content-Security-Policy: + - default-src 'none'; sandbox + Expires: + - Fri, 01 Jan 1980 00:00:00 GMT + Pragma: + - no-cache + Cache-Control: + - no-cache, max-age=0, must-revalidate + Vary: + - Accept-Encoding + X-Github-Request-Id: + - CA08:6405:11682F:1A6B82:60C8F0D6 + X-Frame-Options: + - DENY + body: + encoding: ASCII-8BIT + string: "001e# service=git-upload-pack\n000001561530024bd6a68d36ac18e04836ce110e0d433c36 + HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since + deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want + allow-reachable-sha1-in-want no-done symref=HEAD:refs/heads/master filter + object-format=sha1 agent=git/github-g69d6dd5d35d8\n003f1530024bd6a68d36ac18e04836ce110e0d433c36 + refs/heads/master\n003eee6e0ac1ddc00ea18066c724c4a3808a96c3c211 refs/tags/v0.1.1\n00411530024bd6a68d36ac18e04836ce110e0d433c36 + refs/tags/v0.1.1^{}\n0000" + recorded_at: Tue, 15 Jun 2021 18:26:30 GMT +recorded_with: VCR 6.0.0 diff --git a/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/with_inaccessible_dependency/includes_inaccessible_dependency.yml b/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/with_inaccessible_dependency/includes_inaccessible_dependency.yml new file mode 100644 index 00000000000..43caf1c4dbf --- /dev/null +++ b/bundler/spec/fixtures/vcr_cassettes/Dependabot_Bundler_UpdateChecker_LatestVersionFinder_DependencySource/_inaccessible_git_dependencies/with_inaccessible_dependency/includes_inaccessible_dependency.yml @@ -0,0 +1,35 @@ +--- +http_interactions: +- request: + method: get + uri: https://github.com/no-exist-sorry/prius.git/info/refs?service=git-upload-pack + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - dependabot-core/0.153.0 excon/0.82.0 ruby/2.7.1 (x86_64-linux-gnu) (+https://github.com/dependabot/dependabot-core) + response: + status: + code: 401 + message: Authorization Required + headers: + Server: + - GitHub Babel 2.0 + Content-Type: + - text/plain + Content-Security-Policy: + - default-src 'none'; sandbox + Content-Length: + - '21' + Www-Authenticate: + - Basic realm="GitHub" + X-Github-Request-Id: + - CA09:3FFE:48411:8826C:60C8F0D7 + X-Frame-Options: + - DENY + body: + encoding: ASCII-8BIT + string: Repository not found. + recorded_at: Tue, 15 Jun 2021 18:26:32 GMT +recorded_with: VCR 6.0.0 diff --git a/bundler/spec/shared_contexts.rb b/bundler/spec/shared_contexts.rb index 4751bef40cd..de70b308cd5 100644 --- a/bundler/spec/shared_contexts.rb +++ b/bundler/spec/shared_contexts.rb @@ -5,28 +5,34 @@ require "bundler/compact_index_client" require "bundler/compact_index_client/updater" -RSpec.shared_context "stub rubygems compact index" do +RSpec.shared_context "without caching rubygems" do before do # Stub Bundler to stop it using a cached versions of Rubygems allow_any_instance_of(Bundler::CompactIndexClient::Updater). to receive(:etag_for).and_return("") + end +end +RSpec.shared_context "stub rubygems compact index" do + include_context "without caching rubygems" + + before do # Stub the Rubygems index stub_request(:get, "https://index.rubygems.org/versions"). to_return( status: 200, - body: fixture("ruby", "rubygems_responses", "index") + body: fixture("rubygems_responses", "index") ) # Stub the Rubygems response for each dependency we have a fixture for fixtures = - Dir[File.join("spec", "fixtures", "ruby", "rubygems_responses", "info-*")] + Dir[File.join("spec", "fixtures", "rubygems_responses", "info-*")] fixtures.each do |path| dep_name = path.split("/").last.gsub("info-", "") stub_request(:get, "https://index.rubygems.org/info/#{dep_name}"). to_return( status: 200, - body: fixture("ruby", "rubygems_responses", "info-#{dep_name}") + body: fixture("rubygems_responses", "info-#{dep_name}") ) end end @@ -37,7 +43,7 @@ # Stub the Rubygems response for each dependency we have a fixture for fixtures = Dir[ - File.join("spec", "fixtures", "ruby", "rubygems_responses", + File.join("spec", "fixtures", "rubygems_responses", "versions-*") ] fixtures.each do |path| @@ -45,7 +51,7 @@ stub_request(:get, "https://rubygems.org/api/v1/versions/#{dep_name}"). to_return( status: 200, - body: fixture("ruby", "rubygems_responses", "versions-#{dep_name}") + body: fixture("rubygems_responses", "versions-#{dep_name}") ) end end diff --git a/bundler/spec/spec_helper.rb b/bundler/spec/spec_helper.rb index 6dcb854b37c..bee84875b04 100644 --- a/bundler/spec/spec_helper.rb +++ b/bundler/spec/spec_helper.rb @@ -9,3 +9,45 @@ def require_common_spec(path) end require "#{common_dir}/spec/spec_helper.rb" + +module PackageManagerHelper + def self.use_bundler_1? + ENV["SUITE_NAME"] == "bundler1" + end + + def self.use_bundler_2? + !use_bundler_1? + end + + def self.bundler_version + use_bundler_2? ? "2" : "1" + end +end + +def bundler_project_dependency_files(project, directory: "/") + project_dependency_files(File.join("bundler#{PackageManagerHelper.bundler_version}", project), directory: directory) +end + +def bundler_project_dependency_file(project, filename:) + dependency_file = bundler_project_dependency_files(project).find { |file| file.name == filename } + + raise "Dependency File '#{filename} does not exist for project '#{project}'" unless dependency_file + + dependency_file +end + +def bundler_build_tmp_repo(project) + build_tmp_repo(project, path: "projects/bundler1") +end + +RSpec.configure do |config| + config.around do |example| + if PackageManagerHelper.use_bundler_2? && example.metadata[:bundler_v1_only] + example.skip + elsif PackageManagerHelper.use_bundler_1? && example.metadata[:bundler_v2_only] + example.skip + else + example.run + end + end +end diff --git a/cargo/.rubocop.yml b/cargo/.rubocop.yml new file mode 100644 index 00000000000..fc2019d46a3 --- /dev/null +++ b/cargo/.rubocop.yml @@ -0,0 +1 @@ +inherit_from: ../.rubocop.yml diff --git a/cargo/dependabot-cargo.gemspec b/cargo/dependabot-cargo.gemspec index c250d77f8e4..83879b063f1 100644 --- a/cargo/dependabot-cargo.gemspec +++ b/cargo/dependabot-cargo.gemspec @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "find" - Gem::Specification.new do |spec| common_gemspec = Bundler.load_gemspec_uncached("../common/dependabot-common.gemspec") @@ -25,6 +23,6 @@ Gem::Specification.new do |spec| spec.add_dependency "dependabot-common", Dependabot::VERSION common_gemspec.development_dependencies.each do |dep| - spec.add_development_dependency dep.name, dep.requirement.to_s + spec.add_development_dependency dep.name, *dep.requirement.as_list end end diff --git a/cargo/lib/dependabot/cargo/file_fetcher.rb b/cargo/lib/dependabot/cargo/file_fetcher.rb index 3b6c0366faf..9ad3681fac3 100644 --- a/cargo/lib/dependabot/cargo/file_fetcher.rb +++ b/cargo/lib/dependabot/cargo/file_fetcher.rb @@ -84,7 +84,7 @@ def fetch_workspace_files(file:, previously_fetched_files:) next if previously_fetched_files.map(&:name).include?(path) next if file.name == path - fetched_file = fetch_file_from_host(path) + fetched_file = fetch_file_from_host(path, fetch_submodules: true) previously_fetched_files << fetched_file grandchild_requirement_files = fetch_workspace_files( @@ -144,7 +144,7 @@ def path_dependency_paths_from_file(file) next unless details.is_a?(Hash) next unless details["path"] - paths << File.join(details["path"], "Cargo.toml") + paths << File.join(details["path"], "Cargo.toml").delete_prefix("/") end end @@ -155,7 +155,7 @@ def path_dependency_paths_from_file(file) next unless details.is_a?(Hash) next unless details["path"] - paths << File.join(details["path"], "Cargo.toml") + paths << File.join(details["path"], "Cargo.toml").delete_prefix("/") end end end @@ -218,6 +218,7 @@ def workspace_dependency_paths_from_file(file) # an alternative source (i.e., a git source) is also specified # rubocop:disable Metrics/CyclomaticComplexity # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize def required_path?(file, path) # Paths specified in dependency declaration Cargo::FileParser::DEPENDENCY_TYPES.each do |type| @@ -254,9 +255,9 @@ def required_path?(file, path) false end - - # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/CyclomaticComplexity def expand_workspaces(path) path = Pathname.new(path).cleanpath.to_path diff --git a/cargo/lib/dependabot/cargo/file_parser.rb b/cargo/lib/dependabot/cargo/file_parser.rb index 6e49c119c01..e29ffb73f4f 100644 --- a/cargo/lib/dependabot/cargo/file_parser.rb +++ b/cargo/lib/dependabot/cargo/file_parser.rb @@ -46,16 +46,19 @@ def check_rust_workspace_root workspace_root = parsed_file(cargo_toml).dig("package", "workspace") return unless workspace_root - msg = "This project is part of a Rust workspace but is not the "\ - "workspace root."\ + msg = "This project is part of a Rust workspace but is not the " \ + "workspace root." \ if cargo_toml.directory != "/" - msg += "Please update your settings so Dependabot points at the "\ + msg += "Please update your settings so Dependabot points at the " \ "workspace root instead of #{cargo_toml.directory}." end raise Dependabot::DependencyFileNotEvaluatable, msg end + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity def manifest_dependencies dependency_set = DependencySet.new @@ -78,10 +81,22 @@ def manifest_dependencies end end end + + workspace = parsed_file(file).fetch("workspace", {}) + workspace.fetch("dependencies", {}).each do |name, requirement| + next unless name == name_from_declaration(name, requirement) + next if lockfile && !version_from_lockfile(name, requirement) + + dependency_set << + build_dependency(name, requirement, "workspace.dependencies", file) + end end dependency_set end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity def build_dependency(name, requirement, type, file) Dependency.new( @@ -128,30 +143,22 @@ def requirement_from_declaration(declaration) if declaration.is_a?(String) return declaration == "" ? nil : declaration end - unless declaration.is_a?(Hash) - raise "Unexpected dependency declaration: #{declaration}" - end - if declaration["version"]&.is_a?(String) && declaration["version"] != "" - return declaration["version"] - end + raise "Unexpected dependency declaration: #{declaration}" unless declaration.is_a?(Hash) + return declaration["version"] if declaration["version"].is_a?(String) && declaration["version"] != "" nil end def name_from_declaration(name, declaration) return name if declaration.is_a?(String) - unless declaration.is_a?(Hash) - raise "Unexpected dependency declaration: #{declaration}" - end + raise "Unexpected dependency declaration: #{declaration}" unless declaration.is_a?(Hash) declaration.fetch("package", name) end def source_from_declaration(declaration) return if declaration.is_a?(String) - unless declaration.is_a?(Hash) - raise "Unexpected dependency declaration: #{declaration}" - end + raise "Unexpected dependency declaration: #{declaration}" unless declaration.is_a?(Hash) return git_source_details(declaration) if declaration["git"] return { type: "path" } if declaration["path"] @@ -201,9 +208,7 @@ def git_source_details(declaration) end def version_from_lockfile_details(package_details) - unless package_details["source"]&.start_with?("git+") - return package_details["version"] - end + return package_details["version"] unless package_details["source"]&.start_with?("git+") package_details["source"].split("#").last end diff --git a/cargo/lib/dependabot/cargo/file_updater/lockfile_updater.rb b/cargo/lib/dependabot/cargo/file_updater/lockfile_updater.rb index 01c93a59be2..581d61c45e9 100644 --- a/cargo/lib/dependabot/cargo/file_updater/lockfile_updater.rb +++ b/cargo/lib/dependabot/cargo/file_updater/lockfile_updater.rb @@ -14,9 +14,9 @@ class LockfileUpdater LOCKFILE_ENTRY_REGEX = / \[\[package\]\]\n (?:(?!^\[(\[package|metadata)).)+ - /mx.freeze + /mx - LOCKFILE_CHECKSUM_REGEX = /^"checksum .*$/.freeze + LOCKFILE_CHECKSUM_REGEX = /^"checksum .*$/ def initialize(dependencies:, dependency_files:, credentials:) @dependencies = dependencies @@ -32,15 +32,13 @@ def updated_lockfile_content SharedHelpers.with_git_configured(credentials: credentials) do # Shell out to Cargo, which handles everything for us, and does # so without doing an install (so it's fast). - run_shell_command("cargo update -p #{dependency_spec}") + run_shell_command("cargo update -p #{dependency_spec}", fingerprint: "cargo update -p ") end updated_lockfile = File.read("Cargo.lock") updated_lockfile = post_process_lockfile(updated_lockfile) - if updated_lockfile.include?(desired_lockfile_content) - next updated_lockfile - end + next updated_lockfile if updated_lockfile.include?(desired_lockfile_content) raise "Failed to update #{dependency.name}!" end @@ -60,7 +58,8 @@ def dependency def handle_cargo_error(error) raise unless error.message.include?("failed to select a version") || - error.message.include?("no matching version") + error.message.include?("no matching version") || + error.message.include?("unexpected end of input while parsing major version number") raise if error.message.include?("`#{dependency.name} ") raise Dependabot::DependencyFileNotResolvable, error.message @@ -68,6 +67,7 @@ def handle_cargo_error(error) # rubocop:disable Metrics/PerceivedComplexity # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/AbcSize def better_specification_needed?(error) return false if @custom_specification return false unless error.message.match?(/specification .* is ambigu/) @@ -96,6 +96,7 @@ def better_specification_needed?(error) @custom_specification = spec_options.first true end + # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity @@ -134,7 +135,7 @@ def desired_lockfile_content %(name = "#{dependency.name}"\nversion = "#{dependency.version}") end - def run_shell_command(command) + def run_shell_command(command, fingerprint:) start = Time.now command = SharedHelpers.escape_command(command) stdout, process = Open3.capture2e(command) @@ -148,6 +149,7 @@ def run_shell_command(command) message: stdout, error_context: { command: command, + fingerprint: fingerprint, time_taken: time_taken, process_exit_value: process.to_s } @@ -268,9 +270,7 @@ def remove_binary_specifications(content) def remove_default_run_specification(content) parsed_manifest = TomlRB.parse(content) - if parsed_manifest.dig("package", "default-run") - parsed_manifest["package"].delete("default-run") - end + parsed_manifest["package"].delete("default-run") if parsed_manifest.dig("package", "default-run") TomlRB.dump(parsed_manifest) end diff --git a/cargo/lib/dependabot/cargo/file_updater/manifest_updater.rb b/cargo/lib/dependabot/cargo/file_updater/manifest_updater.rb index 4d3798b8d3f..5877571a9c4 100644 --- a/cargo/lib/dependabot/cargo/file_updater/manifest_updater.rb +++ b/cargo/lib/dependabot/cargo/file_updater/manifest_updater.rb @@ -100,8 +100,9 @@ def update_manifest_req(content:, dep:, old_req:, new_req:) if simple_declaration simple_declaration_regex = /(?:^|["'])#{Regexp.escape(simple_declaration)}/ + old_req_escaped = Regexp.escape(old_req) content.gsub(simple_declaration_regex) do |line| - line.gsub(old_req, new_req) + line.gsub(/.+=.*\K(#{old_req_escaped})/, new_req) end elsif content.match?(feature_declaration_version_regex(dep)) content.gsub(feature_declaration_version_regex(dep)) do |part| @@ -138,7 +139,7 @@ def update_manifest_pin(content:, dep:, old_pin:, new_pin:) end def declaration_regex(dep) - /(?:^|["'])#{Regexp.escape(dep.name)}["']?\s*=.*$/i + /(?:^|^\s*|["'])#{Regexp.escape(dep.name)}["']?(?:\s*\.version)?\s*=.*$/i end def feature_declaration_version_regex(dep) diff --git a/cargo/lib/dependabot/cargo/metadata_finder.rb b/cargo/lib/dependabot/cargo/metadata_finder.rb index 3c8b226384b..0d6ac9940ad 100644 --- a/cargo/lib/dependabot/cargo/metadata_finder.rb +++ b/cargo/lib/dependabot/cargo/metadata_finder.rb @@ -3,7 +3,7 @@ require "excon" require "dependabot/metadata_finders" require "dependabot/metadata_finders/base" -require "dependabot/shared_helpers" +require "dependabot/registry_client" module Dependabot module Cargo @@ -33,15 +33,14 @@ def new_source_type def find_source_from_crates_listing potential_source_urls = SOURCE_KEYS. - map { |key| crates_listing.dig("crate", key) }. - compact + filter_map { |key| crates_listing.dig("crate", key) } source_url = potential_source_urls.find { |url| Source.from_url(url) } Source.from_url(source_url) end def find_source_from_git_url - info = dependency.requirements.map { |r| r[:source] }.compact.first + info = dependency.requirements.filter_map { |r| r[:source] }.first url = info[:url] || info.fetch("url") Source.from_url(url) @@ -50,13 +49,7 @@ def find_source_from_git_url def crates_listing return @crates_listing unless @crates_listing.nil? - response = Excon.get( - "https://crates.io/api/v1/crates/#{dependency.name}", - headers: { "User-Agent" => "Dependabot (dependabot.com)" }, - idempotent: true, - **SharedHelpers.excon_defaults - ) - + response = Dependabot::RegistryClient.get(url: "https://crates.io/api/v1/crates/#{dependency.name}") @crates_listing = JSON.parse(response.body) end end diff --git a/cargo/lib/dependabot/cargo/requirement.rb b/cargo/lib/dependabot/cargo/requirement.rb index e960196cb63..84cec9a8316 100644 --- a/cargo/lib/dependabot/cargo/requirement.rb +++ b/cargo/lib/dependabot/cargo/requirement.rb @@ -16,7 +16,7 @@ class Requirement < Gem::Requirement version_pattern = Cargo::Version::VERSION_PATTERN PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*" - PATTERN = /\A#{PATTERN_RAW}\z/.freeze + PATTERN = /\A#{PATTERN_RAW}\z/ # Use Cargo::Version rather than Gem::Version to ensure that # pre-release versions aren't transformed. @@ -33,7 +33,7 @@ def self.parse(obj) [matches[1] || "=", Cargo::Version.new(matches[2])] end - # For consistency with other langauges, we define a requirements array. + # For consistency with other languages, we define a requirements array. # Rust doesn't have an `OR` separator for requirements, so it always # contains a single element. def self.requirements_array(requirement_string) @@ -42,7 +42,7 @@ def self.requirements_array(requirement_string) def initialize(*requirements) requirements = requirements.flatten.flat_map do |req_string| - req_string.split(",").map do |r| + req_string.split(",").map(&:strip).map do |r| convert_rust_constraint_to_ruby_constraint(r.strip) end end @@ -53,14 +53,13 @@ def initialize(*requirements) private def convert_rust_constraint_to_ruby_constraint(req_string) - req_string = req_string - if req_string.include?("*") ruby_range(req_string.gsub(/(?:\.|^)[*]/, "").gsub(/^[^\d]/, "")) elsif req_string.match?(/^~[^>]/) then convert_tilde_req(req_string) elsif req_string.match?(/^[\d^]/) then convert_caret_req(req_string) elsif req_string.match?(/[<=>]/) then req_string - else ruby_range(req_string) + else + ruby_range(req_string) end end @@ -94,7 +93,8 @@ def convert_caret_req(req_string) upper_bound = parts.map.with_index do |part, i| if i < first_non_zero_index then part elsif i == first_non_zero_index then (part.to_i + 1).to_s - else 0 + else + 0 end end.join(".") diff --git a/cargo/lib/dependabot/cargo/update_checker.rb b/cargo/lib/dependabot/cargo/update_checker.rb index 31ab6f023c2..23a3121f904 100644 --- a/cargo/lib/dependabot/cargo/update_checker.rb +++ b/cargo/lib/dependabot/cargo/update_checker.rb @@ -42,12 +42,14 @@ def latest_resolvable_version end end + def lowest_security_fix_version + latest_version_finder.lowest_security_fix_version + end + def lowest_resolvable_security_fix_version raise "Dependency not vulnerable!" unless vulnerable? - if defined?(@lowest_resolvable_security_fix_version) - return @lowest_resolvable_security_fix_version - end + return @lowest_resolvable_security_fix_version if defined?(@lowest_resolvable_security_fix_version) @lowest_resolvable_security_fix_version = fetch_lowest_resolvable_security_fix_version @@ -121,9 +123,7 @@ def latest_version_for_git_dependency def latest_git_version_sha # If the gem isn't pinned, the latest version is just the latest # commit for the specified branch. - unless git_commit_checker.pinned? - return git_commit_checker.head_commit_for_current_branch - end + return git_commit_checker.head_commit_for_current_branch unless git_commit_checker.pinned? # If the dependency is pinned to a tag that looks like a version then # we want to update that tag. The latest version will then be the SHA @@ -141,9 +141,7 @@ def latest_git_version_sha def latest_resolvable_version_for_git_dependency # If the gem isn't pinned, the latest version is just the latest # commit for the specified branch. - unless git_commit_checker.pinned? - return latest_resolvable_commit_with_unchanged_git_source - end + return latest_resolvable_commit_with_unchanged_git_source unless git_commit_checker.pinned? # If the dependency is pinned to a tag that looks like a version then # we want to update that tag. The latest version will then be the SHA @@ -214,12 +212,10 @@ def fetch_latest_resolvable_version(unlock_requirement:) end def fetch_lowest_resolvable_security_fix_version - fix_version = latest_version_finder.lowest_security_fix_version + fix_version = lowest_security_fix_version return latest_resolvable_version if fix_version.nil? - if path_dependency? || git_dependency? || git_subdependency? - return latest_resolvable_version - end + return latest_resolvable_version if path_dependency? || git_dependency? || git_subdependency? prepared_files = FilePreparer.new( dependency_files: dependency_files, diff --git a/cargo/lib/dependabot/cargo/update_checker/file_preparer.rb b/cargo/lib/dependabot/cargo/update_checker/file_preparer.rb index d78c9828304..6f29dc86483 100644 --- a/cargo/lib/dependabot/cargo/update_checker/file_preparer.rb +++ b/cargo/lib/dependabot/cargo/update_checker/file_preparer.rb @@ -62,7 +62,7 @@ def manifest_content_for_update_check(file) content end - # Note: We don't need to care about formatting in this method, since + # NOTE: We don't need to care about formatting in this method, since # we're only using the manifest to find the latest resolvable version def replace_version_constraint(content, filename) parsed_manifest = TomlRB.parse(content) @@ -120,13 +120,9 @@ def replace_git_pin(content) next unless req.is_a?(Hash) next unless [req["tag"], req["rev"]].compact.uniq.count == 1 - if req["tag"] - parsed_manifest[type][name]["tag"] = replacement_git_pin - end + parsed_manifest[type][name]["tag"] = replacement_git_pin if req["tag"] - if req["rev"] - parsed_manifest[type][name]["rev"] = replacement_git_pin - end + parsed_manifest[type][name]["rev"] = replacement_git_pin if req["rev"] end end @@ -201,6 +197,7 @@ def temporary_requirement_for_resolution(filename) lower_bound_req + ", <= #{latest_allowable_version}" end + # rubocop:disable Metrics/PerceivedComplexity def lower_bound_version @lower_bound_version ||= if git_dependency? && git_dependency_version @@ -209,8 +206,7 @@ def lower_bound_version dependency.version else version_from_requirement = - dependency.requirements.map { |r| r.fetch(:requirement) }. - compact. + dependency.requirements.filter_map { |r| r.fetch(:requirement) }. flat_map { |req_str| Cargo::Requirement.new(req_str) }. flat_map(&:requirements). reject { |req_array| req_array.first.start_with?("<") }. @@ -220,6 +216,7 @@ def lower_bound_version version_from_requirement || 0 end end + # rubocop:enable Metrics/PerceivedComplexity def git_dependency_version return unless lockfile @@ -253,9 +250,7 @@ def dependency_names_for_type_and_target(parsed_manifest, type, target) def name_from_declaration(name, declaration) return name if declaration.is_a?(String) - unless declaration.is_a?(Hash) - raise "Unexpected dependency declaration: #{declaration}" - end + raise "Unexpected dependency declaration: #{declaration}" unless declaration.is_a?(Hash) declaration.fetch("package", name) end diff --git a/cargo/lib/dependabot/cargo/update_checker/latest_version_finder.rb b/cargo/lib/dependabot/cargo/update_checker/latest_version_finder.rb index 14cc67d9dbe..e31e0786be2 100644 --- a/cargo/lib/dependabot/cargo/update_checker/latest_version_finder.rb +++ b/cargo/lib/dependabot/cargo/update_checker/latest_version_finder.rb @@ -2,6 +2,8 @@ require "excon" require "dependabot/cargo/update_checker" +require "dependabot/update_checkers/version_filters" +require "dependabot/registry_client" module Dependabot module Cargo @@ -41,9 +43,11 @@ def fetch_latest_version def fetch_lowest_security_fix_version versions = available_versions versions = filter_prerelease_versions(versions) - versions = filter_vulnerable_versions(versions) + versions = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(versions, + security_advisories) versions = filter_ignored_versions(versions) versions = filter_lower_versions(versions) + versions.min end @@ -55,22 +59,19 @@ def filter_prerelease_versions(versions_array) def filter_ignored_versions(versions_array) filtered = versions_array. - reject { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } } - if @raise_on_ignored && filtered.empty? && versions_array.any? + reject { |v| ignore_requirements.any? { |r| r.satisfied_by?(v) } } + if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(versions_array).any? raise Dependabot::AllVersionsIgnored end filtered end - def filter_vulnerable_versions(versions_array) - versions_array. - reject { |v| security_advisories.any? { |a| a.vulnerable?(v) } } - end - def filter_lower_versions(versions_array) + return versions_array unless dependency.numeric_version + versions_array. - select { |version| version > version_class.new(dependency.version) } + select { |version| version > dependency.numeric_version } end def available_versions @@ -83,27 +84,12 @@ def available_versions def crates_listing return @crates_listing unless @crates_listing.nil? - response = Excon.get( - "https://crates.io/api/v1/crates/#{dependency.name}", - idempotent: true, - headers: { "User-Agent" => "Dependabot (dependabot.com)" }, - **SharedHelpers.excon_defaults - ) - + response = Dependabot::RegistryClient.get(url: "https://crates.io/api/v1/crates/#{dependency.name}") @crates_listing = JSON.parse(response.body) - rescue Excon::Error::Timeout - retrying ||= false - raise if retrying - - retrying = true - sleep(rand(1.0..5.0)) && retry end def wants_prerelease? - if dependency.version && - version_class.new(dependency.version).prerelease? - return true - end + return true if dependency.numeric_version&.prerelease? dependency.requirements.any? do |req| reqs = (req.fetch(:requirement) || "").split(",").map(&:strip) @@ -111,8 +97,8 @@ def wants_prerelease? end end - def ignore_reqs - ignored_versions.map { |req| requirement_class.new(req.split(",")) } + def ignore_requirements + ignored_versions.flat_map { |req| requirement_class.requirements_array(req) } end def version_class diff --git a/cargo/lib/dependabot/cargo/update_checker/requirements_updater.rb b/cargo/lib/dependabot/cargo/update_checker/requirements_updater.rb index fe067b3df33..a19b71beca0 100644 --- a/cargo/lib/dependabot/cargo/update_checker/requirements_updater.rb +++ b/cargo/lib/dependabot/cargo/update_checker/requirements_updater.rb @@ -16,7 +16,7 @@ class UpdateChecker class RequirementsUpdater class UnfixableRequirement < StandardError; end - VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-*]+)*/.freeze + VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-*]+)*/ ALLOWED_UPDATE_STRATEGIES = %i(bump_versions bump_versions_if_necessary).freeze @@ -34,7 +34,7 @@ def initialize(requirements:, updated_source:, update_strategy:, end def updated_requirements - # Note: Order is important here. The FileUpdater needs the updated + # NOTE: Order is important here. The FileUpdater needs the updated # requirement at index `i` to correspond to the previous requirement # at the same index. requirements.map do |req| @@ -94,13 +94,13 @@ def update_version_requirement_if_needed(req) end def update_version_string(req_string) + new_target_parts = target_version.to_s.sub(/\+.*/, "").split(".") req_string.sub(VERSION_REGEX) do |old_version| # For pre-release versions, just use the full version string next target_version.to_s if old_version.match?(/\d-/) old_parts = old_version.split(".") - new_parts = target_version.to_s.split("."). - first(old_parts.count) + new_parts = new_target_parts.first(old_parts.count) new_parts.map.with_index do |part, i| old_parts[i] == "*" ? "*" : part end.join(".") @@ -144,7 +144,8 @@ def update_greatest_version(old_version, version_to_be_permitted) version_to_be_permitted.segments[index] elsif index == index_to_update version_to_be_permitted.segments[index] + 1 - else 0 + else + 0 end end.join(".") end diff --git a/cargo/lib/dependabot/cargo/update_checker/version_resolver.rb b/cargo/lib/dependabot/cargo/update_checker/version_resolver.rb index b74c1bb6220..6ba1dbbba2d 100644 --- a/cargo/lib/dependabot/cargo/update_checker/version_resolver.rb +++ b/cargo/lib/dependabot/cargo/update_checker/version_resolver.rb @@ -11,12 +11,12 @@ module Dependabot module Cargo class UpdateChecker class VersionResolver - UNABLE_TO_UPDATE = - /Unable to update (?.*?)$/.freeze - BRANCH_NOT_FOUND_REGEX = - /#{UNABLE_TO_UPDATE}.*to find branch `(?[^`]+)`/m.freeze - REF_NOT_FOUND_REGEX = - /#{UNABLE_TO_UPDATE}.*revspec '.*' not found/m.freeze + UNABLE_TO_UPDATE = /Unable to update (?.*?)$/ + BRANCH_NOT_FOUND_REGEX = /#{UNABLE_TO_UPDATE}.*to find branch `(?[^`]+)`/m + REVSPEC_PATTERN = /revspec '.*' not found/ + OBJECT_PATTERN = /object not found - no match for id \(.*\)/ + REF_NOT_FOUND_REGEX = /#{UNABLE_TO_UPDATE}.*(#{REVSPEC_PATTERN}|#{OBJECT_PATTERN})/m + GIT_REF_NOT_FOUND_REGEX = /Updating git repository `(?[^`]*)`.*fatal: couldn't find remote ref/m def initialize(dependency:, credentials:, original_dependency_files:, prepared_dependency_files:) @@ -27,7 +27,9 @@ def initialize(dependency:, credentials:, end def latest_resolvable_version - @latest_resolvable_version ||= fetch_latest_resolvable_version + return @latest_resolvable_version if defined?(@latest_resolvable_version) + + @latest_resolvable_version = fetch_latest_resolvable_version end private @@ -41,9 +43,7 @@ def fetch_latest_resolvable_version write_temporary_dependency_files SharedHelpers.with_git_configured(credentials: credentials) do - # Shell out to Cargo, which handles everything for us, and does - # so without doing an install (so it's fast). - run_cargo_command("cargo update -p #{dependency_spec} --verbose") + run_cargo_update_command end updated_version = fetch_version_from_new_lockfile @@ -71,6 +71,8 @@ def fetch_version_from_new_lockfile versions.min_by { |p| version_class.new(p.fetch("version")) } end + return unless updated_version + if git_dependency? updated_version.fetch("source").split("#").last else @@ -80,6 +82,7 @@ def fetch_version_from_new_lockfile # rubocop:disable Metrics/PerceivedComplexity # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/AbcSize def better_specification_needed?(error) return false if @custom_specification return false unless error.message.match?(/specification .* is ambigu/) @@ -108,6 +111,7 @@ def better_specification_needed?(error) @custom_specification = spec_options.first true end + # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity @@ -126,7 +130,16 @@ def dependency_spec spec end - def run_cargo_command(command) + # Shell out to Cargo, which handles everything for us, and does + # so without doing an install (so it's fast). + def run_cargo_update_command + run_cargo_command( + "cargo update -p #{dependency_spec} --verbose", + fingerprint: "cargo update -p --verbose" + ) + end + + def run_cargo_command(command, fingerprint: nil) start = Time.now command = SharedHelpers.escape_command(command) stdout, process = Open3.capture2e(command) @@ -140,6 +153,7 @@ def run_cargo_command(command) message: stdout, error_context: { command: command, + fingerprint: fingerprint, time_taken: time_taken, process_exit_value: process.to_s } @@ -159,11 +173,11 @@ def check_rust_workspace_root max_by { |f| f.name.length } return unless TomlRB.parse(cargo_toml.content)["workspace"] - msg = "This project is part of a Rust workspace but is not the "\ - "workspace root."\ + msg = "This project is part of a Rust workspace but is not the " \ + "workspace root." \ if cargo_toml.directory != "/" - msg += "Please update your settings so Dependabot points at the "\ + msg += "Please update your settings so Dependabot points at the " \ "workspace root instead of #{cargo_toml.directory}." end raise Dependabot::DependencyFileNotResolvable, msg @@ -171,7 +185,6 @@ def check_rust_workspace_root # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/PerceivedComplexity - # rubocop:disable Metrics/MethodLength def handle_cargo_errors(error) if error.message.include?("does not have these features") # TODO: Ideally we should update the declaration not to ask @@ -180,7 +193,7 @@ def handle_cargo_errors(error) end if error.message.include?("authenticate when downloading repo") || - error.message.include?("HTTP 200 response: got 401") + error.message.include?("fatal: Authentication failed for") # Check all dependencies for reachability (so that we raise a # consistent error) urls = unreachable_git_urls @@ -196,24 +209,13 @@ def handle_cargo_errors(error) raise Dependabot::GitDependenciesNotReachable, urls end - if error.message.match?(BRANCH_NOT_FOUND_REGEX) - dependency_url = - error.message.match(BRANCH_NOT_FOUND_REGEX). - named_captures.fetch("url").split(/[#?]/).first - raise Dependabot::GitDependencyReferenceNotFound, dependency_url - end + [BRANCH_NOT_FOUND_REGEX, REF_NOT_FOUND_REGEX, GIT_REF_NOT_FOUND_REGEX].each do |regex| + next unless error.message.match?(regex) - if error.message.match?(REF_NOT_FOUND_REGEX) - dependency_url = - error.message.match(REF_NOT_FOUND_REGEX). - named_captures.fetch("url").split(/[#?]/).first + dependency_url = error.message.match(regex).named_captures.fetch("url").split(/[#?]/).first raise Dependabot::GitDependencyReferenceNotFound, dependency_url end - if resolvability_error?(error.message) - raise Dependabot::DependencyFileNotResolvable, error.message - end - if workspace_native_library_update_error?(error.message) # This happens when we're updating one part of a workspace which # triggers an update of a subdependency that uses a native library, @@ -235,11 +237,12 @@ def handle_cargo_errors(error) return nil end + raise Dependabot::DependencyFileNotResolvable, error.message if resolvability_error?(error.message) + raise error end # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/PerceivedComplexity - # rubocop:enable Metrics/MethodLength def unreachable_git_urls return @unreachable_git_urls if defined?(@unreachable_git_urls) @@ -285,6 +288,7 @@ def resolvability_error?(message) return true if message.include?("wasn't a root") return true if message.include?("requires a nightly version") return true if message.match?(/feature `[^\`]+` is required/) + return true if message.include?("unexpected end of input while parsing major version number") !original_requirements_resolvable? end @@ -295,7 +299,7 @@ def original_requirements_resolvable? write_temporary_dependency_files(prepared: false) SharedHelpers.with_git_configured(credentials: credentials) do - run_cargo_command("cargo update -p #{dependency_spec} --verbose") + run_cargo_update_command end end @@ -325,7 +329,8 @@ def workspace_native_library_update_error?(message) def write_manifest_files(prepared: true) manifest_files = if prepared then prepared_manifest_files - else original_manifest_files + else + original_manifest_files end manifest_files.each do |file| @@ -369,16 +374,12 @@ def sanitized_manifest_content(content) object.delete("bin") - if object.dig("package", "default-run") - object["package"].delete("default-run") - end + object["package"].delete("default-run") if object.dig("package", "default-run") package_name = object.dig("package", "name") return TomlRB.dump(object) unless package_name&.match?(/[\{\}]/) - if lockfile - raise "Sanitizing name for pkg with lockfile. Investigate!" - end + raise "Sanitizing name for pkg with lockfile. Investigate!" if lockfile object["package"]["name"] = "sanitized" TomlRB.dump(object) diff --git a/cargo/lib/dependabot/cargo/version.rb b/cargo/lib/dependabot/cargo/version.rb index 4190104b451..576695ace05 100644 --- a/cargo/lib/dependabot/cargo/version.rb +++ b/cargo/lib/dependabot/cargo/version.rb @@ -10,10 +10,10 @@ module Dependabot module Cargo class Version < Gem::Version - VERSION_PATTERN = '[0-9]+[0-9a-zA-Z]*(?>\.[0-9a-zA-Z]+)*' \ + VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*' \ '(-[0-9A-Za-z-]+(\.[0-9a-zA-Z-]+)*)?' \ - '(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?' - ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze + '(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?' + ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/ def initialize(version) @version_string = version.to_s @@ -29,6 +29,12 @@ def to_s def inspect # :nodoc: "#<#{self.class} #{@version_string}>" end + + def self.correct?(version) + return false if version.nil? + + version.to_s.match?(ANCHORED_VERSION_PATTERN) + end end end end diff --git a/cargo/script/ci-test b/cargo/script/ci-test new file mode 100755 index 00000000000..c29bd83bf2e --- /dev/null +++ b/cargo/script/ci-test @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +bundle install +bundle exec rubocop . +bundle exec rspec spec diff --git a/cargo/spec/dependabot/cargo/file_fetcher_spec.rb b/cargo/spec/dependabot/cargo/file_fetcher_spec.rb index e3f462155d1..07d2a7823d7 100644 --- a/cargo/spec/dependabot/cargo/file_fetcher_spec.rb +++ b/cargo/spec/dependabot/cargo/file_fetcher_spec.rb @@ -157,6 +157,20 @@ end end + context "with a blank path" do + let(:parent_fixture) do + fixture( + "github", + "contents_cargo_manifest_path_deps_blank.json" + ) + end + + it "fetches the path dependency's Cargo.toml" do + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(Cargo.toml)) + end + end + context "for a target dependency" do let(:parent_fixture) do fixture( @@ -223,7 +237,7 @@ "https://api.github.com/repos/gocardless/bump/contents/my_dir/" end before do - stub_request(:get, "https://api.github.com/repos/gocardless/bump/"\ + stub_request(:get, "https://api.github.com/repos/gocardless/bump/" \ "contents/my_dir?ref=sha"). with(headers: { "Authorization" => "token token" }). to_return( @@ -395,6 +409,13 @@ stub_request(:get, url + "lib/sub_crate/Cargo.toml?ref=sha"). with(headers: { "Authorization" => "token token" }). to_return(status: 404, headers: json_header) + # additional requests due to submodule searching + stub_request(:get, url + "lib/sub_crate?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404, headers: json_header) + stub_request(:get, url + "lib?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404, headers: json_header) end it "raises a DependencyFileNotFound error" do @@ -403,6 +424,35 @@ end end + context "that is in a submodule" do + before do + # This file doesn't exist because sub_crate is a submodule, so returns a 404 + stub_request(:get, url + "lib/sub_crate/Cargo.toml?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404, headers: json_header) + # This returns type: submodule, we're in the common submodule logic now + stub_request(:get, url + "lib/sub_crate?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 200, headers: json_header, body: fixture("github", "contents_cargo_submodule.json")) + # Attempt to find the Cargo.toml in the submodule's repo. + submodule_root = "https://api.github.com/repos/runconduit/conduit" + stub_request(:get, submodule_root + "/contents/?ref=453df4efd57f5e8958adf17d728520bd585c82c9"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 200, headers: json_header, body: fixture("github", "contents_cargo_without_lockfile.json")) + # Found it, so download it! + stub_request(:get, submodule_root + "/contents/Cargo.toml?ref=453df4efd57f5e8958adf17d728520bd585c82c9 "). + with(headers: { "Authorization" => "token token" }). + to_return(status: 200, headers: json_header, body: fixture("github", "contents_cargo_manifest.json")) + end + + it "places the found Cargo.toml in the correct directories" do + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(Cargo.toml lib/sub_crate/Cargo.toml)) + expect(file_fetcher_instance.files.map(&:path)). + to match_array(%w(/Cargo.toml /lib/sub_crate/Cargo.toml)) + end + end + context "that specifies a directory of packages" do let(:parent_fixture) do fixture("github", "contents_cargo_manifest_workspace_root_glob.json") diff --git a/cargo/spec/dependabot/cargo/file_parser_spec.rb b/cargo/spec/dependabot/cargo/file_parser_spec.rb index a957820230e..5b8dd4b137a 100644 --- a/cargo/spec/dependabot/cargo/file_parser_spec.rb +++ b/cargo/spec/dependabot/cargo/file_parser_spec.rb @@ -365,6 +365,58 @@ end end + context "with workspace dependencies" do + let(:manifest_fixture_name) { "workspace_dependencies_root" } + let(:lockfile_fixture_name) { "workspace_dependencies" } + let(:files) do + [ + manifest, + lockfile, + workspace_child + ] + end + let(:workspace_child) do + Dependabot::DependencyFile.new( + name: "lib/inherit_ws_dep/Cargo.toml", + content: fixture("manifests", "workspace_dependencies_child") + ) + end + + describe "top level dependencies" do + subject(:top_level_dependencies) do + dependencies.select(&:top_level?) + end + + its(:length) { is_expected.to eq(1) } + + describe "the first dependency" do + subject(:dependency) { top_level_dependencies.first } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("log") + expect(dependency.version).to eq("0.4.0") + expect(dependency.requirements).to eq( + [ + { + requirement: "=0.4.0", + file: "Cargo.toml", + groups: ["workspace.dependencies"], + source: nil + }, + { + requirement: nil, + file: "lib/inherit_ws_dep/Cargo.toml", + groups: ["dependencies"], + source: nil + } + ] + ) + end + end + end + end + context "with a git dependency" do let(:manifest_fixture_name) { "git_dependency" } @@ -732,7 +784,7 @@ let(:lockfile_fixture_name) { "feature_dependency" } describe "the first dependency" do - subject(:dependency) { dependencies.select(&:top_level?).first } + subject(:dependency) { dependencies.find(&:top_level?) } it "has the right details" do expect(dependency).to be_a(Dependabot::Dependency) @@ -753,7 +805,7 @@ let(:manifest_fixture_name) { "feature_dependency_no_version" } describe "the first dependency" do - subject(:dependency) { dependencies.select(&:top_level?).first } + subject(:dependency) { dependencies.find(&:top_level?) } it "has the right details" do expect(dependency).to be_a(Dependabot::Dependency) @@ -773,6 +825,12 @@ end end + context "with resolver version 2" do + let(:manifest_fixture_name) { "resolver2" } + let(:lockfile_fixture_name) { "no_dependencies" } + it { is_expected.to eq([]) } + end + context "with no dependencies" do let(:manifest_fixture_name) { "no_dependencies" } let(:lockfile_fixture_name) { "no_dependencies" } diff --git a/cargo/spec/dependabot/cargo/file_updater/lockfile_updater_spec.rb b/cargo/spec/dependabot/cargo/file_updater/lockfile_updater_spec.rb index 1663c3554dc..43db70f3685 100644 --- a/cargo/spec/dependabot/cargo/file_updater/lockfile_updater_spec.rb +++ b/cargo/spec/dependabot/cargo/file_updater/lockfile_updater_spec.rb @@ -46,9 +46,9 @@ let(:previous_requirements) do [{ file: "Cargo.toml", requirement: "0.1.12", groups: [], source: nil }] end - let(:tmp_path) { Dependabot::SharedHelpers::BUMP_TMP_DIR_PATH } + let(:tmp_path) { Dependabot::Utils::BUMP_TMP_DIR_PATH } - before { Dir.mkdir(tmp_path) unless Dir.exist?(tmp_path) } + before { FileUtils.mkdir_p(tmp_path) } describe "#updated_lockfile_content" do subject(:updated_lockfile_content) { updater.updated_lockfile_content } @@ -95,10 +95,14 @@ expect(updated_lockfile_content). to include(%(name = "time"\nversion = "0.1.40")) expect(updated_lockfile_content).to include( - "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" + <<~CHECKSUM + checksum = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" + CHECKSUM ) expect(updated_lockfile_content).to_not include( - "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" + <<~CHECKSUM + checksum = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" + CHECKSUM ) end @@ -154,9 +158,10 @@ [{ file: "Cargo.toml", requirement: nil, groups: [], source: nil }] end - it "updates the dependency version in the lockfile" do - expect(updated_lockfile_content). - to include(%(name = "time"\nversion = "0.1.40")) + it "raises a DependencyFileNotResolvable error" do + expect { subject }.to raise_error(Dependabot::DependencyFileNotResolvable) do |error| + expect(error.message).to include("unexpected end of input while parsing major version") + end end end @@ -183,13 +188,27 @@ end end + context "with an old format lockfile" do + let(:manifest_fixture_name) { "old_lockfile" } + let(:lockfile_fixture_name) { "old_lockfile" } + + it "updates the lockfile to the new version" do + expect(updated_lockfile_content).to include( + <<~CHECKSUM + checksum = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" + CHECKSUM + ) + expect(updated_lockfile_content).to_not include("[metadata]") + end + end + context "with a git dependency" do let(:manifest_fixture_name) { "git_dependency" } let(:lockfile_fixture_name) { "git_dependency" } let(:dependency_name) { "utf8-ranges" } let(:dependency_version) do - "8d38a931b7e34f9da339c058cbbca6ded624ea58" + "be9b8dfcaf449453cbf83ac85260ee80323f4f77" end let(:dependency_previous_version) do "83141b376b93484341c68fbca3ca110ae5cd2708" @@ -211,7 +230,7 @@ it "updates the dependency version in the lockfile" do expect(updated_lockfile_content). - to include("utf8-ranges#8d38a931b7e34f9da339c058cbbca6ded624ea58") + to include("utf8-ranges#be9b8dfcaf449453cbf83ac85260ee80323f4f77") end context "with an ssh URl" do @@ -234,18 +253,10 @@ it "updates the dependency version in the lockfile" do expect(updated_lockfile_content). - to include("git+ssh://git@github.com/BurntSushi/utf8-ranges#"\ - "8d38a931b7e34f9da339c058cbbca6ded624ea58") + to include("git+ssh://git@github.com/BurntSushi/utf8-ranges#" \ + "be9b8dfcaf449453cbf83ac85260ee80323f4f77") expect(updated_lockfile_content).to_not include("git+https://") - expect(updated_lockfile_content).to include( - "[metadata]\n"\ - '"checksum utf8-ranges 1.0.4 (git+ssh://git@github.com/'\ - "BurntSushi/utf8-ranges)\" = \"\"\n"\ - '"checksum utf8-ranges-parent 1.0.2 (git+ssh://git@github.com/'\ - "dependabot-fixtures/utf8-ranges)\" = \"\"" - ) - content = updated_lockfile_content expect(content.scan(/name = "utf8-ranges"/).count).to eq(1) end diff --git a/cargo/spec/dependabot/cargo/file_updater/manifest_updater_spec.rb b/cargo/spec/dependabot/cargo/file_updater/manifest_updater_spec.rb index 8e588e73397..e0ffd3e1622 100644 --- a/cargo/spec/dependabot/cargo/file_updater/manifest_updater_spec.rb +++ b/cargo/spec/dependabot/cargo/file_updater/manifest_updater_spec.rb @@ -65,6 +65,14 @@ it { is_expected.to include(%(business_time = "0.1.12")) } end + context "with dependencies that include whitespace" do + let(:manifest_fixture_name) { "whitespace_names" } + + it { is_expected.to include(%(time = "0.1.38")) } + it { is_expected.to include(%(regex = "0.1.41")) } + it { is_expected.to_not include(%("time" = "0.1.12")) } + end + context "with a target-specific dependency" do let(:manifest_fixture_name) { "target_dependency" } it { is_expected.to include(%(time = "<= 0.1.38")) } @@ -99,6 +107,41 @@ end end + context "with a dependency version in dotted key syntax" do + let(:manifest_fixture_name) { "dotted_key_version" } + + it { is_expected.to include(%(time.version = "0.1.38")) } + end + + context "with a dependency name that includes the version range" do + let(:manifest_fixture_name) { "version_in_name" } + let(:dependency_name) { "curve25519-dalek" } + let(:dependency_version) { "3" } + let(:dependency_previous_version) { "2" } + let(:requirements) do + [{ + file: "Cargo.toml", + requirement: "3", + groups: [], + source: nil + }] + end + let(:previous_requirements) do + [{ + file: "Cargo.toml", + requirement: "2", + groups: [], + source: nil + }] + end + + it "includes the new requirement" do + expect(updated_manifest_content).to include( + %(curve25519-dalek = "3") + ) + end + end + context "with a repeated dependency when only one req has changed" do let(:manifest_fixture_name) { "repeated_dependency" } let(:requirements) do @@ -235,6 +278,30 @@ to include(%([dependencies.pango]\nversion = "0.3.0"\n)) end end + + context "with a version requirement" do + context "with a target-specific dependency" do + let(:manifest_fixture_name) { "version_requirement" } + let(:previous_requirements) do + [{ + file: "Cargo.toml", + requirement: "^0.1.38", + groups: [], + source: nil + }] + end + let(:requirements) do + [{ + file: "Cargo.toml", + requirement: "^0.1.40", + groups: [], + source: nil + }] + end + + it { is_expected.to include(%(time = "^0.1.40")) } + end + end end end end diff --git a/cargo/spec/dependabot/cargo/file_updater_spec.rb b/cargo/spec/dependabot/cargo/file_updater_spec.rb index a18c7b4d464..f2652a76d10 100644 --- a/cargo/spec/dependabot/cargo/file_updater_spec.rb +++ b/cargo/spec/dependabot/cargo/file_updater_spec.rb @@ -52,9 +52,9 @@ let(:previous_requirements) do [{ file: "Cargo.toml", requirement: "0.1.12", groups: [], source: nil }] end - let(:tmp_path) { Dependabot::SharedHelpers::BUMP_TMP_DIR_PATH } + let(:tmp_path) { Dependabot::Utils::BUMP_TMP_DIR_PATH } - before { Dir.mkdir(tmp_path) unless Dir.exist?(tmp_path) } + before { FileUtils.mkdir_p(tmp_path) } describe "#updated_dependency_files" do subject(:updated_files) { updater.updated_dependency_files } diff --git a/cargo/spec/dependabot/cargo/metadata_finder_spec.rb b/cargo/spec/dependabot/cargo/metadata_finder_spec.rb index aea6f007a89..4f23d4b3499 100644 --- a/cargo/spec/dependabot/cargo/metadata_finder_spec.rb +++ b/cargo/spec/dependabot/cargo/metadata_finder_spec.rb @@ -35,6 +35,14 @@ let(:dependency_name) { "bitflags" } let(:dependency_source) { nil } + before do + stub_request(:get, "https://example.com/status").to_return( + status: 200, + body: "Not GHES", + headers: {} + ) + end + describe "#source_url" do subject(:source_url) { finder.source_url } let(:crates_url) { "https://crates.io/api/v1/crates/bitflags" } diff --git a/cargo/spec/dependabot/cargo/update_checker/file_preparer_spec.rb b/cargo/spec/dependabot/cargo/update_checker/file_preparer_spec.rb index 2da1ab55284..cb8f12768d8 100644 --- a/cargo/spec/dependabot/cargo/update_checker/file_preparer_spec.rb +++ b/cargo/spec/dependabot/cargo/update_checker/file_preparer_spec.rb @@ -114,8 +114,8 @@ it "updates the requirement" do expect(prepared_manifest_file.content). to include( - "[dependencies.alias]\n"\ - "package = \"time\"\n"\ + "[dependencies.alias]\n" \ + "package = \"time\"\n" \ "version = \">= 0.1.12\"" ) end @@ -129,8 +129,8 @@ it "doesn't update the requirement" do expect(prepared_manifest_file.content). to include( - "[dependencies.alias]\n"\ - "package = \"time\"\n"\ + "[dependencies.alias]\n" \ + "package = \"time\"\n" \ "version = \"0.1.12\"" ) end diff --git a/cargo/spec/dependabot/cargo/update_checker/latest_version_finder_spec.rb b/cargo/spec/dependabot/cargo/update_checker/latest_version_finder_spec.rb index b45366efa59..ea942e0c18b 100644 --- a/cargo/spec/dependabot/cargo/update_checker/latest_version_finder_spec.rb +++ b/cargo/spec/dependabot/cargo/update_checker/latest_version_finder_spec.rb @@ -129,6 +129,48 @@ end end end + + context "raise_on_ignored when later versions are allowed" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + + context "when already on the latest version" do + let(:dependency_version) { "0.1.40" } + it { is_expected.to eq(Gem::Version.new("0.1.40")) } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end + + context "when all later versions are being ignored" do + let(:ignored_versions) { ["> 0.1.38"] } + it { is_expected.to eq(Gem::Version.new("0.1.38")) } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "raises an error" do + expect { subject }.to raise_error(Dependabot::AllVersionsIgnored) + end + end + end + + context "when the dependency version isn't known" do + let(:dependency_version) { nil } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end end describe "#lowest_security_fix_version" do diff --git a/cargo/spec/dependabot/cargo/update_checker/requirements_updater_spec.rb b/cargo/spec/dependabot/cargo/update_checker/requirements_updater_spec.rb index 708fa42f72a..57fc55d99e1 100644 --- a/cargo/spec/dependabot/cargo/update_checker/requirements_updater_spec.rb +++ b/cargo/spec/dependabot/cargo/update_checker/requirements_updater_spec.rb @@ -211,6 +211,12 @@ ) end end + + context "and the target version has a build annotation" do + let(:req_string) { "1.2.3" } + let(:target_version) { "1.5.0+build.1" } + its([:requirement]) { is_expected.to eq("1.5.0") } + end end end diff --git a/cargo/spec/dependabot/cargo/update_checker/version_resolver_spec.rb b/cargo/spec/dependabot/cargo/update_checker/version_resolver_spec.rb index c3761b50e10..850872d0094 100644 --- a/cargo/spec/dependabot/cargo/update_checker/version_resolver_spec.rb +++ b/cargo/spec/dependabot/cargo/update_checker/version_resolver_spec.rb @@ -131,7 +131,7 @@ to raise_error do |error| expect(error).to be_a(Dependabot::DependencyFileNotResolvable) expect(error.message). - to include("version for the requirement `regex = \"=99.0.0\"`") + to include("version for the requirement `regex = \"^99.0.0\"`") end end @@ -173,7 +173,7 @@ # Test that the temporary path isn't included in the error message expect(error.message).to_not include("dependabot_20") expect(error.message). - to include("feature `namespaced-features` is required") + to include("feature `metabuild` is required") end end end @@ -232,7 +232,11 @@ let(:lockfile_fixture_name) { "blank_version" } let(:string_req) { nil } - it { is_expected.to be >= Gem::Version.new("0.2.10") } + it "raises a DependencyFileNotResolvable error" do + expect { subject }.to raise_error(Dependabot::DependencyFileNotResolvable) do |error| + expect(error.message).to include("unexpected end of input while parsing major version") + end + end end context "with an optional dependency" do @@ -242,7 +246,7 @@ let(:dependency_version) { "0.1.3" } let(:string_req) { "0.1.3" } - it { is_expected.to eq(Gem::Version.new("1.0.4")) } + it { is_expected.to eq(Gem::Version.new("1.0.5")) } end context "with a git dependency" do @@ -260,7 +264,7 @@ } end - it { is_expected.to eq("8d38a931b7e34f9da339c058cbbca6ded624ea58") } + it { is_expected.to eq("be9b8dfcaf449453cbf83ac85260ee80323f4f77") } context "with a tag" do let(:manifest_fixture_name) { "git_dependency_with_tag" } @@ -282,8 +286,8 @@ let(:manifest_fixture_name) { "git_dependency_unreachable" } let(:lockfile_fixture_name) { "git_dependency_unreachable" } let(:git_url) do - "https://github.com/greysteil/utf8-ranges.git/info/"\ - "refs?service=git-upload-pack" + "https://github.com/greysteil/utf8-ranges.git/info/" \ + "refs?service=git-upload-pack" end let(:auth_header) { "Basic eC1hY2Nlc3MtdG9rZW46dG9rZW4=" } @@ -511,7 +515,7 @@ let(:manifest) do Dependabot::DependencyFile.new( name: "../../Cargo.toml", - content: fixture("manifests", "blank_version"), + content: fixture("manifests", "default_run"), directory: "/lib/sub_crate" ) end @@ -533,5 +537,56 @@ let(:dependency_files) { unprepared_dependency_files } it { is_expected.to eq(Gem::Version.new("0.1.80")) } end + + context "when multiple packages have a version conflict with one another" do + let(:dependency_name) { "ructe" } + let(:dependency_version) { "0b8acfe5eea15713bc56c156f974fa05967d0353" } + let(:string_req) { nil } + let(:source) { { type: "git", url: "https://github.com/kaj/ructe" } } + let(:dependency_files) { project_dependency_files("version_conflict") } + let(:unprepared_dependency_files) { project_dependency_files("version_conflict") } + + specify { expect(subject).to be_nil } + end + + context "with an optional dependency" do + let(:manifest_fixture_name) { "bare_version_specified_as_optional" } + let(:unprepared_dependency_files) { [manifest] } + + it { is_expected.to be >= Gem::Version.new("0.2.10") } + end + + context "when attempting to resolve a subdependency of a path dependency" do + let(:path_dependency_manifest) do + Dependabot::DependencyFile.new( + name: "src/s3/Cargo.toml", + content: fixture("manifests", path_dependency_manifest_fixture_name) + ) + end + + let(:manifest_fixture_name) { "path_dependency" } + let(:path_dependency_manifest_fixture_name) { "cargo-registry-s3" } + + let(:unprepared_dependency_files) { [manifest, path_dependency_manifest] } + + let(:dependency_name) { "openssl" } + let(:dependency_version) { "0.10" } + let(:string_req) { "0.10" } + + it { is_expected.to be >= Gem::Version.new("0.10.41") } + + context "when the subdependency is optional" do + let(:path_dependency_manifest_fixture_name) { "cargo-registry-s3-ssl-optional" } + + it { is_expected.to be_nil } + end + + context "when the subdependency is optional but enabled by the parent" do + let(:manifest_fixture_name) { "path_dependency_feature_enabled" } + let(:path_dependency_manifest_fixture_name) { "cargo-registry-s3-ssl-optional" } + + it { is_expected.to be >= Gem::Version.new("0.10.41") } + end + end end end diff --git a/cargo/spec/dependabot/cargo/update_checker_spec.rb b/cargo/spec/dependabot/cargo/update_checker_spec.rb index e687a62d690..e10af77dd35 100644 --- a/cargo/spec/dependabot/cargo/update_checker_spec.rb +++ b/cargo/spec/dependabot/cargo/update_checker_spec.rb @@ -187,6 +187,30 @@ end end + describe "#lowest_security_fix_version" do + subject { checker.lowest_security_fix_version } + + it "finds the lowest available non-vulnerable version" do + is_expected.to eq(Gem::Version.new("0.1.39")) + end + + context "with a security vulnerability" do + let(:security_advisories) do + [ + Dependabot::SecurityAdvisory.new( + dependency_name: dependency_name, + package_manager: "cargo", + vulnerable_versions: ["<= 0.1.39"] + ) + ] + end + + it "finds the lowest available non-vulnerable version" do + is_expected.to eq(Gem::Version.new("0.1.40")) + end + end + end + describe "#latest_resolvable_version" do subject { checker.latest_resolvable_version } @@ -247,7 +271,7 @@ } end - it { is_expected.to eq("8d38a931b7e34f9da339c058cbbca6ded624ea58") } + it { is_expected.to eq("be9b8dfcaf449453cbf83ac85260ee80323f4f77") } context "with a tag" do let(:manifest_fixture_name) { "git_dependency_with_tag" } @@ -278,7 +302,7 @@ } end - it { is_expected.to eq("8d38a931b7e34f9da339c058cbbca6ded624ea58") } + it { is_expected.to eq("be9b8dfcaf449453cbf83ac85260ee80323f4f77") } end end @@ -370,7 +394,7 @@ ) end - it { is_expected.to eq("8d38a931b7e34f9da339c058cbbca6ded624ea58") } + it { is_expected.to eq("be9b8dfcaf449453cbf83ac85260ee80323f4f77") } context "with a tag" do let(:manifest_fixture_name) { "git_dependency_with_tag" } diff --git a/cargo/spec/dependabot/cargo/version_spec.rb b/cargo/spec/dependabot/cargo/version_spec.rb index 780ad28f1c5..814f3e873e6 100644 --- a/cargo/spec/dependabot/cargo/version_spec.rb +++ b/cargo/spec/dependabot/cargo/version_spec.rb @@ -30,6 +30,16 @@ it { is_expected.to eq "1.0.0-pre1+something" } end + context "with a build version with hypens" do + let(:version_string) { "0.9.0+wasi-snapshot-preview1" } + it { is_expected.to eq "0.9.0+wasi-snapshot-preview1" } + end + + context "with a build version with hypens in multiple identifiers" do + let(:version_string) { "0.9.0+wasi-snapshot1.alpha-preview" } + it { is_expected.to eq "0.9.0+wasi-snapshot1.alpha-preview" } + end + context "with a blank version" do let(:version_string) { "" } it { is_expected.to eq "" } @@ -60,4 +70,25 @@ it { is_expected.to eq(true) } end end + + describe "#correct?" do + subject { described_class.correct?(version_string) } + + valid = %w(1.0.0 1.0.0.pre1 1.0.0-pre1 1.0.0-pre1+something 0.9.0+wasi-snapshot-preview1 + 0.9.0+wasi-snapshot1.alpha-preview) + valid.each do |version| + context "with version #{version}" do + let(:version_string) { version } + it { is_expected.to eq(true) } + end + end + + invalid = %w(☃ questionmark?) + invalid.each do |version| + context "with version #{version}" do + let(:version_string) { version } + it { is_expected.to eq(false) } + end + end + end end diff --git a/cargo/spec/fixtures/github/contents_cargo_manifest_path_deps_blank.json b/cargo/spec/fixtures/github/contents_cargo_manifest_path_deps_blank.json new file mode 100644 index 00000000000..3195dd84bc8 --- /dev/null +++ b/cargo/spec/fixtures/github/contents_cargo_manifest_path_deps_blank.json @@ -0,0 +1,18 @@ +{ + "name": "Cargo.toml", + "path": "Cargo.toml", + "sha": "f64d367113fa82730ab846bff5c0775ef13e0695", + "size": 1724, + "url": "https://api.github.com/repos/khonsulabs/fabruic/contents/Cargo.toml?ref=main", + "html_url": "https://github.com/khonsulabs/fabruic/blob/main/Cargo.toml", + "git_url": "https://api.github.com/repos/khonsulabs/fabruic/git/blobs/f64d367113fa82730ab846bff5c0775ef13e0695", + "download_url": "https://raw.githubusercontent.com/khonsulabs/fabruic/main/Cargo.toml", + "type": "file", + "content": "W3BhY2thZ2VdCm5hbWUgPSAiZmFicnVpYyIKdmVyc2lvbiA9ICIwLjAuMS1k\nZXYuNSIKZGVzY3JpcHRpb24gPSAiQSBzaW1wbGUgUVVJQy1iYXNlZCBwcm90\nb2NvbCB1c2luZyBxdWlubi4gV3JpdHRlbiBmb3IgUGxpYW50REIgYW5kIENv\nc21pYyBWZXJnZS4iCmxpY2Vuc2UgPSAiTUlUIE9SIEFwYWNoZS0yLjAiCnJl\ncG9zaXRvcnkgPSAiaHR0cHM6Ly9naXRodWIuY29tL2tob25zdWxhYnMvZmFi\ncnVpYyIKa2V5d29yZHMgPSBbInF1aWMiXQpjYXRlZ29yaWVzID0gWyJuZXR3\nb3JrLXByb2dyYW1taW5nIl0KZWRpdGlvbiA9ICIyMDIxIgoKW2ZlYXR1cmVz\nXQpkYW5nZXJvdXMgPSBbXQpkZWZhdWx0ID0gWyJyY2dlbiJdCnRlc3QgPSBb\nXQp0cnVzdC1kbnMgPSBbInRydXN0LWRucy1yZXNvbHZlciJdCgpbZGVwZW5k\nZW5jaWVzXQphc3luYy10cmFpdCA9ICIwLjEiCmJpbmNvZGUgPSAiMSIKYnl0\nZXMgPSAiMSIKY3QtbG9ncyA9ICIwLjkiCmZsdW1lID0gIjAuMTAiCmZ1dHVy\nZXMtY2hhbm5lbCA9ICIwLjMiCmZ1dHVyZXMtZXhlY3V0b3IgPSAiMC4zIgpm\ndXR1cmVzLXV0aWwgPSAiMC4zIgppZl9jaGFpbiA9ICIxIgpwYXJraW5nX2xv\ndCA9IHsgdmVyc2lvbiA9ICIwLjEyIiwgZmVhdHVyZXMgPSBbInNlbmRfZ3Vh\ncmQiXSB9CnBpbi1wcm9qZWN0ID0gIjEiCnF1aW5uID0gIjAuOCIKcmNnZW4g\nPSB7IHZlcnNpb24gPSAiMC45IiwgZGVmYXVsdC1mZWF0dXJlcyA9IGZhbHNl\nLCBvcHRpb25hbCA9IHRydWUgfQpyaW5nID0gIjAuMTYiCnJ1c3RscyA9IHsg\ndmVyc2lvbiA9ICIwLjIwIiwgZGVmYXVsdC1mZWF0dXJlcyA9IGZhbHNlLCBm\nZWF0dXJlcyA9IFsKCSJkYW5nZXJvdXNfY29uZmlndXJhdGlvbiIsCl0gfQpz\nZXJkZSA9IHsgdmVyc2lvbiA9ICIxIiwgZmVhdHVyZXMgPSBbImRlcml2ZSJd\nIH0KdGhpc2Vycm9yID0gIjEiCnRpbWUgPSAiMC4zIgp0b2tpbyA9IHsgdmVy\nc2lvbiA9ICIxIiwgZmVhdHVyZXMgPSBbInJ0LW11bHRpLXRocmVhZCJdIH0K\ndHJ1c3QtZG5zLXJlc29sdmVyID0geyB2ZXJzaW9uID0gIjAuMjEuMC1hbHBo\nYS40IiwgZGVmYXVsdC1mZWF0dXJlcyA9IGZhbHNlLCBvcHRpb25hbCA9IHRy\ndWUsIGZlYXR1cmVzID0gWwoJImRucy1vdmVyLWh0dHBzLXJ1c3RscyIsCgki\nZG5zc2VjLXJpbmciLAoJInRva2lvLXJ1bnRpbWUiLApdIH0KdXJsID0gIjIi\nCndlYnBraSA9IHsgdmVyc2lvbiA9ICIwLjIyIiwgZGVmYXVsdC1mZWF0dXJl\ncyA9IGZhbHNlIH0Kd2VicGtpLXJvb3RzID0gIjAuMjIiCnJ1c3Rscy1uYXRp\ndmUtY2VydHMgPSAiMC42Igp4NTA5LXBhcnNlciA9ICIwLjEyIgp6ZXJvaXpl\nID0geyB2ZXJzaW9uID0gIjEiLCBmZWF0dXJlcyA9IFsiemVyb2l6ZV9kZXJp\ndmUiXSB9CgpbZGV2LWRlcGVuZGVuY2llc10KYW55aG93ID0gIjEiCmZhYnJ1\naWMgPSB7IHBhdGggPSAiIiwgZmVhdHVyZXMgPSBbInJjZ2VuIiwgInRlc3Qi\nXSB9CnF1aW5uLXByb3RvID0geyB2ZXJzaW9uID0gIjAuOCIsIGRlZmF1bHQt\nZmVhdHVyZXMgPSBmYWxzZSB9CnRva2lvID0geyB2ZXJzaW9uID0gIjEiLCBm\nZWF0dXJlcyA9IFsibWFjcm9zIl0gfQp0cnVzdC1kbnMtcHJvdG8gPSAiMC4y\nMS4wLWFscGhhLjQiCgpbcHJvZmlsZS5yZWxlYXNlXQpjb2RlZ2VuLXVuaXRz\nID0gMQpsdG8gPSB0cnVlCgpbcGFja2FnZS5tZXRhZGF0YS5kb2NzLnJzXQpm\nZWF0dXJlcyA9IFsiZGFuZ2Vyb3VzIiwgInJjZ2VuIiwgInRydXN0LWRucyJd\nCnRhcmdldHMgPSBbXQo=\n", + "encoding": "base64", + "_links": { + "self": "https://api.github.com/repos/khonsulabs/fabruic/contents/Cargo.toml?ref=main", + "git": "https://api.github.com/repos/khonsulabs/fabruic/git/blobs/f64d367113fa82730ab846bff5c0775ef13e0695", + "html": "https://github.com/khonsulabs/fabruic/blob/main/Cargo.toml" + } +} diff --git a/cargo/spec/fixtures/github/contents_cargo_submodule.json b/cargo/spec/fixtures/github/contents_cargo_submodule.json new file mode 100644 index 00000000000..e13d1079bf4 --- /dev/null +++ b/cargo/spec/fixtures/github/contents_cargo_submodule.json @@ -0,0 +1,17 @@ +{ + "name": "sub_crate", + "path": "lib/sub_crate", + "sha": "453df4efd57f5e8958adf17d728520bd585c82c9", + "size": 0, + "url": "https://api.github.com/repos/dsp-testing/updates-issue-2483/contents/deps/rusty_v8?ref=main", + "html_url": "https://github.com/denoland/rusty_v8/tree/453df4efd57f5e8958adf17d728520bd585c82c9", + "git_url": "https://api.github.com/repos/denoland/rusty_v8/git/trees/453df4efd57f5e8958adf17d728520bd585c82c9", + "download_url": null, + "type": "submodule", + "submodule_git_url": "git@github.com:runconduit/conduit.git", + "_links": { + "self": "https://api.github.com/repos/runconduit/conduit/contents/Cargo.toml?ref=master", + "git": "https://api.github.com/repos/runconduit/conduit/git/blobs/cb9ddc34d2c13ca51bd54ec7374d89cbad814d78", + "html": "https://github.com/runconduit/conduit/blob/master/Cargo.toml" + } +} diff --git a/cargo/spec/fixtures/lockfiles/bare_version_specified b/cargo/spec/fixtures/lockfiles/bare_version_specified index 9abb9db0e41..f5237db6059 100644 --- a/cargo/spec/fixtures/lockfiles/bare_version_specified +++ b/cargo/spec/fixtures/lockfiles/bare_version_specified @@ -5,6 +5,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +checksum = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" [[package]] name = "dependabot" @@ -22,11 +23,13 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" [[package]] name = "libc" version = "0.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" [[package]] name = "memchr" @@ -35,11 +38,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] +checksum = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" [[package]] name = "redox_syscall" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" [[package]] name = "regex" @@ -50,11 +55,13 @@ dependencies = [ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +checksum = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" [[package]] name = "regex-syntax" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" [[package]] name = "time" @@ -66,25 +73,16 @@ dependencies = [ "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +checksum = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" -"checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/blank_version b/cargo/spec/fixtures/lockfiles/blank_version index 9abb9db0e41..ec19afc37c5 100644 --- a/cargo/spec/fixtures/lockfiles/blank_version +++ b/cargo/spec/fixtures/lockfiles/blank_version @@ -76,15 +76,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" -"checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/build_version b/cargo/spec/fixtures/lockfiles/build_version index aea1d766305..77cfc2c91d9 100644 --- a/cargo/spec/fixtures/lockfiles/build_version +++ b/cargo/spec/fixtures/lockfiles/build_version @@ -75,15 +75,3 @@ dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" -"checksum blob 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "122c3fa3949d822d2a51c648db9e8105d6e75b89dc628cc366901d3d396fa4f4" -"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)" = "92ec94e2754699adddbbc4f555791bd3acc2a2f5574cba16c93a4a9cf4a04415" -"checksum zstd 0.4.19+zstd.1.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e44f036c43e506ce5651cad4f340af6b0b6d405a1c440e4a553bc422df7a81a2" -"checksum zstd-safe 1.4.4+zstd.1.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9291dbf678d18ace21725e3409d07e0a80d512feb75f5e27ac472a4948e5ddd1" -"checksum zstd-sys 1.4.4+zstd.1.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de44a435b7bb72cb779af17a72d6e9dc039dbb11a85fa2f79abf4a74dc73c013" diff --git a/cargo/spec/fixtures/lockfiles/dev_dependencies b/cargo/spec/fixtures/lockfiles/dev_dependencies index 96482c8b9ed..e11b561e8be 100644 --- a/cargo/spec/fixtures/lockfiles/dev_dependencies +++ b/cargo/spec/fixtures/lockfiles/dev_dependencies @@ -118,21 +118,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" -"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/feature_dependency b/cargo/spec/fixtures/lockfiles/feature_dependency index 5644e9fb0d4..71a9110d6a7 100644 --- a/cargo/spec/fixtures/lockfiles/feature_dependency +++ b/cargo/spec/fixtures/lockfiles/feature_dependency @@ -286,32 +286,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum atk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33a67fd81e1922dddc335887516f2f5254534e89c9d39fa89bca5d79bd150d34" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum c_vec 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6237ac5a4b1e81c213c24c6437964c61e646df910a914b4ab1487b46df20bd13" -"checksum cairo-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6b5695f59fd036fe5741bc5a4eb20c78fbe42256e3b08a2af26bbcbe8070bf3" -"checksum cairo-sys-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6e18fecaeac51809db57f45f4553cc0975225a7eb435a7a7e91e5e8113a84d" -"checksum gdk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e51db95be6565011bcd5cd99f9b17fdd585001057a999b21e09f1e8c28deb9" -"checksum gdk-pixbuf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16160d212ae91abe9f3324c3fb233929ba322dde63585d15cda3336f8c529ed1" -"checksum gdk-pixbuf-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "798f97101eea8180da363d0e80e07ec7ec6d1809306601c0100c1de5bc8b4f52" -"checksum gdk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4ee916f5f25c5f4b21bd9dcb12a216ae697406940ff9476358c308a8ececada" -"checksum gio 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84ba5a2beb559059a0c9c2bd3681743cdede8d9a36c775840bca800333b22867" -"checksum gio-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a303bbf7a5e75ab3b627117ff10e495d1b9e97e1d68966285ac2b1f6270091bc" -"checksum glib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b0452824cc63066940f01adc721804919f0b76cdba3cfab977b00b87f16d4a" -"checksum glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9693049613ff52b93013cc3d2590366d8e530366d288438724b73f6c7dc4be8" -"checksum gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60d507c87a71b1143c66ed21a969be9b99a76df234b342d733e787e6c9c7d7c2" -"checksum gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0847c507e52c1feaede13ef56fb4847742438602655449d5f1f782e8633f146f" -"checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e81c404ab81ea7ea2fc2431a0a7672507b80e4b8bf4b41eac3fc83cc665104e" -"checksum pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34f34a1be107fe16abb2744e0e206bee4b3b07460b5fddd3009a6aaf60bd69ab" -"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/feature_removed b/cargo/spec/fixtures/lockfiles/feature_removed index 5adb4e54fd5..2c90db534ba 100644 --- a/cargo/spec/fixtures/lockfiles/feature_removed +++ b/cargo/spec/fixtures/lockfiles/feature_removed @@ -339,49 +339,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" -"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" -"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" -"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873" -"checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" -"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum onig 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1271a3f93197303deda8aedcd96ed2dbb908f61c0954ae70bf7a42f536dc35d7" -"checksum onig_sys 65.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fbdee58fb75f5b7749ebc8f601f570961eed595dfe4c2bb9a542e2f7ae20b946" -"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503" -"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" -"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" -"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645" -"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f" -"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce" -"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74" -"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" -"checksum syntect 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ff5898205c88327ab1c99dfd25337e9f29e547e0596a5b098a6780a43801e3c5" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency b/cargo/spec/fixtures/lockfiles/git_dependency index b47a9d6ad21..b204b91a009 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency +++ b/cargo/spec/fixtures/lockfiles/git_dependency @@ -49,12 +49,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" -"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" -"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" -"checksum utf8-ranges 1.0.0 (git+https://github.com/BurntSushi/utf8-ranges)" = "" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_ssh b/cargo/spec/fixtures/lockfiles/git_dependency_ssh index 5395954667e..7b1896420ce 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_ssh +++ b/cargo/spec/fixtures/lockfiles/git_dependency_ssh @@ -18,7 +18,3 @@ source = "git+ssh://git@github.com/dependabot-fixtures/utf8-ranges#9996043f61e9b dependencies = [ "utf8-ranges 1.0.0 (git+ssh://git@github.com/BurntSushi/utf8-ranges)", ] - -[metadata] -"checksum utf8-ranges 1.0.0 (git+ssh://git@github.com/BurntSushi/utf8-ranges)" = "" -"checksum utf8-ranges-parent 1.0.2 (git+ssh://git@github.com/dependabot-fixtures/utf8-ranges)" = "" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_unfetchable_ref b/cargo/spec/fixtures/lockfiles/git_dependency_unfetchable_ref index 4c5106734ac..29df5a6a491 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_unfetchable_ref +++ b/cargo/spec/fixtures/lockfiles/git_dependency_unfetchable_ref @@ -49,12 +49,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" -"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum utf8-ranges 1.0.0 (git+https://github.com/BurntSushi/utf8-ranges)" = "" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_unreachable b/cargo/spec/fixtures/lockfiles/git_dependency_unreachable index 09ce7118d74..cdf2c26017c 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_unreachable +++ b/cargo/spec/fixtures/lockfiles/git_dependency_unreachable @@ -49,12 +49,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" -"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" -"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" -"checksum utf8-ranges 1.0.0 (git+https://github.com/greysteil/utf8-ranges)" = "" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_update_blocked b/cargo/spec/fixtures/lockfiles/git_dependency_update_blocked index 4dd66280fad..8c3b1abdacd 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_update_blocked +++ b/cargo/spec/fixtures/lockfiles/git_dependency_update_blocked @@ -1389,173 +1389,3 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" -"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" -"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" -"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" -"checksum cc 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d9324127e719125ec8a16e6e509abc4c641e773621b50aea695af3f005656d61" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" -"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" -"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" -"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" -"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum elasticlunr-rs 2.0.0 (git+https://github.com/mattico/elasticlunr-rs)" = "" -"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad" -"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" -"checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05" -"checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" -"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" -"checksum handlebars 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07af2ff31f66f39a5c8b8b8a5dc02734a453110146763e3a2323f4931a915a76" -"checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" -"checksum html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e579ac8647178ab915d400d7d22938bda5cd351c6c62e1c294d56884ccfc75fe" -"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" -"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8e17268922834707e1c29e8badbf9c712c9c43378e1b6a3388946baff10be2" -"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" -"checksum itertools 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "23d53b4c7394338044c3b9c8c5b2caaf7b40ae049ecd321578ebdc2e13738cd1" -"checksum itoa 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92a9df60778f789c37f76778ae8d0a2471c41baa8b059d98a5873c978f549587" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" -"checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" -"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime_guess 1.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b7e2b09d08313f84e0fb82d13a4d859109a17543fe9af3b6d941dc1431f7de79" -"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" -"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" -"checksum mount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e25c06012941aaf8c75f2eaf7ec5c48cf69f9fc489ab3eb3589edc107e386f0b" -"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" -"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" -"checksum notify 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5c3812da3098f210a0bb440f9c008471a031aa4c1de07a264fdd75456c95a4eb" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" -"checksum pest_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6453faedc5c9980a3c278f28b1df33344a79cc6d4a2fd96e2b56288374dc822a" -"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" -"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" -"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" -"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" -"checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" -"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" -"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" -"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" -"checksum pulldown-cmark-to-cmark 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57efca5f52f63336ee3a49bceee1a1169f18ef01c75aa7e71949441b49bbe7e4" -"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756" -"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24" -"checksum rust-stemmers 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbf06149ec391025664a5634200ced1afb489f0f3f8a140d515ebc0eb04b4bc0" -"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" -"checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" -"checksum sequence_trie 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "32157204e5c9d3c04007bd7e56e96e987635ce0e8e23c085b1e403861b76c351" -"checksum serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe95aa0d46f04ce5c3a88bdcd4114ecd6144ed0b2725ebca2f1127744357807" -"checksum serde_derive 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "23b163a6ce7e1aa897919f9d8e40bd1f8a6f95342ed57727ae31387a01a7a356" -"checksum serde_derive_internals 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "370aa477297975243dc914d0b0e1234927520ec311de507a560fbd1c80f7ab8c" -"checksum serde_json 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "28556329a1d04efa036376c9588a0ed8655e202676d918733ca8a14740ee31be" -"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" -"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" -"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum staticfile 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "babd3fa68bb7e3994ce181c5f21ff3ff5fffef7b18b8a10163b45e4dafc6fb86" -"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" -"checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12" -"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" -"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "099e21b5dd6dd07b5adcf8c4b723a7c0b7efd7a9359bf963d58c0caae8532545" -"checksum strum_macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd9bd569e88028750e3ae5c25616b8278ac16a8e61aba4339195c72396d49e1" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99" -"checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" -"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" -"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" -"checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" -"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" -"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" -"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" -"checksum ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89c48c53bf9dee34411a08993c10b879c36e105d609b46e25673befe3a5c1320" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_with_tag b/cargo/spec/fixtures/lockfiles/git_dependency_with_tag index 3f38815481d..046152615c1 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_with_tag +++ b/cargo/spec/fixtures/lockfiles/git_dependency_with_tag @@ -9,6 +9,3 @@ dependencies = [ name = "utf8-ranges" version = "0.1.3" source = "git+https://github.com/BurntSushi/utf8-ranges?tag=0.1.3#d5094c7e9456f2965dec20de671094a98c6929c2" - -[metadata] -"checksum utf8-ranges 0.1.3 (git+https://github.com/BurntSushi/utf8-ranges?tag=0.1.3)" = "" diff --git a/cargo/spec/fixtures/lockfiles/git_dependency_with_unreachable_branch b/cargo/spec/fixtures/lockfiles/git_dependency_with_unreachable_branch index 1a279780b63..08b7fff4c52 100644 --- a/cargo/spec/fixtures/lockfiles/git_dependency_with_unreachable_branch +++ b/cargo/spec/fixtures/lockfiles/git_dependency_with_unreachable_branch @@ -9,6 +9,3 @@ dependencies = [ name = "utf8-ranges" version = "0.1.3" source = "git+https://github.com/BurntSushi/utf8-ranges?branch=no_exist#d5094c7e9456f2965dec20de671094a98c6929c2" - -[metadata] -"checksum utf8-ranges 0.1.3 (git+https://github.com/BurntSushi/utf8-ranges?branch=no_exist)" = "" diff --git a/cargo/spec/fixtures/lockfiles/git_subdependency b/cargo/spec/fixtures/lockfiles/git_subdependency index f16e0b524cf..9ba9ffaa8e0 100644 --- a/cargo/spec/fixtures/lockfiles/git_subdependency +++ b/cargo/spec/fixtures/lockfiles/git_subdependency @@ -167,25 +167,3 @@ dependencies = [ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" -"checksum cranelift 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-bforest 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-codegen 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-codegen-meta 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-entity 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum cranelift-frontend 0.23.0 (git+https://github.com/CraneStation/cranelift.git)" = "" -"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" -"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" -"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" -"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" -"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" -"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/cargo/spec/fixtures/lockfiles/mdBook b/cargo/spec/fixtures/lockfiles/mdBook index 874237cf63f..33fae6a329a 100644 --- a/cargo/spec/fixtures/lockfiles/mdBook +++ b/cargo/spec/fixtures/lockfiles/mdBook @@ -1389,173 +1389,3 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" -"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" -"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" -"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" -"checksum cc 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d9324127e719125ec8a16e6e509abc4c641e773621b50aea695af3f005656d61" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" -"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" -"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" -"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" -"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum elasticlunr-rs 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c5413e83a7be7e86ce0afce03b23508db56082edbb2b28a178e6275fa3957d" -"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad" -"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" -"checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05" -"checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" -"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" -"checksum handlebars 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07af2ff31f66f39a5c8b8b8a5dc02734a453110146763e3a2323f4931a915a76" -"checksum html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a49d5001dd1bddf042ea41ed4e0a671d50b1bf187e66b349d7ec613bdce4ad90" -"checksum html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e579ac8647178ab915d400d7d22938bda5cd351c6c62e1c294d56884ccfc75fe" -"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" -"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8e17268922834707e1c29e8badbf9c712c9c43378e1b6a3388946baff10be2" -"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" -"checksum itertools 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "23d53b4c7394338044c3b9c8c5b2caaf7b40ae049ecd321578ebdc2e13738cd1" -"checksum itoa 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92a9df60778f789c37f76778ae8d0a2471c41baa8b059d98a5873c978f549587" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" -"checksum markup5ever 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff834ac7123c6a37826747e5ca09db41fd7a83126792021c2e636ad174bb77d3" -"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime_guess 1.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b7e2b09d08313f84e0fb82d13a4d859109a17543fe9af3b6d941dc1431f7de79" -"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" -"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" -"checksum mount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e25c06012941aaf8c75f2eaf7ec5c48cf69f9fc489ab3eb3589edc107e386f0b" -"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" -"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" -"checksum notify 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5c3812da3098f210a0bb440f9c008471a031aa4c1de07a264fdd75456c95a4eb" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" -"checksum pest_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6453faedc5c9980a3c278f28b1df33344a79cc6d4a2fd96e2b56288374dc822a" -"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" -"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" -"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" -"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" -"checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" -"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" -"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" -"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" -"checksum pulldown-cmark-to-cmark 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57efca5f52f63336ee3a49bceee1a1169f18ef01c75aa7e71949441b49bbe7e4" -"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756" -"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24" -"checksum rust-stemmers 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbf06149ec391025664a5634200ced1afb489f0f3f8a140d515ebc0eb04b4bc0" -"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" -"checksum select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7004292887d0a030e29abda3ae1b63a577c96a17e25d74eaa1952503e6c1c946" -"checksum sequence_trie 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "32157204e5c9d3c04007bd7e56e96e987635ce0e8e23c085b1e403861b76c351" -"checksum serde 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe95aa0d46f04ce5c3a88bdcd4114ecd6144ed0b2725ebca2f1127744357807" -"checksum serde_derive 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "23b163a6ce7e1aa897919f9d8e40bd1f8a6f95342ed57727ae31387a01a7a356" -"checksum serde_derive_internals 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "370aa477297975243dc914d0b0e1234927520ec311de507a560fbd1c80f7ab8c" -"checksum serde_json 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "28556329a1d04efa036376c9588a0ed8655e202676d918733ca8a14740ee31be" -"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" -"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" -"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum staticfile 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "babd3fa68bb7e3994ce181c5f21ff3ff5fffef7b18b8a10163b45e4dafc6fb86" -"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" -"checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12" -"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" -"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "099e21b5dd6dd07b5adcf8c4b723a7c0b7efd7a9359bf963d58c0caae8532545" -"checksum strum_macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd9bd569e88028750e3ae5c25616b8278ac16a8e61aba4339195c72396d49e1" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99" -"checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" -"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" -"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" -"checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" -"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" -"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" -"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" -"checksum ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89c48c53bf9dee34411a08993c10b879c36e105d609b46e25673befe3a5c1320" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/cargo/spec/fixtures/lockfiles/missing_dependency b/cargo/spec/fixtures/lockfiles/missing_dependency index c4afd043bb9..eb5e9f6eea6 100644 --- a/cargo/spec/fixtures/lockfiles/missing_dependency +++ b/cargo/spec/fixtures/lockfiles/missing_dependency @@ -68,14 +68,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" -"checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/missing_version b/cargo/spec/fixtures/lockfiles/missing_version index 0bd5d1a32a5..9f994944c6d 100644 --- a/cargo/spec/fixtures/lockfiles/missing_version +++ b/cargo/spec/fixtures/lockfiles/missing_version @@ -76,15 +76,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 99.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" -"checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/multiple_versions b/cargo/spec/fixtures/lockfiles/multiple_versions index c87232a3402..a6c5dc2fe6d 100644 --- a/cargo/spec/fixtures/lockfiles/multiple_versions +++ b/cargo/spec/fixtures/lockfiles/multiple_versions @@ -213,33 +213,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873" -"checksum email 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0809dd991afe3cc925063fa1c44cd57e5ed92d06d93f92661a53b79f5e44d4de" -"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" -"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" -"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" -"checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" -"checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" -"checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" -"checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5f78082e6a6d042862611e9640cf20776185fee506cf6cf67e93c6225cee31" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/multiple_versions_git b/cargo/spec/fixtures/lockfiles/multiple_versions_git index 1a19f29d4ec..c1d9599330f 100644 --- a/cargo/spec/fixtures/lockfiles/multiple_versions_git +++ b/cargo/spec/fixtures/lockfiles/multiple_versions_git @@ -222,34 +222,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873" -"checksum email 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0809dd991afe3cc925063fa1c44cd57e5ed92d06d93f92661a53b79f5e44d4de" -"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" -"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" -"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" -"checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" -"checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" -"checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" -"checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5f78082e6a6d042862611e9640cf20776185fee506cf6cf67e93c6225cee31" -"checksum rand 0.4.2 (git+https://github.com/rust-random/rand?rev=31465bbbd7fa0382d3ce745e021ada681f090784" = "" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/multiple_versions_subdependency b/cargo/spec/fixtures/lockfiles/multiple_versions_subdependency index 9854c95b5f1..f2a093e4db4 100644 --- a/cargo/spec/fixtures/lockfiles/multiple_versions_subdependency +++ b/cargo/spec/fixtures/lockfiles/multiple_versions_subdependency @@ -1051,129 +1051,3 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum bugsnag 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20015af8027d22db67e2c84f8b9f2c31b1efa0ec554d8b210c77acb7065d69bf" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" -"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" -"checksum cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8b9d2900f78631a5876dc5d6c9033ede027253efcd33dd36b1309fc6cab97ee0" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" -"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" -"checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" -"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" -"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" -"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)" = "549dbb86397490ce69d908425b9beebc85bbaad25157d67479d4995bb56fdf9a" -"checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" -"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" -"checksum mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130ea3c9c1b65dba905ab5a4d9ac59234a9585c24d135f264e187fe7336febbd" -"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" -"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)" = "0bbd90640b148b46305c1691eed6039b5c8509bed16991e3562a01eeb76902a3" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" -"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" -"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" -"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" -"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" -"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" -"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24" -"checksum reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "241faa9a8ca28a03cbbb9815a5d085f271d4c0168a19181f106aa93240c22ddb" -"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" -"checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" -"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "4c36359ac1a823e00db02a243376ced650f088dc1f6259bbf828e4668e3c7399" -"checksum serde_derive 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "f0477feff739386f5bca8e13fa43d96a4e834904d538f503906c8179f9205f50" -"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794" -"checksum serde_json 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8f6f1f77b969caa064f347544d703efacaf4854b84831096a5dc206a8aedbc27" -"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" -"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" -"checksum sys-info 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "617f594d3869801871433390254b4a79f2a18176d7f4ad5784fa990bc8c12986" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" -"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" -"checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" -"checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" -"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -"checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" -"checksum tokio-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" -"checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" -"checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" -"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" -"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" -"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" -"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/cargo/spec/fixtures/lockfiles/old_lockfile b/cargo/spec/fixtures/lockfiles/old_lockfile new file mode 100644 index 00000000000..9abb9db0e41 --- /dev/null +++ b/cargo/spec/fixtures/lockfiles/old_lockfile @@ -0,0 +1,90 @@ +[[package]] +name = "aho-corasick" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dependabot" +version = "0.1.0" +dependencies = [ + "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "time" +version = "0.1.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5314d38125dc9b9ca99ed19a516eb19feac7bf8b22b5b32993c971bf8cb2a4d" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" +"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "4499ef755e709fbfe334ecbc3206537e84952ead5347791b0f54c2b75fe63a28" +"checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" +"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/optional_dependency b/cargo/spec/fixtures/lockfiles/optional_dependency index e13fa750d48..69ab4fba074 100644 --- a/cargo/spec/fixtures/lockfiles/optional_dependency +++ b/cargo/spec/fixtures/lockfiles/optional_dependency @@ -9,6 +9,3 @@ dependencies = [ name = "utf8-ranges" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" diff --git a/cargo/spec/fixtures/lockfiles/path_dependency b/cargo/spec/fixtures/lockfiles/path_dependency index 4ecc9cb7773..0f82cd6a536 100644 --- a/cargo/spec/fixtures/lockfiles/path_dependency +++ b/cargo/spec/fixtures/lockfiles/path_dependency @@ -294,42 +294,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b38494a0e560c04f5a05d0fde029419511937ce4054af58e9945a6db9b547d75" -"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b70fd6394677d3c0e239ff4be6f2b3176e171ffd1c23ffdc541e78dea2b8bb5e" -"checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1636c9f1d78af9cbcc50e523bfff4a30274108aad5e86761afd4d31e4e184fa7" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9" -"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "bc2a4457b0c25dae6fee3dcd631ccded31e97d689b892c26554e096aa08dd136" -"checksum regex-syntax 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa7523743a36e7aff26042364f7695ab6a4eb318f7a0e95a57ffe130e9321fbb" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" -"checksum socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "71ebbe82fcdd697244ba7fe6e05e63b5c45910c3927e28469a04947494ff48d8" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/cargo/spec/fixtures/lockfiles/target_dependency b/cargo/spec/fixtures/lockfiles/target_dependency index 1782c544809..9162661c165 100644 --- a/cargo/spec/fixtures/lockfiles/target_dependency +++ b/cargo/spec/fixtures/lockfiles/target_dependency @@ -97,18 +97,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" -"checksum gcc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "08fa0b80a2193b08b8d38acb18d0cdb9ff00a287389bb59e685d907d1b4bf072" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" -"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" -"checksum time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "615f31b68e20d17a912d0a91a398b9bd2ee7eb7c5b02d8c67589b898bbb38216" -"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/cargo/spec/fixtures/lockfiles/virtual_workspace b/cargo/spec/fixtures/lockfiles/virtual_workspace index 28a48542a8e..2087373ec35 100644 --- a/cargo/spec/fixtures/lockfiles/virtual_workspace +++ b/cargo/spec/fixtures/lockfiles/virtual_workspace @@ -31,7 +31,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" diff --git a/cargo/spec/fixtures/lockfiles/virtual_workspace_old_format b/cargo/spec/fixtures/lockfiles/virtual_workspace_old_format index 10e2d95c1cb..a4fbc5cc312 100644 --- a/cargo/spec/fixtures/lockfiles/virtual_workspace_old_format +++ b/cargo/spec/fixtures/lockfiles/virtual_workspace_old_format @@ -31,7 +31,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] - -[metadata] -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" diff --git a/cargo/spec/fixtures/lockfiles/workspace b/cargo/spec/fixtures/lockfiles/workspace index d539eb71436..1f0b8d3a539 100644 --- a/cargo/spec/fixtures/lockfiles/workspace +++ b/cargo/spec/fixtures/lockfiles/workspace @@ -102,18 +102,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/cargo/spec/fixtures/lockfiles/workspace_dependencies b/cargo/spec/fixtures/lockfiles/workspace_dependencies new file mode 100644 index 00000000000..ba4f1cb66bd --- /dev/null +++ b/cargo/spec/fixtures/lockfiles/workspace_dependencies @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "inherit_ws_dep" +version = "0.1.0" +dependencies = [ + "log", +] + +[[package]] +name = "log" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" +dependencies = [ + "cfg-if", +] diff --git a/cargo/spec/fixtures/lockfiles/workspace_with_patch b/cargo/spec/fixtures/lockfiles/workspace_with_patch index 3e1d4b311fe..9f70451dc6f 100644 --- a/cargo/spec/fixtures/lockfiles/workspace_with_patch +++ b/cargo/spec/fixtures/lockfiles/workspace_with_patch @@ -107,18 +107,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "log" version = "0.4.1" source = "git+https://github.com/rust-lang-nursery/log#08d0e4169d9107f0aaae885faeb09015706c95f2" - -[metadata] -"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/cargo/spec/fixtures/manifests/bare_version_specified_as_optional b/cargo/spec/fixtures/manifests/bare_version_specified_as_optional new file mode 100644 index 00000000000..88fe08806e6 --- /dev/null +++ b/cargo/spec/fixtures/manifests/bare_version_specified_as_optional @@ -0,0 +1,8 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] +time = "0.1.12" +regex = { version = "0.1.41", optional = true } diff --git a/cargo/spec/fixtures/manifests/cargo-registry-s3-ssl-optional b/cargo/spec/fixtures/manifests/cargo-registry-s3-ssl-optional new file mode 100644 index 00000000000..ddfefe8b88f --- /dev/null +++ b/cargo/spec/fixtures/manifests/cargo-registry-s3-ssl-optional @@ -0,0 +1,25 @@ + +[package] + +name = "cargo-registry-s3" +version = "0.2.0" +authors = ["Alex Crichton "] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/crates.io" +description = "Interaction between crates.io and S3 for storing crate files" + +[lib] + +name = "s3" +path = "lib.rs" + +[features] +default = ["not_safe"] +safe = ["openssl"] +not_safe = [] + +[dependencies] +chrono = "0.4" +curl = "0.4" +base64 = "0.9" +openssl = { version = "0.10", optional = true } diff --git a/cargo/spec/fixtures/manifests/disabled_feature b/cargo/spec/fixtures/manifests/disabled_feature index 4d04d26fd43..d9754284340 100644 --- a/cargo/spec/fixtures/manifests/disabled_feature +++ b/cargo/spec/fixtures/manifests/disabled_feature @@ -2,7 +2,7 @@ name = "dependabot" # the name of the package version = "0.1.0" # the current version, obeying semver authors = ["support@dependabot.com"] -namespaced-features = true +metabuild = ["foo", "bar"] [dependencies] time = "0.1.12" diff --git a/cargo/spec/fixtures/manifests/dotted_key_version b/cargo/spec/fixtures/manifests/dotted_key_version new file mode 100644 index 00000000000..5735fd12974 --- /dev/null +++ b/cargo/spec/fixtures/manifests/dotted_key_version @@ -0,0 +1,7 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] +time.version = "0.1.12" diff --git a/cargo/spec/fixtures/manifests/old_lockfile b/cargo/spec/fixtures/manifests/old_lockfile new file mode 100644 index 00000000000..945aff320fc --- /dev/null +++ b/cargo/spec/fixtures/manifests/old_lockfile @@ -0,0 +1,8 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] +time = "0.1.12" +regex = "0.1.41" diff --git a/cargo/spec/fixtures/manifests/path_dependency_feature_enabled b/cargo/spec/fixtures/manifests/path_dependency_feature_enabled new file mode 100644 index 00000000000..6b29f694c10 --- /dev/null +++ b/cargo/spec/fixtures/manifests/path_dependency_feature_enabled @@ -0,0 +1,8 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] +cargo-registry-s3 = { path = "src/s3", version = "0.2.0", features = ["safe"] } +regex = "=0.1.38" diff --git a/cargo/spec/fixtures/manifests/requires_nightly b/cargo/spec/fixtures/manifests/requires_nightly index 0cfaecc7ef4..014aba62dfe 100644 --- a/cargo/spec/fixtures/manifests/requires_nightly +++ b/cargo/spec/fixtures/manifests/requires_nightly @@ -1,10 +1,10 @@ -cargo-features = ["namespaced-features"] +cargo-features = ["metabuild"] [package] name = "dependabot" # the name of the package version = "0.1.0" # the current version, obeying semver authors = ["support@dependabot.com"] -namespaced-features = true +metabuild = ["foo", "bar"] [dependencies] time = "0.1.12" diff --git a/cargo/spec/fixtures/manifests/resolver2 b/cargo/spec/fixtures/manifests/resolver2 new file mode 100644 index 00000000000..0bb6ac85d65 --- /dev/null +++ b/cargo/spec/fixtures/manifests/resolver2 @@ -0,0 +1,5 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] +resolver = "2" diff --git a/cargo/spec/fixtures/manifests/version_in_name b/cargo/spec/fixtures/manifests/version_in_name new file mode 100644 index 00000000000..6e0580787b3 --- /dev/null +++ b/cargo/spec/fixtures/manifests/version_in_name @@ -0,0 +1,7 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] +curve25519-dalek = "2" diff --git a/cargo/spec/fixtures/manifests/version_requirement b/cargo/spec/fixtures/manifests/version_requirement new file mode 100644 index 00000000000..69f4eda6def --- /dev/null +++ b/cargo/spec/fixtures/manifests/version_requirement @@ -0,0 +1,8 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] +default-run = "viewer" + +[dependencies] +time = "^0.1.38" diff --git a/cargo/spec/fixtures/manifests/whitespace_names b/cargo/spec/fixtures/manifests/whitespace_names new file mode 100644 index 00000000000..2a50757cd98 --- /dev/null +++ b/cargo/spec/fixtures/manifests/whitespace_names @@ -0,0 +1,9 @@ +[package] +name = "dependabot" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["support@dependabot.com"] + +[dependencies] + time = "0.1.12" + regex = "0.1.41" +business_time = "0.1.12" diff --git a/cargo/spec/fixtures/manifests/workspace_dependencies_child b/cargo/spec/fixtures/manifests/workspace_dependencies_child new file mode 100644 index 00000000000..a2247042cc5 --- /dev/null +++ b/cargo/spec/fixtures/manifests/workspace_dependencies_child @@ -0,0 +1,8 @@ +[package] +name = "inherit_ws_dep" +version = "0.1.0" +edition = "2021" +workspace = "../.." + +[dependencies] +log.workspace = true diff --git a/cargo/spec/fixtures/manifests/workspace_dependencies_root b/cargo/spec/fixtures/manifests/workspace_dependencies_root new file mode 100644 index 00000000000..5a16d94bd12 --- /dev/null +++ b/cargo/spec/fixtures/manifests/workspace_dependencies_root @@ -0,0 +1,5 @@ +[workspace] +members = ["lib/inherit_ws_dep"] + +[workspace.dependencies] +log = "=0.4.0" diff --git a/cargo/spec/fixtures/projects/version_conflict/Cargo.lock b/cargo/spec/fixtures/projects/version_conflict/Cargo.lock new file mode 100644 index 00000000000..c3f17b0faa4 --- /dev/null +++ b/cargo/spec/fixtures/projects/version_conflict/Cargo.lock @@ -0,0 +1,290 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "askama" +version = "0.10.5" +source = "git+https://github.com/djc/askama?branch=main#bc2e92e7d64a2987647f8702c4e5680acef03943" +dependencies = [ + "askama_derive", + "askama_escape", + "askama_shared", +] + +[[package]] +name = "askama_derive" +version = "0.10.5" +source = "git+https://github.com/djc/askama?branch=main#bc2e92e7d64a2987647f8702c4e5680acef03943" +dependencies = [ + "askama_shared", + "proc-macro2", + "syn", +] + +[[package]] +name = "askama_escape" +version = "0.10.1" +source = "git+https://github.com/djc/askama?branch=main#bc2e92e7d64a2987647f8702c4e5680acef03943" + +[[package]] +name = "askama_shared" +version = "0.11.1" +source = "git+https://github.com/djc/askama?branch=main#bc2e92e7d64a2987647f8702c4e5680acef03943" +dependencies = [ + "askama_escape", + "humansize", + "nom 6.0.1", + "num-traits", + "percent-encoding", + "proc-macro2", + "quote", + "serde", + "syn", + "toml", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitvec" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "bytecount" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "funty" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" + +[[package]] +name = "humansize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "lexical-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" +dependencies = [ + "arrayvec", + "bitflags", + "cfg-if 0.1.10", + "ryu", + "static_assertions", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "nom" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0" +dependencies = [ + "bitvec", + "memchr", + "version_check", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "ructe" +version = "0.13.1-PRE" +source = "git+https://github.com/kaj/ructe#0b8acfe5eea15713bc56c156f974fa05967d0353" +dependencies = [ + "base64", + "bytecount", + "itertools", + "md5", + "nom 5.1.2", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" + + +[[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "version_conflict" +version = "0.1.0" +dependencies = [ + "askama", + "ructe", +] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" diff --git a/cargo/spec/fixtures/projects/version_conflict/Cargo.toml b/cargo/spec/fixtures/projects/version_conflict/Cargo.toml new file mode 100644 index 00000000000..a06eb3da5ec --- /dev/null +++ b/cargo/spec/fixtures/projects/version_conflict/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "version_conflict" +version = "0.1.0" +authors = ["support@dependabot.com"] + +[dependencies] +askama = { git = "https://github.com/djc/askama", rev = "d45e106bf219d6da94538e2816472ca8026500ba" } + +[build-dependencies] +ructe = { git = "https://github.com/kaj/ructe" } diff --git a/cargo/spec/fixtures/projects/version_conflict/src/main.rs b/cargo/spec/fixtures/projects/version_conflict/src/main.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/common/.gitignore b/common/.gitignore index 15ae26ea05f..06845bd78c0 100644 --- a/common/.gitignore +++ b/common/.gitignore @@ -3,4 +3,3 @@ /tmp /dependabot-*.gem Gemfile.lock -.byebug_history diff --git a/common/.rubocop.yml b/common/.rubocop.yml new file mode 100644 index 00000000000..fc2019d46a3 --- /dev/null +++ b/common/.rubocop.yml @@ -0,0 +1 @@ +inherit_from: ../.rubocop.yml diff --git a/common/dependabot-common.gemspec b/common/dependabot-common.gemspec index 33c680bc6f2..4ff2ec0896b 100644 --- a/common/dependabot-common.gemspec +++ b/common/dependabot-common.gemspec @@ -1,13 +1,12 @@ # frozen_string_literal: true -require "find" require "./lib/dependabot/version" Gem::Specification.new do |spec| spec.name = "dependabot-common" spec.version = Dependabot::VERSION spec.summary = "Shared code used between Dependabot package managers" - spec.description = "Automated dependency management for Ruby, JavaScript, "\ + spec.description = "Automated dependency management for Ruby, JavaScript, " \ "Python, PHP, Elixir, Rust, Java, .NET, Elm and Go" spec.author = "Dependabot" @@ -18,44 +17,39 @@ Gem::Specification.new do |spec| spec.require_path = "lib" spec.files = [] - spec.required_ruby_version = ">= 2.5.0" - spec.required_rubygems_version = ">= 2.7.3" + spec.required_ruby_version = ">= 3.1.0" + spec.required_rubygems_version = ">= 3.3.7" + spec.add_dependency "activesupport", ">= 6.0.0" spec.add_dependency "aws-sdk-codecommit", "~> 1.28" spec.add_dependency "aws-sdk-ecr", "~> 1.5" spec.add_dependency "bundler", ">= 1.16", "< 3.0.0" - spec.add_dependency "commonmarker", ">= 0.20.1", "< 0.22.0" - spec.add_dependency "docker_registry2", "~> 1.7", ">= 1.7.1" - spec.add_dependency "excon", "~> 0.75" - spec.add_dependency "gitlab", "4.16.1" + spec.add_dependency "commonmarker", ">= 0.20.1", "< 0.24.0" + spec.add_dependency "docker_registry2", "~> 1.11", ">= 1.11.0" + spec.add_dependency "excon", "~> 0.75", "< 0.94" + spec.add_dependency "faraday", "2.6.0" + spec.add_dependency "faraday-retry", "2.0.0" + spec.add_dependency "gitlab", "4.19.0" spec.add_dependency "nokogiri", "~> 1.8" - spec.add_dependency "octokit", "~> 4.6" - spec.add_dependency "pandoc-ruby", "~> 2.0" - spec.add_dependency "parseconfig", "~> 1.0" - spec.add_dependency "parser", "~> 2.5" + spec.add_dependency "octokit", ">= 4.6", "< 7.0" + spec.add_dependency "parser", ">= 2.5", "< 4.0" spec.add_dependency "toml-rb", ">= 1.1.2", "< 3.0" - spec.add_development_dependency "byebug", "~> 11.0" + spec.add_development_dependency "debug", ">= 1.0.0" spec.add_development_dependency "gpgme", "~> 2.0" + spec.add_development_dependency "parallel_tests", "~> 4.0.0" spec.add_development_dependency "rake", "~> 13" spec.add_development_dependency "rspec", "~> 3.8" spec.add_development_dependency "rspec-its", "~> 1.2" - spec.add_development_dependency "rspec_junit_formatter", "~> 0.4" - spec.add_development_dependency "rubocop", "~> 0.88.0" - spec.add_development_dependency "vcr", "6.0.0" + spec.add_development_dependency "rubocop", "~> 1.39.0" + spec.add_development_dependency "rubocop-performance", "~> 1.15.0" + spec.add_development_dependency "simplecov", "~> 0.21.0" + spec.add_development_dependency "simplecov-console", "~> 0.9.1" + spec.add_development_dependency "stackprof", "~> 0.2.16" + spec.add_development_dependency "vcr", "6.1.0" spec.add_development_dependency "webmock", "~> 3.4" next unless File.exist?("../.gitignore") - ignores = File.readlines("../.gitignore").grep(/\S+/).map(&:chomp) - - next unless File.directory?("lib") - - Find.find("lib", "bin") do |path| - if ignores.any? { |i| File.fnmatch(i, "/" + path, File::FNM_DOTMATCH) } - Find.prune - else - spec.files << path unless File.directory?(path) - end - end + spec.files += `git -C #{__dir__} ls-files lib bin -z`.split("\x0") end diff --git a/common/lib/dependabot/clients/azure.rb b/common/lib/dependabot/clients/azure.rb index 01235327661..0e512a99851 100644 --- a/common/lib/dependabot/clients/azure.rb +++ b/common/lib/dependabot/clients/azure.rb @@ -8,6 +8,22 @@ module Clients class Azure class NotFound < StandardError; end + class InternalServerError < StandardError; end + + class ServiceNotAvailable < StandardError; end + + class BadGateway < StandardError; end + + class Unauthorized < StandardError; end + + class Forbidden < StandardError; end + + class TagsCreationForbidden < StandardError; end + + RETRYABLE_ERRORS = [InternalServerError, BadGateway, ServiceNotAvailable].freeze + + MAX_PR_DESCRIPTION_LENGTH = 3999 + ####################### # Constructor methods # ####################### @@ -25,9 +41,11 @@ def self.for_source(source:, credentials:) # Client # ########## - def initialize(source, credentials) + def initialize(source, credentials, max_retries: 3) @source = source @credentials = credentials + @auth_header = auth_header_for(credentials&.fetch("token", nil)) + @max_retries = max_retries || 3 end def fetch_commit(_repo, branch) @@ -36,6 +54,8 @@ def fetch_commit(_repo, branch) "/_apis/git/repositories/" + source.unscoped_repo + "/stats/branches?name=" + branch) + raise NotFound if response.status == 400 + JSON.parse(response.body).fetch("commit").fetch("commitId") end @@ -94,9 +114,7 @@ def commits(branch_name = nil) "/_apis/git/repositories/" + source.unscoped_repo + "/commits" - unless branch_name.to_s.empty? - commits_url += "?searchCriteria.itemVersion.version=" + branch_name - end + commits_url += "?searchCriteria.itemVersion.version=" + branch_name unless branch_name.to_s.empty? response = get(commits_url) @@ -152,23 +170,20 @@ def create_commit(branch_name, base_commit, commit_message, files, "/pushes?api-version=5.0", content.to_json) end + # rubocop:disable Metrics/ParameterLists def create_pull_request(pr_name, source_branch, target_branch, - pr_description, labels) - # Azure DevOps only support descriptions up to 4000 characters - # https://developercommunity.visualstudio.com/content/problem/608770/remove-4000-character-limit-on-pull-request-descri.html - azure_max_length = 3999 - if pr_description.length > azure_max_length - truncated_msg = "...\n\n_Description has been truncated_" - truncate_length = azure_max_length - truncated_msg.length - pr_description = pr_description[0..truncate_length] + truncated_msg - end + pr_description, labels, + reviewers = nil, assignees = nil, work_item = nil) + pr_description = truncate_pr_description(pr_description) content = { sourceRefName: "refs/heads/" + source_branch, targetRefName: "refs/heads/" + target_branch, title: pr_name, description: pr_description, - labels: labels.map { |label| { name: label } } + labels: labels.map { |label| { name: label } }, + reviewers: pr_reviewers(reviewers, assignees), + workItemRefs: [{ id: work_item }] } post(source.api_endpoint + @@ -177,31 +192,88 @@ def create_pull_request(pr_name, source_branch, target_branch, "/pullrequests?api-version=5.0", content.to_json) end + def pull_request(pull_request_id) + response = get(source.api_endpoint + + source.organization + "/" + source.project + + "/_apis/git/pullrequests/" + pull_request_id) + + JSON.parse(response.body) + end + + def update_ref(branch_name, old_commit, new_commit) + content = [ + { + name: "refs/heads/" + branch_name, + oldObjectId: old_commit, + newObjectId: new_commit + } + ] + + response = post(source.api_endpoint + source.organization + "/" + source.project + + "/_apis/git/repositories/" + source.unscoped_repo + + "/refs?api-version=5.0", content.to_json) + + JSON.parse(response.body).fetch("value").first + end + # rubocop:enable Metrics/ParameterLists + def get(url) - response = Excon.get( - url, - user: credentials&.fetch("username"), - password: credentials&.fetch("password"), - idempotent: true, - **SharedHelpers.excon_defaults - ) + response = nil + + retry_connection_failures do + response = Excon.get( + url, + user: credentials&.fetch("username", nil), + password: credentials&.fetch("password", nil), + idempotent: true, + **SharedHelpers.excon_defaults( + headers: auth_header + ) + ) + + raise InternalServerError if response.status == 500 + raise BadGateway if response.status == 502 + raise ServiceNotAvailable if response.status == 503 + end + + raise Unauthorized if response.status == 401 + raise Forbidden if response.status == 403 raise NotFound if response.status == 404 response end def post(url, json) - response = Excon.post( - url, - headers: { - "Content-Type" => "application/json" - }, - body: json, - user: credentials&.fetch("username"), - password: credentials&.fetch("password"), - idempotent: true, - **SharedHelpers.excon_defaults - ) + response = nil + + retry_connection_failures do + response = Excon.post( + url, + body: json, + user: credentials&.fetch("username", nil), + password: credentials&.fetch("password", nil), + idempotent: true, + **SharedHelpers.excon_defaults( + headers: auth_header.merge( + { + "Content-Type" => "application/json" + } + ) + ) + ) + + raise InternalServerError if response.status == 500 + raise BadGateway if response.status == 502 + raise ServiceNotAvailable if response.status == 503 + end + + raise Unauthorized if response.status == 401 + + if response.status == 403 + raise TagsCreationForbidden if tags_creation_forbidden?(response) + + raise Forbidden + end raise NotFound if response.status == 404 response @@ -209,6 +281,59 @@ def post(url, json) private + def retry_connection_failures + retry_attempt = 0 + + begin + yield + rescue *RETRYABLE_ERRORS + retry_attempt += 1 + retry_attempt <= @max_retries ? retry : raise + end + end + + def auth_header_for(token) + return {} unless token + + if token.include?(":") + encoded_token = Base64.encode64(token).delete("\n") + { "Authorization" => "Basic #{encoded_token}" } + elsif Base64.decode64(token).ascii_only? && + Base64.decode64(token).include?(":") + { "Authorization" => "Basic #{token.delete("\n")}" } + else + { "Authorization" => "Bearer #{token}" } + end + end + + def truncate_pr_description(pr_description) + # Azure DevOps only support descriptions up to 4000 characters in UTF-16 + # encoding. + # https://developercommunity.visualstudio.com/content/problem/608770/remove-4000-character-limit-on-pull-request-descri.html + pr_description = pr_description.dup.force_encoding(Encoding::UTF_16) + if pr_description.length > MAX_PR_DESCRIPTION_LENGTH + truncated_msg = (+"...\n\n_Description has been truncated_").force_encoding(Encoding::UTF_16) + truncate_length = MAX_PR_DESCRIPTION_LENGTH - truncated_msg.length + pr_description = (pr_description[0..truncate_length] + truncated_msg) + end + pr_description.force_encoding(Encoding::UTF_8) + end + + def tags_creation_forbidden?(response) + return if response.body.empty? + + message = JSON.parse(response.body).fetch("message", nil) + message&.include?("TF401289") + end + + def pr_reviewers(reviewers, assignees) + return [] unless reviewers || assignees + + pr_reviewers = reviewers&.map { |r_id| { id: r_id, isRequired: true } } || [] + pr_reviewers + (assignees&.map { |r_id| { id: r_id, isRequired: false } } || []) + end + + attr_reader :auth_header attr_reader :credentials attr_reader :source end diff --git a/common/lib/dependabot/clients/bitbucket.rb b/common/lib/dependabot/clients/bitbucket.rb index 00dbf45b84a..510f6a48d15 100644 --- a/common/lib/dependabot/clients/bitbucket.rb +++ b/common/lib/dependabot/clients/bitbucket.rb @@ -7,15 +7,33 @@ module Dependabot module Clients class Bitbucket class NotFound < StandardError; end + class Unauthorized < StandardError; end + class Forbidden < StandardError; end + class TimedOut < StandardError; end + + ####################### + # Constructor methods # + ####################### + + def self.for_source(source:, credentials:) + credential = + credentials. + select { |cred| cred["type"] == "git_source" }. + find { |cred| cred["host"] == source.hostname } + + new(credentials: credential) + end + ########## # Client # ########## def initialize(credentials:) @credentials = credentials + @auth_header = auth_header_for(credentials&.fetch("token", nil)) end def fetch_commit(repo, branch) @@ -50,6 +68,127 @@ def fetch_file_contents(repo, commit, path) response.body end + def commits(repo, branch_name = nil) + commits_path = "#{repo}/commits/#{branch_name}?pagelen=100" + next_page_url = base_url + commits_path + paginate({ "next" => next_page_url }) + end + + def branch(repo, branch_name) + branch_path = "#{repo}/refs/branches/#{branch_name}" + response = get(base_url + branch_path) + + JSON.parse(response.body) + end + + def pull_requests(repo, source_branch, target_branch, status = %w(OPEN MERGED DECLINED SUPERSEDED)) + pr_path = "#{repo}/pullrequests?" + # Get pull requests with given status + status.each { |n| pr_path += "status=#{n}&" } + next_page_url = base_url + pr_path + pull_requests = paginate({ "next" => next_page_url }) + + pull_requests unless source_branch && target_branch + + pull_requests.select do |pr| + if source_branch.nil? + source_branch_matches = true + else + pr_source_branch = pr.fetch("source").fetch("branch").fetch("name") + source_branch_matches = pr_source_branch == source_branch + end + pr_target_branch = pr.fetch("destination").fetch("branch").fetch("name") + source_branch_matches && pr_target_branch == target_branch + end + end + + # rubocop:disable Metrics/ParameterLists + def create_commit(repo, branch_name, base_commit, commit_message, files, + author_details) + parameters = { + message: commit_message, # TODO: Format markup in commit message + author: "#{author_details.fetch(:name)} <#{author_details.fetch(:email)}>", + parents: base_commit, + branch: branch_name + } + + files.each do |file| + parameters[file.path] = file.content + end + + body = encode_form_parameters(parameters) + + commit_path = "#{repo}/src" + post(base_url + commit_path, body, "application/x-www-form-urlencoded") + end + # rubocop:enable Metrics/ParameterLists + + # rubocop:disable Metrics/ParameterLists + def create_pull_request(repo, pr_name, source_branch, target_branch, + pr_description, _labels, _work_item = nil) + reviewers = default_reviewers(repo) + + content = { + title: pr_name, + source: { + branch: { + name: source_branch + } + }, + destination: { + branch: { + name: target_branch + } + }, + description: pr_description, + reviewers: reviewers, + close_source_branch: true + } + + pr_path = "#{repo}/pullrequests" + post(base_url + pr_path, content.to_json) + end + # rubocop:enable Metrics/ParameterLists + + def decline_pull_request(repo, pr_id, comment = nil) + # https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/ + decline_path = "#{repo}/pullrequests/#{pr_id}/decline" + post(base_url + decline_path, "") + + comment = "Dependabot declined the pull request." if comment.nil? + + content = { + content: { + raw: comment + } + } + + comment_path = "#{repo}/pullrequests/#{pr_id}/comments" + post(base_url + comment_path, content.to_json) + end + + def current_user + base_url = "https://api.bitbucket.org/2.0/user?fields=uuid" + response = get(base_url) + JSON.parse(response.body).fetch("uuid") + end + + def default_reviewers(repo) + current_uuid = current_user + path = "#{repo}/default-reviewers?pagelen=100&fields=values.uuid,next" + reviewers_url = base_url + path + + default_reviewers = paginate({ "next" => reviewers_url }) + + reviewer_data = [] + + default_reviewers.each do |reviewer| + reviewer_data.append({ uuid: reviewer.fetch("uuid") }) unless current_uuid == reviewer.fetch("uuid") + end + + reviewer_data + end + def tags(repo) path = "#{repo}/refs/tags?pagelen=100" response = get(base_url + path) @@ -69,24 +208,92 @@ def get(url) url, user: credentials&.fetch("username", nil), password: credentials&.fetch("password", nil), - idempotent: true, - **Dependabot::SharedHelpers.excon_defaults + # Setting to false to prevent Excon retries, use BitbucketWithRetries for retries. + idempotent: false, + **Dependabot::SharedHelpers.excon_defaults( + headers: auth_header + ) ) raise Unauthorized if response.status == 401 raise Forbidden if response.status == 403 raise NotFound if response.status == 404 if response.status >= 400 - raise "Unhandled Bitbucket error!\n"\ - "Status: #{response.status}\n"\ + raise "Unhandled Bitbucket error!\n" \ + "Status: #{response.status}\n" \ "Body: #{response.body}" end response end + def post(url, body, content_type = "application/json") + headers = auth_header + + headers = if body.empty? + headers.merge({ "Accept" => "application/json" }) + else + headers.merge({ "Content-Type" => content_type }) + end + + response = Excon.post( + url, + body: body, + user: credentials&.fetch("username", nil), + password: credentials&.fetch("password", nil), + idempotent: false, + **SharedHelpers.excon_defaults( + headers: headers + ) + ) + raise Unauthorized if response.status == 401 + raise Forbidden if response.status == 403 + raise NotFound if response.status == 404 + raise TimedOut if response.status == 555 + + response + end + private + def auth_header_for(token) + return {} unless token + + { "Authorization" => "Bearer #{token}" } + end + + def encode_form_parameters(parameters) + parameters.map do |key, value| + URI.encode_www_form_component(key.to_s) + "=" + URI.encode_www_form_component(value.to_s) + end.join("&") + end + + # Takes a hash with optional `values` and `next` fields + # Returns an enumerator. + # + # Can be used a few ways: + # With GET: + # paginate ({"next" => url}) + # or + # paginate(JSON.parse(get(url).body)) + # + # With POST (for endpoints that provide POST methods for long query parameters) + # response = post(url, body) + # first_page = JSON.parse(repsonse.body) + # paginate(first_page) + def paginate(page) + Enumerator.new do |yielder| + loop do + page.fetch("values", []).each { |value| yielder << value } + break unless page.key?("next") + + next_page_url = page.fetch("next") + page = JSON.parse(get(next_page_url).body) + end + end + end + + attr_reader :auth_header attr_reader :credentials def base_url diff --git a/common/lib/dependabot/clients/bitbucket_with_retries.rb b/common/lib/dependabot/clients/bitbucket_with_retries.rb index 54bd87e6ecc..36e928831e0 100644 --- a/common/lib/dependabot/clients/bitbucket_with_retries.rb +++ b/common/lib/dependabot/clients/bitbucket_with_retries.rb @@ -29,7 +29,7 @@ def self.for_bitbucket_dot_org(credentials:) def initialize(max_retries: 3, **args) @max_retries = max_retries || 3 - @client = Bitbucket.new(args) + @client = Bitbucket.new(**args) end def method_missing(method_name, *args, &block) diff --git a/common/lib/dependabot/clients/github_with_retries.rb b/common/lib/dependabot/clients/github_with_retries.rb index 86b70d29489..71805c94235 100644 --- a/common/lib/dependabot/clients/github_with_retries.rb +++ b/common/lib/dependabot/clients/github_with_retries.rb @@ -5,11 +5,22 @@ module Dependabot module Clients class GithubWithRetries + DEFAULT_OPEN_TIMEOUT_IN_SECONDS = 2 + DEFAULT_READ_TIMEOUT_IN_SECONDS = 5 + + def self.open_timeout_in_seconds + ENV.fetch("DEPENDABOT_OPEN_TIMEOUT_IN_SECONDS", DEFAULT_OPEN_TIMEOUT_IN_SECONDS).to_i + end + + def self.read_timeout_in_seconds + ENV.fetch("DEPENDABOT_READ_TIMEOUT_IN_SECONDS", DEFAULT_READ_TIMEOUT_IN_SECONDS).to_i + end + DEFAULT_CLIENT_ARGS = { connection_options: { request: { - open_timeout: 2, - timeout: 5 + open_timeout: open_timeout_in_seconds, + timeout: read_timeout_in_seconds } } }.freeze @@ -78,7 +89,16 @@ def initialize(max_retries: 3, **args) access_tokens << nil if access_tokens.empty? access_tokens.uniq! - @max_retries = max_retries || 3 + Octokit.middleware = Faraday::RackBuilder.new do |builder| + builder.use Faraday::Retry::Middleware, exceptions: RETRYABLE_ERRORS, max: max_retries || 3 + + Octokit::Default::MIDDLEWARE.handlers.each do |handler| + next if handler.klass == Faraday::Retry::Middleware + + builder.use handler.klass + end + end + @clients = access_tokens.map do |token| Octokit::Client.new(args.merge(access_token: token)) end @@ -89,13 +109,11 @@ def method_missing(method_name, *args, &block) client = untried_clients.pop begin - retry_connection_failures do - if client.respond_to?(method_name) - mutatable_args = args.map(&:dup) - client.public_send(method_name, *mutatable_args, &block) - else - super - end + if client.respond_to?(method_name) + mutatable_args = args.map(&:dup) + client.public_send(method_name, *mutatable_args, &block) + else + super end rescue Octokit::NotFound, Octokit::Unauthorized, Octokit::Forbidden raise unless (client = untried_clients.pop) @@ -107,17 +125,6 @@ def method_missing(method_name, *args, &block) def respond_to_missing?(method_name, include_private = false) @clients.first.respond_to?(method_name) || super end - - def retry_connection_failures - retry_attempt = 0 - - begin - yield - rescue *RETRYABLE_ERRORS - retry_attempt += 1 - retry_attempt <= @max_retries ? retry : raise - end - end end end end diff --git a/common/lib/dependabot/config.rb b/common/lib/dependabot/config.rb new file mode 100644 index 00000000000..db4a6eb3b5d --- /dev/null +++ b/common/lib/dependabot/config.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dependabot + module Config + class InvalidConfigError < StandardError; end + end +end diff --git a/common/lib/dependabot/config/file.rb b/common/lib/dependabot/config/file.rb new file mode 100644 index 00000000000..e5d446c1374 --- /dev/null +++ b/common/lib/dependabot/config/file.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require "dependabot/config/update_config" + +module Dependabot + module Config + # Configuration for the repository, a parsed dependabot.yaml. + class File + attr_reader :updates, :registries + + def initialize(updates:, registries: nil) + @updates = updates || [] + @registries = registries || [] + end + + def update_config(package_manager, directory: nil, target_branch: nil) + dir = directory || "/" + package_ecosystem = PACKAGE_MANAGER_LOOKUP.invert.fetch(package_manager) + cfg = updates.find do |u| + u[:"package-ecosystem"] == package_ecosystem && u[:directory] == dir && + (target_branch.nil? || u[:"target-branch"] == target_branch) + end + Dependabot::Config::UpdateConfig.new( + ignore_conditions: ignore_conditions(cfg), + commit_message_options: commit_message_options(cfg) + ) + end + + # Parse the YAML config file + def self.parse(config) + parsed = YAML.safe_load(config, symbolize_names: true) + version = parsed[:version] + raise InvalidConfigError, "invalid version #{version}" if version && version != 2 + + File.new(updates: parsed[:updates], registries: parsed[:registries]) + end + + private + + PACKAGE_MANAGER_LOOKUP = { + "bundler" => "bundler", + "cargo" => "cargo", + "composer" => "composer", + "docker" => "docker", + "elm" => "elm", + "github-actions" => "github_actions", + "gitsubmodule" => "submodules", + "gomod" => "go_modules", + "gradle" => "gradle", + "maven" => "maven", + "mix" => "hex", + "nuget" => "nuget", + "npm" => "npm_and_yarn", + "pip" => "pip", + "pub" => "pub", + "terraform" => "terraform" + }.freeze + + def ignore_conditions(cfg) + ignores = cfg&.dig(:ignore) || [] + ignores.map do |ic| + Dependabot::Config::IgnoreCondition.new( + dependency_name: ic[:"dependency-name"], + versions: ic[:versions], + update_types: ic[:"update-types"] + ) + end + end + + def commit_message_options(cfg) + commit_message = cfg&.dig(:"commit-message") || {} + Dependabot::Config::UpdateConfig::CommitMessageOptions.new( + prefix: commit_message[:prefix], + prefix_development: commit_message[:"prefix-development"] || commit_message[:prefix], + include: commit_message[:include] + ) + end + end + end +end diff --git a/common/lib/dependabot/config/file_fetcher.rb b/common/lib/dependabot/config/file_fetcher.rb new file mode 100644 index 00000000000..d217832d2cb --- /dev/null +++ b/common/lib/dependabot/config/file_fetcher.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "dependabot/file_fetchers/base" +require "dependabot/config/file" + +module Dependabot + module Config + class FileFetcher < Dependabot::FileFetchers::Base + CONFIG_FILE_PATHS = %w(.github/dependabot.yml .github/dependabot.yaml).freeze + + def self.required_files_in?(filenames) + CONFIG_FILE_PATHS.any? { |file| filenames.include?(file) } + end + + def self.required_files_message + "Repo must contain either a #{CONFIG_FILE_PATHS.join(' or a ')} file" + end + + def config_file + @config_file ||= files.first + end + + private + + def fetch_files + fetched_files = [] + + CONFIG_FILE_PATHS.each do |file| + fn = Pathname.new("/#{file}").relative_path_from(directory) + + begin + config_file = fetch_file_from_host(fn) + if config_file + fetched_files << config_file + break + end + rescue Dependabot::DependencyFileNotFound + next + end + end + + unless self.class.required_files_in?(fetched_files.map(&:name)) + raise Dependabot::DependencyFileNotFound, self.class.required_files_message + end + + fetched_files + end + end + end +end diff --git a/common/lib/dependabot/config/ignore_condition.rb b/common/lib/dependabot/config/ignore_condition.rb new file mode 100644 index 00000000000..29f9f52d3f6 --- /dev/null +++ b/common/lib/dependabot/config/ignore_condition.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module Dependabot + module Config + # Filters versions that should not be considered for dependency updates + class IgnoreCondition + PATCH_VERSION_TYPE = "version-update:semver-patch" + MINOR_VERSION_TYPE = "version-update:semver-minor" + MAJOR_VERSION_TYPE = "version-update:semver-major" + + ALL_VERSIONS = ">= 0" + + attr_reader :dependency_name, :versions, :update_types + + def initialize(dependency_name:, versions: nil, update_types: nil) + @dependency_name = dependency_name + @versions = versions || [] + @update_types = update_types || [] + end + + def ignored_versions(dependency, security_updates_only) + return versions if security_updates_only + return [ALL_VERSIONS] if versions.empty? && transformed_update_types.empty? + + versions_by_type(dependency) + versions + end + + private + + def transformed_update_types + update_types.map(&:downcase).filter_map(&:strip) + end + + def versions_by_type(dependency) + return [] unless dependency.version + + transformed_update_types.flat_map do |t| + case t + when PATCH_VERSION_TYPE + ignore_patch(dependency.version) + when MINOR_VERSION_TYPE + ignore_minor(dependency.version) + when MAJOR_VERSION_TYPE + ignore_major(dependency.version) + else + [] + end + end.compact + end + + def ignore_patch(version) + return [] unless rubygems_compatible?(version) + + parts = version.split(".") + version_parts = parts.fill(0, parts.length...2) + upper_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + lower_bound = "> #{version}" + upper_bound = "< #{upper_parts.join('.')}" + + ["#{lower_bound}, #{upper_bound}"] + end + + def ignore_minor(version) + return [] unless rubygems_compatible?(version) + + parts = version.split(".") + version_parts = parts.fill(0, parts.length...2) + lower_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + ["a"] + upper_parts = version_parts.first(0) + [version_parts[0].to_i + 1] + lower_bound = ">= #{lower_parts.join('.')}" + upper_bound = "< #{upper_parts.join('.')}" + + ["#{lower_bound}, #{upper_bound}"] + end + + def ignore_major(version) + return [] unless rubygems_compatible?(version) + + version_parts = version.split(".") + lower_parts = [version_parts[0].to_i + 1] + ["a"] + lower_bound = ">= #{lower_parts.join('.')}" + + [lower_bound] + end + + def rubygems_compatible?(version) + return false if version.nil? || version.empty? + + Gem::Version.correct?(version) + end + end + end +end diff --git a/common/lib/dependabot/config/update_config.rb b/common/lib/dependabot/config/update_config.rb new file mode 100644 index 00000000000..7603b421967 --- /dev/null +++ b/common/lib/dependabot/config/update_config.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require "dependabot/config/ignore_condition" + +module Dependabot + module Config + # Configuration for a single ecosystem + class UpdateConfig + attr_reader :commit_message_options, :ignore_conditions + def initialize(ignore_conditions: nil, commit_message_options: nil) + @ignore_conditions = ignore_conditions || [] + @commit_message_options = commit_message_options + end + + def ignored_versions_for(dependency, security_updates_only: false) + normalizer = name_normaliser_for(dependency) + dep_name = normalizer.call(dependency.name) + + @ignore_conditions. + select { |ic| self.class.wildcard_match?(normalizer.call(ic.dependency_name), dep_name) }. + map { |ic| ic.ignored_versions(dependency, security_updates_only) }. + flatten. + compact. + uniq + end + + def self.wildcard_match?(wildcard_string, candidate_string) + return false unless wildcard_string && candidate_string + + regex_string = "a#{wildcard_string.downcase}a".split("*"). + map { |p| Regexp.quote(p) }. + join(".*").gsub(/^a|a$/, "") + regex = /^#{regex_string}$/ + regex.match?(candidate_string.downcase) + end + + private + + def name_normaliser_for(dep) + name_normaliser ||= {} + name_normaliser[dep] ||= Dependency.name_normaliser_for_package_manager(dep.package_manager) + end + + class CommitMessageOptions + attr_reader :prefix, :prefix_development, :include + + def initialize(prefix:, prefix_development:, include:) + @prefix = prefix + @prefix_development = prefix_development + @include = include + end + + def include_scope? + @include == "scope" + end + + def to_h + { + prefix: @prefix, + prefix_development: @prefix_development, + include_scope: include_scope? + } + end + end + end + end +end diff --git a/common/lib/dependabot/dependency.rb b/common/lib/dependabot/dependency.rb index 6532ffec8cc..be4f97bcf61 100644 --- a/common/lib/dependabot/dependency.rb +++ b/common/lib/dependabot/dependency.rb @@ -37,11 +37,11 @@ def self.register_name_normaliser(package_manager, name_builder) attr_reader :name, :version, :requirements, :package_manager, :previous_version, :previous_requirements, - :subdependency_metadata + :subdependency_metadata, :metadata def initialize(name:, requirements:, package_manager:, version: nil, previous_version: nil, previous_requirements: nil, - subdependency_metadata: []) + subdependency_metadata: [], removed: false, metadata: {}) @name = name @version = version @requirements = requirements.map { |req| symbolize_keys(req) } @@ -53,6 +53,8 @@ def initialize(name:, requirements:, package_manager:, version: nil, @subdependency_metadata = subdependency_metadata&. map { |h| symbolize_keys(h) } end + @removed = removed + @metadata = symbolize_keys(metadata || {}) check_values end @@ -61,6 +63,14 @@ def top_level? requirements.any? end + def removed? + @removed + end + + def numeric_version + @numeric_version ||= version_class.new(version) if version && version_class.correct?(version) + end + def to_h { "name" => name, @@ -69,7 +79,8 @@ def to_h "previous_version" => previous_version, "previous_requirements" => previous_requirements, "package_manager" => package_manager, - "subdependency_metadata" => subdependency_metadata + "subdependency_metadata" => subdependency_metadata, + "removed" => removed? ? true : nil }.compact end @@ -99,6 +110,22 @@ def display_name display_name_builder.call(name) end + # Returns all detected versions of the dependency. Only ecosystems that + # support this feature will return more than the current version. + def all_versions + all_versions = metadata[:all_versions] + return [version].compact unless all_versions + + all_versions.filter_map(&:version) + end + + # This dependency is being indirectly updated by an update to another + # dependency. We don't need to try and update it ourselves but want to + # surface it to the user in the PR. + def informational_only? + metadata[:information_only] + end + def ==(other) other.instance_of?(self.class) && to_h == other.to_h end @@ -113,10 +140,12 @@ def eql?(other) private + def version_class + Utils.version_class_for_package_manager(package_manager) + end + def check_values - if [version, previous_version].any? { |v| v == "" } - raise ArgumentError, "blank strings must not be provided as versions" - end + raise ArgumentError, "blank strings must not be provided as versions" if [version, previous_version].any?("") check_requirement_fields check_subdependency_metadata @@ -124,8 +153,8 @@ def check_values def check_requirement_fields requirement_fields = [requirements, previous_requirements].compact - unless requirement_fields.all? { |r| r.is_a?(Array) } && - requirement_fields.flatten.all? { |r| r.is_a?(Hash) } + unless requirement_fields.all?(Array) && + requirement_fields.flatten.all?(Hash) raise ArgumentError, "requirements must be an array of hashes" end @@ -133,9 +162,9 @@ def check_requirement_fields optional_keys = %i(metadata) unless requirement_fields.flatten. all? { |r| required_keys.sort == (r.keys - optional_keys).sort } - raise ArgumentError, "each requirement must have the following "\ - "required keys: #{required_keys.join(', ')}."\ - "Optionally, it may have the following keys: "\ + raise ArgumentError, "each requirement must have the following " \ + "required keys: #{required_keys.join(', ')}." \ + "Optionally, it may have the following keys: " \ "#{optional_keys.join(', ')}." end @@ -148,13 +177,13 @@ def check_subdependency_metadata return unless subdependency_metadata unless subdependency_metadata.is_a?(Array) && - subdependency_metadata.all? { |r| r.is_a?(Hash) } + subdependency_metadata.all?(Hash) raise ArgumentError, "subdependency_metadata must be an array of hashes" end end def symbolize_keys(hash) - Hash[hash.keys.map { |k| [k.to_sym, hash[k]] }] + hash.keys.to_h { |k| [k.to_sym, hash[k]] } end end end diff --git a/common/lib/dependabot/dependency_file.rb b/common/lib/dependabot/dependency_file.rb index b9540e4dce3..6b26561a5b3 100644 --- a/common/lib/dependabot/dependency_file.rb +++ b/common/lib/dependabot/dependency_file.rb @@ -5,15 +5,34 @@ module Dependabot class DependencyFile attr_accessor :name, :content, :directory, :type, :support_file, - :symlink_target + :symlink_target, :content_encoding, :operation, :mode + + class ContentEncoding + UTF_8 = "utf-8" + BASE64 = "base64" + end + + class Operation + UPDATE = "update" + CREATE = "create" + DELETE = "delete" + end def initialize(name:, content:, directory: "/", type: "file", - support_file: false, symlink_target: nil) + support_file: false, symlink_target: nil, + content_encoding: ContentEncoding::UTF_8, deleted: false, + operation: Operation::UPDATE, mode: nil) @name = name @content = content @directory = clean_directory(directory) @symlink_target = symlink_target @support_file = support_file + @content_encoding = content_encoding + @operation = operation + + # Make deleted override the operation. Deleted is kept when operation + # was introduced to keep compatibility with downstream dependants. + @operation = Operation::DELETE if deleted # Type is used *very* sparingly. It lets the git_modules updater know that # a "file" is actually a submodule, and lets our Go updaters know which @@ -22,6 +41,12 @@ def initialize(name:, content:, directory: "/", type: "file", # support_file flag instead) @type = type + begin + @mode = File.stat((symlink_target || path).sub(%r{^/}, "")).mode.to_s(8) + rescue StandardError + @mode = mode + end + return unless (type == "symlink") ^ symlink_target raise "Symlinks must specify a target!" unless symlink_target @@ -34,7 +59,11 @@ def to_h "content" => content, "directory" => directory, "type" => type, - "support_file" => support_file + "support_file" => support_file, + "content_encoding" => content_encoding, + "deleted" => deleted, + "operation" => operation, + "mode" => mode } details["symlink_target"] = symlink_target if symlink_target @@ -65,6 +94,28 @@ def support_file? @support_file end + def deleted + @operation == Operation::DELETE + end + + def deleted=(deleted) + @operation = deleted ? Operation::DELETE : Operation::UPDATE + end + + def deleted? + deleted + end + + def binary? + content_encoding == ContentEncoding::BASE64 + end + + def decoded_content + return Base64.decode64(content) if binary? + + content + end + private def clean_directory(directory) diff --git a/common/lib/dependabot/errors.rb b/common/lib/dependabot/errors.rb index 3f6d8589118..1e3ca67ee6f 100644 --- a/common/lib/dependabot/errors.rb +++ b/common/lib/dependabot/errors.rb @@ -1,29 +1,54 @@ # frozen_string_literal: true -require "dependabot/shared_helpers" +require "dependabot/utils" module Dependabot class DependabotError < StandardError - def initialize(msg = nil) - msg = sanitize_message(msg) - super(msg) + BASIC_AUTH_REGEX = %r{://(?[^:]*:[^@%\s]+(@|%40))} + # Remove any path segment from fury.io sources + FURY_IO_PATH_REGEX = %r{fury\.io/(?.+)} + + def initialize(message = nil) + super(sanitize_message(message)) end private def sanitize_message(message) - return unless message + return message unless message.is_a?(String) path_regex = - Regexp.escape(SharedHelpers::BUMP_TMP_DIR_PATH) + "\/" + - Regexp.escape(SharedHelpers::BUMP_TMP_FILE_PREFIX) + "[^/]*" + Regexp.escape(Utils::BUMP_TMP_DIR_PATH) + "\\/" + + Regexp.escape(Utils::BUMP_TMP_FILE_PREFIX) + "[a-zA-Z0-9-]*" + + message = message.gsub(/#{path_regex}/, "dependabot_tmp_dir").strip + filter_sensitive_data(message) + end - message.gsub(/#{path_regex}/, "dependabot_tmp_dir") + def filter_sensitive_data(message) + replace_capture_groups(message, BASIC_AUTH_REGEX, "") + end + + def sanitize_source(source) + source = filter_sensitive_data(source) + replace_capture_groups(source, FURY_IO_PATH_REGEX, "") + end + + def replace_capture_groups(string, regex, replacement) + return string unless string.is_a?(String) + + string.scan(regex).flatten.compact.reduce(string) do |original_msg, match| + original_msg.gsub(match, replacement) + end end end + class OutOfDisk < DependabotError; end + class OutOfMemory < DependabotError; end + class NotImplemented < DependabotError; end + ##################### # Repo level errors # ##################### @@ -33,7 +58,6 @@ class BranchNotFound < DependabotError def initialize(branch_name, msg = nil) @branch_name = branch_name - msg = sanitize_message(msg) super(msg) end end @@ -88,6 +112,7 @@ def directory end class DependencyFileNotEvaluatable < DependabotError; end + class DependencyFileNotResolvable < DependabotError; end ####################### @@ -98,10 +123,10 @@ class PrivateSourceAuthenticationFailure < DependabotError attr_reader :source def initialize(source) - @source = source.gsub(%r{(?<=\.fury\.io)/[A-Za-z0-9]{20}(?=/)}, "") - msg = "The following source could not be reached as it requires "\ - "authentication (and any provided details were invalid or lacked "\ - "the required permissions): #{source}" + @source = sanitize_source(source) + msg = "The following source could not be reached as it requires " \ + "authentication (and any provided details were invalid or lacked " \ + "the required permissions): #{@source}" super(msg) end end @@ -110,8 +135,8 @@ class PrivateSourceTimedOut < DependabotError attr_reader :source def initialize(source) - @source = source.gsub(%r{(?<=\.fury\.io)/[A-Za-z0-9]{20}(?=/)}, "") - super("The following source timed out: #{source}") + @source = sanitize_source(source) + super("The following source timed out: #{@source}") end end @@ -119,8 +144,8 @@ class PrivateSourceCertificateFailure < DependabotError attr_reader :source def initialize(source) - @source = source.gsub(%r{(?<=\.fury\.io)/[A-Za-z0-9]{20}(?=/)}, "") - super("Could not verify the SSL certificate for #{source}") + @source = sanitize_source(source) + super("Could not verify the SSL certificate for #{@source}") end end @@ -129,7 +154,7 @@ class MissingEnvironmentVariable < DependabotError def initialize(environment_variable) @environment_variable = environment_variable - super("Missing environment variable #{environment_variable}") + super("Missing environment variable #{@environment_variable}") end end @@ -146,10 +171,10 @@ class GitDependenciesNotReachable < DependabotError def initialize(*dependency_urls) @dependency_urls = - dependency_urls.flatten.map { |uri| uri.gsub(/x-access-token.*?@/, "") } + dependency_urls.flatten.map { |uri| filter_sensitive_data(uri) } - msg = "The following git URLs could not be retrieved: "\ - "#{dependency_urls.join(', ')}" + msg = "The following git URLs could not be retrieved: " \ + "#{@dependency_urls.join(', ')}" super(msg) end end @@ -160,7 +185,7 @@ class GitDependencyReferenceNotFound < DependabotError def initialize(dependency) @dependency = dependency - msg = "The branch or reference specified for #{dependency} could not "\ + msg = "The branch or reference specified for #{@dependency} could not " \ "be retrieved" super(msg) end @@ -171,8 +196,8 @@ class PathDependenciesNotReachable < DependabotError def initialize(*dependencies) @dependencies = dependencies.flatten - msg = "The following path based dependencies could not be retrieved: "\ - "#{dependencies.join(', ')}" + msg = "The following path based dependencies could not be retrieved: " \ + "#{@dependencies.join(', ')}" super(msg) end end @@ -185,8 +210,8 @@ def initialize(go_mod, declared_path, discovered_path) @declared_path = declared_path @discovered_path = discovered_path - msg = "The module path '#{declared_path}' found in #{go_mod} doesn't "\ - "match the actual path '#{discovered_path}' in the dependency's "\ + msg = "The module path '#{@declared_path}' found in #{@go_mod} doesn't " \ + "match the actual path '#{@discovered_path}' in the dependency's " \ "go.mod" super(msg) end @@ -194,4 +219,7 @@ def initialize(go_mod, declared_path, discovered_path) # Raised by UpdateChecker if all candidate updates are ignored class AllVersionsIgnored < DependabotError; end + + # Raised by FileParser if processing may execute external code in the update context + class UnexpectedExternalCode < DependabotError; end end diff --git a/common/lib/dependabot/experiments.rb b/common/lib/dependabot/experiments.rb new file mode 100644 index 00000000000..291262d0e29 --- /dev/null +++ b/common/lib/dependabot/experiments.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Dependabot + module Experiments + @experiments = {} + + def self.reset! + @experiments = {} + end + + def self.register(name, value) + @experiments[name.to_sym] = value + end + + def self.enabled?(name) + !!@experiments[name.to_sym] + end + end +end diff --git a/common/lib/dependabot/file_fetchers/base.rb b/common/lib/dependabot/file_fetchers/base.rb index 46cadb3189f..32a6ca12413 100644 --- a/common/lib/dependabot/file_fetchers/base.rb +++ b/common/lib/dependabot/file_fetchers/base.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "stringio" +require "dependabot/config" require "dependabot/dependency_file" require "dependabot/source" require "dependabot/errors" @@ -14,7 +16,7 @@ module Dependabot module FileFetchers class Base - attr_reader :source, :credentials + attr_reader :source, :credentials, :repo_contents_path, :options CLIENT_NOT_FOUND_ERRORS = [ Octokit::NotFound, @@ -24,6 +26,12 @@ class Base Dependabot::Clients::CodeCommit::NotFound ].freeze + GIT_SUBMODULE_INACCESSIBLE_ERROR = + /^fatal: unable to access '(?.*)': The requested URL returned error: (?\d+)$/ + GIT_SUBMODULE_CLONE_ERROR = + /^fatal: clone of '(?.*)' into submodule path '.*' failed$/ + GIT_SUBMODULE_ERROR_REGEX = /(#{GIT_SUBMODULE_INACCESSIBLE_ERROR})|(#{GIT_SUBMODULE_CLONE_ERROR})/ + def self.required_files_in?(_filename_array) raise NotImplementedError end @@ -32,11 +40,23 @@ def self.required_files_message raise NotImplementedError end - def initialize(source:, credentials:) + # Creates a new FileFetcher for retrieving `DependencyFile`s. + # + # Files are typically grabbed individually via the source's API. + # repo_contents_path is an optional empty directory that will be used + # to clone the entire source repository on first read. + # + # If provided, file _data_ will be loaded from the clone. + # Submodules and directory listings are _not_ currently supported + # by repo_contents_path and still use an API trip. + # + # options supports custom feature enablement + def initialize(source:, credentials:, repo_contents_path: nil, options: {}) @source = source @credentials = credentials - + @repo_contents_path = repo_contents_path @linked_paths = {} + @options = options end def repo @@ -56,6 +76,7 @@ def files end def commit + return cloned_commit if cloned_commit return source.commit if source.commit branch = target_branch || default_branch_for_repo @@ -67,9 +88,29 @@ def commit raise unless e.message.include?("Repository is empty") end + # Returns the path to the cloned repo + def clone_repo_contents + @clone_repo_contents ||= + _clone_repo_contents(target_directory: repo_contents_path) + rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e + if e.message.include?("fatal: Remote branch #{target_branch} not found in upstream origin") + raise Dependabot::BranchNotFound, target_branch + end + + raise Dependabot::RepoNotFound, source + end + private def fetch_file_if_present(filename, fetch_submodules: false) + unless repo_contents_path.nil? + begin + return load_cloned_file_if_present(filename) + rescue Dependabot::DependencyFileNotFound + return + end + end + dir = File.dirname(filename) basename = File.basename(filename) @@ -85,10 +126,34 @@ def fetch_file_if_present(filename, fetch_submodules: false) raise Dependabot::DependencyFileNotFound, path end + def load_cloned_file_if_present(filename) + path = Pathname.new(File.join(directory, filename)).cleanpath.to_path + repo_path = File.join(clone_repo_contents, path) + raise Dependabot::DependencyFileNotFound, path unless File.exist?(repo_path) + + content = File.read(repo_path) + type = if File.symlink?(repo_path) + symlink_target = File.readlink(repo_path) + "symlink" + else + "file" + end + + DependencyFile.new( + name: Pathname.new(filename).cleanpath.to_path, + directory: directory, + type: type, + content: content, + symlink_target: symlink_target + ) + end + def fetch_file_from_host(filename, type: "file", fetch_submodules: false) + return load_cloned_file_if_present(filename) unless repo_contents_path.nil? + path = Pathname.new(File.join(directory, filename)).cleanpath.to_path content = _fetch_file_content(path, fetch_submodules: fetch_submodules) - type = @linked_paths.key?(path.gsub(%r{^/}, "")) ? "symlink" : type + type = "symlink" if @linked_paths.key?(path.gsub(%r{^/}, "")) DependencyFile.new( name: Pathname.new(filename).cleanpath.to_path, @@ -107,11 +172,103 @@ def repo_contents(dir: ".", ignore_base_directory: false, path = Pathname.new(File.join(dir)).cleanpath.to_path.gsub(%r{^/*}, "") @repo_contents ||= {} - @repo_contents[dir] ||= _fetch_repo_contents( - path, - raise_errors: raise_errors, - fetch_submodules: fetch_submodules - ) + @repo_contents[dir] ||= if repo_contents_path + _cloned_repo_contents(path) + else + _fetch_repo_contents(path, raise_errors: raise_errors, + fetch_submodules: fetch_submodules) + end + end + + def cloned_commit + return if repo_contents_path.nil? || !File.directory?(File.join(repo_contents_path, ".git")) + + SharedHelpers.with_git_configured(credentials: credentials) do + Dir.chdir(repo_contents_path) do + return SharedHelpers.run_shell_command("git rev-parse HEAD")&.strip + end + end + end + + def default_branch_for_repo + @default_branch_for_repo ||= client_for_provider. + fetch_default_branch(repo) + rescue *CLIENT_NOT_FOUND_ERRORS + raise Dependabot::RepoNotFound, source + end + + def update_linked_paths(repo, path, commit, github_response) + case github_response.type + when "submodule" + sub_source = Source.from_url(github_response.submodule_git_url) + return unless sub_source + + @linked_paths[path] = { + repo: sub_source.repo, + provider: sub_source.provider, + commit: github_response.sha, + path: "/" + } + when "symlink" + updated_path = File.join(File.dirname(path), github_response.target) + @linked_paths[path] = { + repo: repo, + provider: "github", + commit: commit, + path: Pathname.new(updated_path).cleanpath.to_path + } + end + end + + def recurse_submodules_when_cloning? + false + end + + def client_for_provider + case source.provider + when "github" then github_client + when "gitlab" then gitlab_client + when "azure" then azure_client + when "bitbucket" then bitbucket_client + when "codecommit" then codecommit_client + else raise "Unsupported provider '#{source.provider}'." + end + end + + def github_client + @github_client ||= + Dependabot::Clients::GithubWithRetries.for_source( + source: source, + credentials: credentials + ) + end + + def gitlab_client + @gitlab_client ||= + Dependabot::Clients::GitlabWithRetries.for_source( + source: source, + credentials: credentials + ) + end + + def azure_client + @azure_client ||= + Dependabot::Clients::Azure. + for_source(source: source, credentials: credentials) + end + + def bitbucket_client + # TODO: When self-hosted Bitbucket is supported this should use + # `Bitbucket.for_source` + @bitbucket_client ||= + Dependabot::Clients::BitbucketWithRetries. + for_bitbucket_dot_org(credentials: credentials) + end + + def codecommit_client + @codecommit_client ||= + Dependabot::Clients::CodeCommit. + for_source(source: source, credentials: credentials) end ################################################# @@ -175,26 +332,28 @@ def _github_repo_contents(repo, path, commit) github_response.map { |f| _build_github_file_struct(f) } end - def update_linked_paths(repo, path, commit, github_response) - case github_response.type - when "submodule" - sub_source = Source.from_url(github_response.submodule_git_url) - return unless sub_source + def _cloned_repo_contents(relative_path) + repo_path = File.join(clone_repo_contents, relative_path) + return [] unless Dir.exist?(repo_path) - @linked_paths[path] = { - repo: sub_source.repo, - provider: sub_source.provider, - commit: github_response.sha, - path: "/" - } - when "symlink" - updated_path = File.join(File.dirname(path), github_response.target) - @linked_paths[path] = { - repo: repo, - provider: "github", - commit: commit, - path: Pathname.new(updated_path).cleanpath.to_path - } + Dir.entries(repo_path).filter_map do |name| + next if name == "." || name == ".." + + absolute_path = File.join(repo_path, name) + type = if File.symlink?(absolute_path) + "symlink" + elsif Dir.exist?(absolute_path) + "dir" + else + "file" + end + + OpenStruct.new( + name: name, + path: Pathname.new(File.join(relative_path, name)).cleanpath.to_path, + type: type, + size: 0 # NOTE: added for parity with github contents API + ) end end @@ -280,8 +439,8 @@ def _codecommit_repo_contents(repo, path, commit) response.files.map do |file| OpenStruct.new( - name: file.absolute_path, - path: file.absolute_path, + name: File.basename(file.relative_path), + path: file.relative_path, type: "file", size: 0 # file size would require new api call per file.. ) @@ -370,7 +529,13 @@ def _fetch_file_content_from_github(path, repo, commit) ) end - Base64.decode64(tmp.content).force_encoding("UTF-8").encode + if tmp.content == "" + # The file may have exceeded the 1MB limit + # see https://github.blog/changelog/2022-05-03-increased-file-size-limit-when-retrieving-file-contents-via-rest-api/ + github_client.contents(repo, path: path, ref: commit, accept: "application/vnd.github.v3.raw") + else + Base64.decode64(tmp.content).force_encoding("UTF-8").encode + end rescue Octokit::Forbidden => e raise unless e.message.include?("too_large") @@ -388,13 +553,6 @@ def _fetch_file_content_from_github(path, repo, commit) end # rubocop:enable Metrics/AbcSize - def default_branch_for_repo - @default_branch_for_repo ||= client_for_provider. - fetch_default_branch(repo) - rescue *CLIENT_NOT_FOUND_ERRORS - raise Dependabot::RepoNotFound, source - end - # Update the @linked_paths hash by exploiting a side-effect of # recursively calling `repo_contents` for each directory up the tree # until a submodule or symlink is found @@ -419,52 +577,81 @@ def _linked_dir_for(path) max_by(&:length) end - def client_for_provider - case source.provider - when "github" then github_client - when "gitlab" then gitlab_client - when "azure" then azure_client - when "bitbucket" then bitbucket_client - when "codecommit" then codecommit_client - else raise "Unsupported provider '#{source.provider}'." - end - end + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/BlockLength + def _clone_repo_contents(target_directory:) + SharedHelpers.with_git_configured(credentials: credentials) do + path = target_directory || File.join("tmp", source.repo) + # Assume we're retrying the same branch, or that a `target_directory` + # is specified when retrying a different branch. + return path if Dir.exist?(File.join(path, ".git")) + + FileUtils.mkdir_p(path) + + clone_options = StringIO.new + clone_options << "--no-tags --depth 1" + clone_options << if recurse_submodules_when_cloning? + " --recurse-submodules --shallow-submodules" + else + " --no-recurse-submodules" + end + clone_options << " --branch #{source.branch} --single-branch" if source.branch + + submodule_cloning_failed = false + begin + SharedHelpers.run_shell_command( + <<~CMD + git clone #{clone_options.string} #{source.url} #{path} + CMD + ) + rescue SharedHelpers::HelperSubprocessFailed => e + raise unless GIT_SUBMODULE_ERROR_REGEX && e.message.downcase.include?("submodule") - def github_client - @github_client ||= - Dependabot::Clients::GithubWithRetries.for_source( - source: source, - credentials: credentials - ) - end + submodule_cloning_failed = true + match = e.message.match(GIT_SUBMODULE_ERROR_REGEX) + url = match.named_captures["url"] + code = match.named_captures["code"] - def gitlab_client - @gitlab_client ||= - Dependabot::Clients::GitlabWithRetries.for_source( - source: source, - credentials: credentials - ) - end - - def azure_client - @azure_client ||= - Dependabot::Clients::Azure. - for_source(source: source, credentials: credentials) - end + # Submodules might be in the repo but unrelated to dependencies, + # so ignoring this error to try the update anyway since the base repo exists. + Dependabot.logger.error("Cloning of submodule failed: #{url} error: #{code || 'unknown'}") + end - def bitbucket_client - # TODO: When self-hosted Bitbucket is supported this should use - # `Bitbucket.for_source` - @bitbucket_client ||= - Dependabot::Clients::BitbucketWithRetries. - for_bitbucket_dot_org(credentials: credentials) - end + if source.commit + # This code will only be called for testing. Production will never pass a commit + # since Dependabot always wants to use the latest commit on a branch. + Dir.chdir(path) do + fetch_options = StringIO.new + fetch_options << "--depth 1" + fetch_options << if recurse_submodules_when_cloning? && !submodule_cloning_failed + " --recurse-submodules=on-demand" + else + " --no-recurse-submodules" + end + # Need to fetch the commit due to the --depth 1 above. + SharedHelpers.run_shell_command("git fetch #{fetch_options.string} origin #{source.commit}") + + reset_options = StringIO.new + reset_options << "--hard" + reset_options << if recurse_submodules_when_cloning? && !submodule_cloning_failed + " --recurse-submodules" + else + " --no-recurse-submodules" + end + # Set HEAD to this commit so later calls so git reset HEAD will work. + SharedHelpers.run_shell_command("git reset #{reset_options.string} #{source.commit}") + end + end - def codecommit_client - @codecommit_client ||= - Dependabot::Clients::CodeCommit. - for_source(source: source, credentials: credentials) + path + end end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/BlockLength end end end diff --git a/common/lib/dependabot/file_parsers/base.rb b/common/lib/dependabot/file_parsers/base.rb index 68a692f8706..fa9ce612b9c 100644 --- a/common/lib/dependabot/file_parsers/base.rb +++ b/common/lib/dependabot/file_parsers/base.rb @@ -1,14 +1,20 @@ # frozen_string_literal: true +require "dependabot/notifications" + module Dependabot module FileParsers class Base - attr_reader :dependency_files, :credentials, :source + attr_reader :dependency_files, :repo_contents_path, :credentials, :source, :options - def initialize(dependency_files:, source:, credentials: []) + def initialize(dependency_files:, repo_contents_path: nil, source:, + credentials: [], reject_external_code: false, options: {}) @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials @source = source + @reject_external_code = reject_external_code + @options = options check_required_files end diff --git a/common/lib/dependabot/file_parsers/base/dependency_set.rb b/common/lib/dependabot/file_parsers/base/dependency_set.rb index 7d87465b206..ee466fe3b92 100644 --- a/common/lib/dependabot/file_parsers/base/dependency_set.rb +++ b/common/lib/dependabot/file_parsers/base/dependency_set.rb @@ -10,42 +10,46 @@ class Base class DependencySet def initialize(dependencies = [], case_sensitive: false) unless dependencies.is_a?(Array) && - dependencies.all? { |dep| dep.is_a?(Dependency) } + dependencies.all?(Dependency) raise ArgumentError, "must be an array of Dependency objects" end - @dependencies = dependencies @case_sensitive = case_sensitive + @dependencies = Hash.new { |hsh, key| hsh[key] = DependencySlot.new } + dependencies.each { |dep| self << dep } end - attr_reader :dependencies + def dependencies + @dependencies.values.filter_map(&:combined) + end def <<(dep) - unless dep.is_a?(Dependency) - raise ArgumentError, "must be a Dependency object" - end + raise ArgumentError, "must be a Dependency object" unless dep.is_a?(Dependency) - existing_dependency = dependency_for_name(dep.name) + @dependencies[key_for_dependency(dep)] << dep + self + end - return self if existing_dependency&.to_h == dep.to_h + def +(other) + raise ArgumentError, "must be a DependencySet" unless other.is_a?(DependencySet) - if existing_dependency - dependencies[dependencies.index(existing_dependency)] = - combined_dependency(existing_dependency, dep) - else - dependencies << dep + other_names = other.dependencies.map(&:name) + other_names.each do |name| + all_versions = other.all_versions_for_name(name) + all_versions.each { |dep| self << dep } end self end - def +(other) - unless other.is_a?(DependencySet) - raise ArgumentError, "must be a DependencySet" - end + def all_versions_for_name(name) + key = key_for_name(name) + @dependencies.key?(key) ? @dependencies[key].all_versions : [] + end - other.dependencies.each { |dep| self << dep } - self + def dependency_for_name(name) + key = key_for_name(name) + @dependencies.key?(key) ? @dependencies[key].combined : nil end private @@ -54,43 +58,98 @@ def case_sensitive? @case_sensitive end - def dependency_for_name(name) - return dependencies.find { |d| d.name == name } if case_sensitive? + def key_for_name(name) + case_sensitive? ? name : name.downcase + end - dependencies.find { |d| d.name&.downcase == name&.downcase } + def key_for_dependency(dep) + key_for_name(dep.name) end - # rubocop:disable Metrics/PerceivedComplexity - def combined_dependency(old_dep, new_dep) - package_manager = old_dep.package_manager - v_cls = Utils.version_class_for_package_manager(package_manager) - - # If we already have a requirement use the existing version - # (if present). Otherwise, use whatever the lowest version is - new_version = - if old_dep.requirements.any? then old_dep.version || new_dep.version - elsif !v_cls.correct?(new_dep.version) then old_dep.version - elsif !v_cls.correct?(old_dep.version) then new_dep.version - elsif v_cls.new(new_dep.version) > v_cls.new(old_dep.version) - old_dep.version - else new_dep.version + # There can only be one entry per dependency name in a `DependencySet`. Each entry + # is assigned a `DependencySlot`. + # + # In some ecosystems (like `npm_and_yarn`), however, multiple versions of a + # dependency may be encountered and added to the set. The `DependencySlot` retains + # all added versions and presents a single unified dependency for the entry + # that combines the attributes of these versions. + # + # The combined dependency is accessible via `DependencySet#dependencies` or + # `DependencySet#dependency_for_name`. The list of individual versions of the + # dependency is accessible via `DependencySet#all_versions_for_name`. + class DependencySlot + attr_reader :all_versions, :combined + + def initialize + @all_versions = [] + @combined = nil + end + + def <<(dep) + return self if @all_versions.include?(dep) + + @combined = if @combined + combined_dependency(@combined, dep) + else + Dependency.new( + name: dep.name, + version: dep.version, + requirements: dep.requirements, + package_manager: dep.package_manager, + subdependency_metadata: dep.subdependency_metadata + ) + end + + index_of_same_version = + @all_versions.find_index { |other| other.version == dep.version } + + if index_of_same_version.nil? + @all_versions << dep + else + same_version = @all_versions[index_of_same_version] + @all_versions[index_of_same_version] = combined_dependency(same_version, dep) end - subdependency_metadata = ( - (old_dep.subdependency_metadata || []) + - (new_dep.subdependency_metadata || []) - ).uniq - - Dependency.new( - name: old_dep.name, - version: new_version, - requirements: (old_dep.requirements + new_dep.requirements).uniq, - package_manager: package_manager, - subdependency_metadata: subdependency_metadata - ) - end + self + end + + private + + # Produces a new dependency by merging the attributes of `old_dep` with those of + # `new_dep`. Requirements and subdependency metadata will be combined and deduped. + # The version of the combined dependency is determined by the logic below. + def combined_dependency(old_dep, new_dep) + version = if old_dep.top_level? # Prefer a direct dependency over a transitive one + old_dep.version || new_dep.version + elsif !version_class.correct?(new_dep.version) + old_dep.version + elsif !version_class.correct?(old_dep.version) + new_dep.version + elsif version_class.new(new_dep.version) > version_class.new(old_dep.version) + old_dep.version + else + new_dep.version + end + requirements = (old_dep.requirements + new_dep.requirements).uniq + subdependency_metadata = ( + (old_dep.subdependency_metadata || []) + + (new_dep.subdependency_metadata || []) + ).uniq + + Dependency.new( + name: old_dep.name, + version: version, + requirements: requirements, + package_manager: old_dep.package_manager, + subdependency_metadata: subdependency_metadata + ) + end - # rubocop:enable Metrics/PerceivedComplexity + def version_class + @version_class ||= Utils.version_class_for_package_manager(@combined.package_manager) + end + end + private_constant :DependencySlot end end end diff --git a/common/lib/dependabot/file_updaters/base.rb b/common/lib/dependabot/file_updaters/base.rb index 5d8f3549da7..90f7fe36086 100644 --- a/common/lib/dependabot/file_updaters/base.rb +++ b/common/lib/dependabot/file_updaters/base.rb @@ -3,16 +3,20 @@ module Dependabot module FileUpdaters class Base - attr_reader :dependencies, :dependency_files, :credentials + attr_reader :dependencies, :dependency_files, :repo_contents_path, + :credentials, :options def self.updated_files_regex raise NotImplementedError end - def initialize(dependencies:, dependency_files:, credentials:) + def initialize(dependencies:, dependency_files:, repo_contents_path: nil, + credentials:, options: {}) @dependencies = dependencies @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials + @options = options check_required_files end diff --git a/common/lib/dependabot/file_updaters/vendor_updater.rb b/common/lib/dependabot/file_updaters/vendor_updater.rb new file mode 100644 index 00000000000..a8fc743316b --- /dev/null +++ b/common/lib/dependabot/file_updaters/vendor_updater.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require "dependabot/dependency_file" + +module Dependabot + module FileUpdaters + class VendorUpdater + def initialize(repo_contents_path:, vendor_dir:) + @repo_contents_path = repo_contents_path + @vendor_dir = vendor_dir + end + + # Returns changed files in the vendor/cache folder + # + # @param base_directory [String] Update config base directory + # @return [Array] + def updated_vendor_cache_files(base_directory:) + return [] unless repo_contents_path && vendor_dir + + Dir.chdir(repo_contents_path) do + # rubocop:disable Performance/DeletePrefix + relative_dir = Pathname.new(base_directory).sub(%r{\A/}, "").join(vendor_dir) + # rubocop:enable Performance/DeletePrefix + + status = SharedHelpers.run_shell_command( + "git status --untracked-files all --porcelain v1 #{relative_dir}", + fingerprint: "git status --untracked-files all --porcelain v1 " + ) + changed_paths = status.split("\n").map(&:split) + changed_paths.map do |type, path| + # The following types are possible to be returned: + # M = Modified = Default for DependencyFile + # D = Deleted + # ?? = Untracked = Created + operation = Dependabot::DependencyFile::Operation::UPDATE + operation = Dependabot::DependencyFile::Operation::DELETE if type == "D" + operation = Dependabot::DependencyFile::Operation::CREATE if type == "??" + encoding = "" + encoded_content = File.read(path) unless operation == Dependabot::DependencyFile::Operation::DELETE + if binary_file?(path) + encoding = Dependabot::DependencyFile::ContentEncoding::BASE64 + if operation != Dependabot::DependencyFile::Operation::DELETE + encoded_content = Base64.encode64(encoded_content) + end + end + + project_root = + Pathname.new(File.expand_path(File.join(Dir.pwd, base_directory))) + file_path = + Pathname.new(path).expand_path.relative_path_from(project_root) + + Dependabot::DependencyFile.new( + name: file_path.to_s, + content: encoded_content, + directory: base_directory, + operation: operation, + content_encoding: encoding + ) + end + end + end + + private + + TEXT_ENCODINGS = %w(us-ascii utf-8).freeze + + attr_reader :repo_contents_path, :vendor_dir + + def binary_file?(path) + return false unless File.exist?(path) + + command = SharedHelpers.escape_command("file -b --mime-encoding #{path}") + encoding = `#{command}`.strip + + !TEXT_ENCODINGS.include?(encoding) + end + end + end +end diff --git a/common/lib/dependabot/git_commit_checker.rb b/common/lib/dependabot/git_commit_checker.rb index e284ba923c4..35b1b62401e 100644 --- a/common/lib/dependabot/git_commit_checker.rb +++ b/common/lib/dependabot/git_commit_checker.rb @@ -19,17 +19,16 @@ class GitCommitChecker | [0-9]+\.[0-9]+(?:\.[a-z0-9\-]+)* )$ - /ix.freeze + /ix def initialize(dependency:, credentials:, ignored_versions: [], raise_on_ignored: false, - requirement_class: nil, version_class: nil) + consider_version_branches_pinned: false) @dependency = dependency @credentials = credentials @ignored_versions = ignored_versions @raise_on_ignored = raise_on_ignored - @requirement_class = requirement_class - @version_class = version_class + @consider_version_branches_pinned = consider_version_branches_pinned end def git_dependency? @@ -49,21 +48,36 @@ def pinned? return true if branch return true if dependency.version&.start_with?(ref) - # Check the specified `ref` isn't actually a branch - !local_upload_pack.match?("refs/heads/#{ref}") + # If the specified `ref` is actually a tag, we're pinned + return true if local_upload_pack.match?(%r{ refs/tags/#{ref}$}) + + # Assume we're pinned unless the specified `ref` is actually a branch + return true unless local_upload_pack.match?(%r{ refs/heads/#{ref}$}) + + # TODO: Research whether considering branches that look like versions pinned makes sense for all ecosystems + @consider_version_branches_pinned && version_tag?(ref) end def pinned_ref_looks_like_version? return false unless pinned? - dependency_source_details.fetch(:ref).match?(VERSION_REGEX) + version_tag?(dependency_source_details.fetch(:ref)) end def pinned_ref_looks_like_commit_sha? - return false unless pinned? + ref = dependency_source_details.fetch(:ref) + ref_looks_like_commit_sha?(ref) + end + def head_commit_for_pinned_ref ref = dependency_source_details.fetch(:ref) - return false unless ref.match?(/^[0-9a-f]{6,40}$/) + local_repo_git_metadata_fetcher.head_commit_for_ref_sha(ref) + end + + def ref_looks_like_commit_sha?(ref) + return false unless ref&.match?(/^[0-9a-f]{6,40}$/) + + return false unless pinned? local_repo_git_metadata_fetcher.head_commit_for_ref(ref).nil? end @@ -75,44 +89,70 @@ def branch_or_ref_in_release?(version) def head_commit_for_current_branch ref = ref_or_branch || "HEAD" - if pinned? - return dependency.version || - local_repo_git_metadata_fetcher.head_commit_for_ref(ref) - end - - sha = local_repo_git_metadata_fetcher.head_commit_for_ref(ref) - return sha if sha + sha = head_commit_for_local_branch(ref) + return sha if pinned? || sha raise Dependabot::GitDependencyReferenceNotFound, dependency.name end + def head_commit_for_local_branch(name) + local_repo_git_metadata_fetcher.head_commit_for_ref(name) + end + + def local_ref_for_latest_version_matching_existing_precision + allowed_refs = local_tag_for_pinned_sha ? allowed_version_tags : allowed_version_refs + + max_local_tag_for_current_precision(allowed_refs) + end + def local_tag_for_latest_version - tags = - local_tags. - select { |t| version_tag?(t.name) && matches_existing_prefix?(t.name) } - filtered = tags. - reject { |t| tag_included_in_ignore_reqs?(t) } - if @raise_on_ignored && tags.any? && filtered.empty? - raise Dependabot::AllVersionsIgnored + max_local_tag(allowed_version_tags) + end + + def local_tags_for_allowed_versions_matching_existing_precision + select_matching_existing_precision(allowed_version_tags).map { |t| to_local_tag(t) } + end + + def local_tags_for_allowed_versions + allowed_version_tags.map { |t| to_local_tag(t) } + end + + def allowed_version_tags + allowed_versions(local_tags) + end + + def allowed_version_refs + allowed_versions(local_refs) + end + + def current_version + return unless dependency.version && version_tag?(dependency.version) + + version_from_ref(dependency.version) + end + + def filter_lower_versions(tags) + return tags unless current_version + + versions = tags.map do |t| + version_from_tag(t) end - tag = filtered. - reject { |t| tag_is_prerelease?(t) && !wants_prerelease? }. - max_by do |t| - version = t.name.match(VERSION_REGEX).named_captures. - fetch("version") - version_class.new(version) - end + versions.select do |version| + version > current_version + end + end - return unless tag + def most_specific_tag_equivalent_to_pinned_ref + commit_sha = head_commit_for_local_branch(dependency_source_details.fetch(:ref)) + most_specific_version_tag_for_sha(commit_sha) + end - version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") - { - tag: tag.name, - version: version_class.new(version), - commit_sha: tag.commit_sha, - tag_sha: tag.tag_sha - } + def local_tag_for_pinned_sha + return unless pinned_ref_looks_like_commit_sha? + + commit_sha = dependency_source_details.fetch(:ref) + most_specific_version_tag_for_sha(commit_sha) end def git_repo_reachable? @@ -126,6 +166,49 @@ def git_repo_reachable? attr_reader :dependency, :credentials, :ignored_versions + def max_local_tag_for_current_precision(tags) + max_local_tag(select_matching_existing_precision(tags)) + end + + def max_local_tag(tags) + max_version_tag = tags.max_by { |t| version_from_tag(t) } + + to_local_tag(max_version_tag) + end + + # Find the latest version with the same precision as the pinned version. + def select_matching_existing_precision(tags) + current_precision = precision(dependency.version) + + tags.select { |tag| precision(scan_version(tag.name)) == current_precision } + end + + def precision(version) + version.split(".").length + end + + def most_specific_version_tag_for_sha(commit_sha) + tags = local_tags.select { |t| t.commit_sha == commit_sha && version_class.correct?(t.name) }. + sort_by { |t| version_class.new(t.name) } + return if tags.empty? + + tags[-1].name + end + + def allowed_versions(local_tags) + tags = + local_tags. + select { |t| version_tag?(t.name) && matches_existing_prefix?(t.name) } + filtered = tags. + reject { |t| tag_included_in_ignore_requirements?(t) } + if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(tags).any? + raise Dependabot::AllVersionsIgnored + end + + filtered. + reject { |t| tag_is_prerelease?(t) && !wants_prerelease? } + end + def pinned_ref_in_release?(version) raise "Not a git dependency!" unless git_dependency? @@ -164,9 +247,15 @@ def local_upload_pack local_repo_git_metadata_fetcher.upload_pack end + def local_refs + handle_tag_prefix(local_repo_git_metadata_fetcher.refs_for_upload_pack) + end + def local_tags - tags = local_repo_git_metadata_fetcher.tags + handle_tag_prefix(local_repo_git_metadata_fetcher.tags_for_upload_pack) + end + def handle_tag_prefix(tags) if dependency_source_details&.fetch(:ref, nil)&.start_with?("tags/") tags = tags.map do |tag| tag.dup.tap { |t| t.name = "tags/#{tag.name}" } @@ -182,6 +271,7 @@ def commit_included_in_tag?(tag:, commit:, allow_identical: false) when "github" then github_commit_comparison_status(tag, commit) when "gitlab" then gitlab_commit_comparison_status(tag, commit) when "bitbucket" then bitbucket_commit_comparison_status(tag, commit) + when "codecommit" then nil # TODO: get codecommit comparison status else raise "Unknown source" end @@ -209,13 +299,14 @@ def gitlab_commit_comparison_status(ref1, ref2) if comparison.commits.none? then "behind" elsif comparison.compare_same_ref then "identical" - else "ahead" + else + "ahead" end end def bitbucket_commit_comparison_status(ref1, ref2) - url = "https://api.bitbucket.org/2.0/repositories/"\ - "#{listing_source_repo}/commits/?"\ + url = "https://api.bitbucket.org/2.0/repositories/" \ + "#{listing_source_repo}/commits/?" \ "include=#{ref2}&exclude=#{ref1}" client = Clients::BitbucketWithRetries. @@ -226,13 +317,16 @@ def bitbucket_commit_comparison_status(ref1, ref2) # Conservatively assume that ref2 is ahead in the equality case, of # if we get an unexpected format (e.g., due to a 404) if JSON.parse(response.body).fetch("values", ["x"]).none? then "behind" - else "ahead" + else + "ahead" end end def dependency_source_details sources = - dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact + dependency.requirements. + map { |requirement| requirement.fetch(:source) }.uniq.compact. + select { |source| source[:type] == "git" } return sources.first if sources.count <= 1 @@ -264,6 +358,18 @@ def matches_existing_prefix?(tag) tag.gsub(VERSION_REGEX, "").gsub(/v$/i, "") end + def to_local_tag(tag) + return unless tag + + version = version_from_tag(tag) + { + tag: tag.name, + version: version, + commit_sha: tag.commit_sha, + tag_sha: tag.ref_sha + } + end + def listing_source_url @listing_source_url ||= begin @@ -298,17 +404,19 @@ def listing_tag_for_version(version) def listing_tags return [] unless listing_source_url - tags = listing_repo_git_metadata_fetcher.tags + @listing_tags ||= begin + tags = listing_repo_git_metadata_fetcher.tags - if dependency_source_details&.fetch(:ref, nil)&.start_with?("tags/") - tags = tags.map do |tag| - tag.dup.tap { |t| t.name = "tags/#{tag.name}" } + if dependency_source_details&.fetch(:ref, nil)&.start_with?("tags/") + tags = tags.map do |tag| + tag.dup.tap { |t| t.name = "tags/#{tag.name}" } + end end - end - tags - rescue GitDependenciesNotReachable - [] + tags + rescue GitDependenciesNotReachable + [] + end end def listing_upload_pack @@ -317,39 +425,45 @@ def listing_upload_pack listing_repo_git_metadata_fetcher.upload_pack end - def ignore_reqs - ignored_versions.map { |req| requirement_class.new(req.split(",")) } + def ignore_requirements + ignored_versions.flat_map { |req| requirement_class.requirements_array(req) } end def wants_prerelease? return false unless dependency_source_details&.fetch(:ref, nil) return false unless pinned_ref_looks_like_version? - version = dependency_source_details.fetch(:ref).match(VERSION_REGEX). - named_captures.fetch("version") - version_class.new(version).prerelease? + version = version_from_ref(dependency_source_details.fetch(:ref)) + version.prerelease? end - def tag_included_in_ignore_reqs?(tag) - version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") - ignore_reqs.any? { |r| r.satisfied_by?(version_class.new(version)) } + def tag_included_in_ignore_requirements?(tag) + version = version_from_tag(tag) + ignore_requirements.any? { |r| r.satisfied_by?(version) } end def tag_is_prerelease?(tag) - version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") - version_class.new(version).prerelease? + version_from_tag(tag).prerelease? end - def version_class - return @version_class if @version_class + def version_from_tag(tag) + version_from_ref(tag.name) + end - Utils.version_class_for_package_manager(dependency.package_manager) + def version_from_ref(name) + version_class.new(scan_version(name)) end - def requirement_class - return @requirement_class if @requirement_class + def scan_version(name) + name.match(VERSION_REGEX).named_captures.fetch("version") + end - Utils.requirement_class_for_package_manager(dependency.package_manager) + def version_class + @version_class ||= Utils.version_class_for_package_manager(dependency.package_manager) + end + + def requirement_class + @requirement_class ||= Utils.requirement_class_for_package_manager(dependency.package_manager) end def local_repo_git_metadata_fetcher diff --git a/common/lib/dependabot/git_metadata_fetcher.rb b/common/lib/dependabot/git_metadata_fetcher.rb index 78eb8ba0fac..87c519bcec1 100644 --- a/common/lib/dependabot/git_metadata_fetcher.rb +++ b/common/lib/dependabot/git_metadata_fetcher.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true require "excon" +require "open3" require "dependabot/errors" module Dependabot class GitMetadataFetcher - KNOWN_HOSTS = /github\.com|bitbucket\.org|gitlab.com/i.freeze + KNOWN_HOSTS = /github\.com|bitbucket\.org|gitlab.com/i def initialize(url:, credentials:) @url = url @@ -21,7 +22,21 @@ def upload_pack def tags return [] unless upload_pack - @tags ||= tags_for_upload_pack + @tags ||= tags_for_upload_pack.map do |ref| + OpenStruct.new( + name: ref.name, + tag_sha: ref.ref_sha, + commit_sha: ref.commit_sha + ) + end + end + + def tags_for_upload_pack + @tags_for_upload_pack ||= refs_for_upload_pack.select { |ref| ref.ref_type == :tag } + end + + def refs_for_upload_pack + @refs_for_upload_pack ||= parse_refs_for_upload_pack end def ref_names @@ -43,22 +58,26 @@ def head_commit_for_ref(ref) commit_sha end + def head_commit_for_ref_sha(ref) + refs_for_upload_pack. + find { |r| r.ref_sha == ref }&. + commit_sha + end + private attr_reader :url, :credentials - # rubocop:disable Metrics/PerceivedComplexity def fetch_upload_pack_for(uri) response = fetch_raw_upload_pack_for(uri) return response.body if response.status == 200 - unless uri.match?(KNOWN_HOSTS) - raise Dependabot::GitDependenciesNotReachable, [uri] - end + response_with_git = fetch_raw_upload_pack_with_git_for(uri) + return response_with_git.body if response_with_git.status == 200 - if response.status < 400 - raise "Unexpected response: #{response.status} - #{response.body}" - end + raise Dependabot::GitDependenciesNotReachable, [uri] unless uri.match?(KNOWN_HOSTS) + + raise "Unexpected response: #{response.status} - #{response.body}" if response.status < 400 if uri.match?(/github\.com/i) response = response.data @@ -70,15 +89,10 @@ def fetch_upload_pack_for(uri) raise Dependabot::GitDependenciesNotReachable, [uri] rescue Excon::Error::Socket, Excon::Error::Timeout - retry_count ||= 0 - retry_count += 1 - - sleep(rand(0.9)) && retry if retry_count <= 2 && uri.match?(KNOWN_HOSTS) raise if uri.match?(KNOWN_HOSTS) raise Dependabot::GitDependenciesNotReachable, [uri] end - # rubocop:enable Metrics/PerceivedComplexity def fetch_raw_upload_pack_for(uri) url = service_pack_uri(uri) @@ -90,30 +104,32 @@ def fetch_raw_upload_pack_for(uri) ) end - def tags_for_upload_pack - refs_for_upload_pack. - select { |ref| ref.ref_type == :tag }. - map do |ref| - OpenStruct.new( - name: ref.name, - tag_sha: ref.ref_sha, - commit_sha: ref.commit_sha - ) - end - end + def fetch_raw_upload_pack_with_git_for(uri) + service_pack_uri = uri + service_pack_uri += ".git" unless service_pack_uri.end_with?(".git") - def refs_for_upload_pack - @refs_for_upload_pack ||= parse_refs_for_upload_pack + env = { "PATH" => ENV.fetch("PATH", nil) } + command = "git ls-remote #{service_pack_uri}" + command = SharedHelpers.escape_command(command) + + stdout, stderr, process = Open3.capture3(env, command) + # package the command response like a HTTP response so error handling + # remains unchanged + if process.success? + OpenStruct.new(body: stdout, status: 200) + else + OpenStruct.new(body: stderr, status: 500) + end end def parse_refs_for_upload_pack peeled_lines = [] result = upload_pack.lines.each_with_object({}) do |line, res| - full_ref_name = line.split(" ").last + full_ref_name = line.split.last next unless full_ref_name.start_with?("refs/tags", "refs/heads") - peeled_lines << line && next if line.strip.end_with?("^{}") + (peeled_lines << line) && next if line.strip.end_with?("^{}") ref_name = full_ref_name.sub(%r{^refs/(tags|heads)/}, "").strip sha = sha_for_update_pack_line(line) @@ -149,7 +165,8 @@ def service_pack_uri(uri) def uri_with_auth(uri) bare_uri = if uri.include?("git@") then uri.split("git@").last.sub(%r{:/?}, "/") - else uri.sub(%r{.*?://}, "") + else + uri.sub(%r{.*?://}, "") end cred = credentials.select { |c| c["type"] == "git_source" }. find { |c| bare_uri.start_with?(c["host"]) } @@ -178,12 +195,12 @@ def scheme_for_uri(uri) end def sha_for_update_pack_line(line) - line.split(" ").first.chars.last(40).join + line.split.first.chars.last(40).join end def excon_defaults # Some git hosts are slow when returning a large number of tags - SharedHelpers.excon_defaults.merge(read_timeout: 20) + SharedHelpers.excon_defaults(read_timeout: 20) end end end diff --git a/common/lib/dependabot/logger.rb b/common/lib/dependabot/logger.rb new file mode 100644 index 00000000000..bbd18484033 --- /dev/null +++ b/common/lib/dependabot/logger.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "logger" + +module Dependabot + def self.logger + @logger ||= Logger.new(nil) + end + + def self.logger=(logger) + @logger = logger + end +end diff --git a/common/lib/dependabot/metadata_finders/base.rb b/common/lib/dependabot/metadata_finders/base.rb index 2c0ea68aa46..426da620798 100644 --- a/common/lib/dependabot/metadata_finders/base.rb +++ b/common/lib/dependabot/metadata_finders/base.rb @@ -9,7 +9,7 @@ class Base require "dependabot/metadata_finders/base/release_finder" require "dependabot/metadata_finders/base/commits_finder" - PACKAGE_MANAGERS_WITH_RELIABLE_DIRECTORIES = %w(npm_and_yarn).freeze + PACKAGE_MANAGERS_WITH_RELIABLE_DIRECTORIES = %w(npm_and_yarn pub).freeze attr_reader :dependency, :credentials diff --git a/common/lib/dependabot/metadata_finders/base/changelog_finder.rb b/common/lib/dependabot/metadata_finders/base/changelog_finder.rb index ec0a90eafef..e3322791302 100644 --- a/common/lib/dependabot/metadata_finders/base/changelog_finder.rb +++ b/common/lib/dependabot/metadata_finders/base/changelog_finder.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require "excon" -require "pandoc-ruby" require "dependabot/clients/github_with_retries" require "dependabot/clients/gitlab_with_retries" @@ -17,7 +16,7 @@ class ChangelogFinder # Earlier entries are preferred CHANGELOG_NAMES = %w( - changelog news changes history release whatsnew + changelog news changes history release whatsnew releases ).freeze attr_reader :source, :dependency, :credentials, :suggested_changelog_url @@ -37,31 +36,10 @@ def changelog_url def changelog_text return unless full_changelog_text - pruned_text = ChangelogPruner.new( + ChangelogPruner.new( dependency: dependency, changelog_text: full_changelog_text ).pruned_text - - return pruned_text unless changelog.name.end_with?(".rst") - - begin - PandocRuby.convert( - pruned_text, - from: :rst, - to: :markdown, - wrap: :none, - timeout: 10 - ) - rescue Errno::ENOENT => e - raise unless e.message == "No such file or directory - pandoc" - - # If pandoc isn't installed just return the rst - pruned_text - rescue RuntimeError => e - raise unless e.message.include?("Pandoc timed out") - - pruned_text - end end def upgrade_guide_url @@ -100,9 +78,7 @@ def changelog # rubocop:enable Metrics/PerceivedComplexity def changelog_from_suggested_url - if defined?(@changelog_from_suggested_url) - return @changelog_from_suggested_url - end + return @changelog_from_suggested_url if defined?(@changelog_from_suggested_url) return unless suggested_changelog_url # TODO: Support other providers @@ -143,6 +119,7 @@ def changelog_from_ref(ref) select_best_changelog(files) end + # rubocop:disable Metrics/PerceivedComplexity def select_best_changelog(files) CHANGELOG_NAMES.each do |name| candidates = files.select { |f| f.name =~ /#{name}/i } @@ -163,6 +140,7 @@ def select_best_changelog(files) nil end + # rubocop:enable Metrics/PerceivedComplexity def tag_for_new_version @tag_for_new_version ||= @@ -189,6 +167,7 @@ def fetch_file_text(file) when "github" then fetch_github_file(file) when "gitlab" then fetch_gitlab_file(file) when "bitbucket" then fetch_bitbucket_file(file) + when "codecommit" then nil # TODO: git file from codecommit else raise "Unsupported provider '#{provider}'" end end @@ -242,6 +221,7 @@ def fetch_dependency_file_list(ref) when "bitbucket" then fetch_bitbucket_file_list when "gitlab" then fetch_gitlab_file_list when "azure" then [] # TODO: Fetch files from Azure + when "codecommit" then [] # TODO: Fetch Files from Codecommit else raise "Unexpected repo provider '#{source.provider}'" end end @@ -259,7 +239,7 @@ def fetch_github_file_list(ref) files += github_client.contents(source.repo, opts) files.uniq.each do |f| - next unless %w(doc docs).include?(f.name) && f.type == "dir" + next unless f.type == "dir" && f.name.match?(/docs?/o) opts = { path: f.path, ref: ref }.compact files += github_client.contents(source.repo, opts) @@ -293,6 +273,7 @@ def fetch_bitbucket_file_list end def fetch_gitlab_file_list + branch = default_gitlab_branch gitlab_client.repo_tree(source.repo).map do |file| type = case file.type when "blob" then "file" @@ -303,8 +284,8 @@ def fetch_gitlab_file_list name: file.name, type: type, size: 100, # GitLab doesn't return file size - html_url: "#{source.url}/blob/master/#{file.path}", - download_url: "#{source.url}/raw/master/#{file.path}" + html_url: "#{source.url}/blob/#{branch}/#{file.path}", + download_url: "#{source.url}/raw/#{branch}/#{file.path}" ) end rescue Gitlab::Error::NotFound @@ -319,16 +300,16 @@ def new_version end def previous_ref - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end @@ -377,6 +358,11 @@ def default_bitbucket_branch @default_bitbucket_branch ||= bitbucket_client.fetch_default_branch(source.repo) end + + def default_gitlab_branch + @default_gitlab_branch ||= + gitlab_client.fetch_default_branch(source.repo) + end end end end diff --git a/common/lib/dependabot/metadata_finders/base/changelog_pruner.rb b/common/lib/dependabot/metadata_finders/base/changelog_pruner.rb index 5fda592a42c..1c6a1de007c 100644 --- a/common/lib/dependabot/metadata_finders/base/changelog_pruner.rb +++ b/common/lib/dependabot/metadata_finders/base/changelog_pruner.rb @@ -21,7 +21,6 @@ def includes_previous_version? !old_version_changelog_line.nil? end - # rubocop:disable Metrics/PerceivedComplexity def pruned_text changelog_lines = changelog_text.split("\n") @@ -51,7 +50,6 @@ def pruned_text changelog_lines.slice(slice_range).join("\n").sub(/\n*\z/, "") end - # rubocop:enable Metrics/PerceivedComplexity private @@ -139,16 +137,16 @@ def new_version end def previous_ref - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end diff --git a/common/lib/dependabot/metadata_finders/base/commits_finder.rb b/common/lib/dependabot/metadata_finders/base/commits_finder.rb index 18d4a47b69a..fed88a55f77 100644 --- a/common/lib/dependabot/metadata_finders/base/commits_finder.rb +++ b/common/lib/dependabot/metadata_finders/base/commits_finder.rb @@ -23,6 +23,7 @@ def initialize(source:, dependency:, credentials:) def commits_url return unless source return if source.provider == "azure" # TODO: Fetch Azure commits + return if source.provider == "codecommit" # TODO: Fetch Codecommit commits path = case source.provider @@ -44,6 +45,7 @@ def commits when "bitbucket" then fetch_bitbucket_commits when "gitlab" then fetch_gitlab_commits when "azure" then [] # TODO: Fetch Azure commits + when "codecommit" then [] # TODO: Fetch Codecommit commits else raise "Unexpected source provider '#{source.provider}'" end end @@ -51,9 +53,7 @@ def commits def new_tag new_version = dependency.version - if git_source?(dependency.requirements) && git_sha?(new_version) - return new_version - end + return new_version if git_source?(dependency.requirements) && git_sha?(new_version) return new_ref if new_ref && ref_changed? @@ -98,9 +98,7 @@ def lowest_tag_satisfying_previous_requirements end def version_from_tag(tag) - if version_class.correct?(tag.gsub(/^v/, "")) - version_class.new(tag.gsub(/^v/, "")) - end + version_class.new(tag.gsub(/^v/, "")) if version_class.correct?(tag.gsub(/^v/, "")) return unless tag.gsub(/^[^\d]*/, "").length > 1 return unless version_class.correct?(tag.gsub(/^[^\d]*/, "")) @@ -138,27 +136,25 @@ def ref_changed? def previous_ref return unless git_source?(dependency.previous_requirements) - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref return unless git_source?(dependency.previous_requirements) - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end def tag_matches_version?(tag, version) return false unless version - unless version_class.correct?(version) - return tag.match?(/(?:[^0-9\.]|\A)#{Regexp.escape(version)}\z/) - end + return tag.match?(/(?:[^0-9\.]|\A)#{Regexp.escape(version)}\z/) unless version_class.correct?(version) version_regex = GitCommitChecker::VERSION_REGEX return false unless tag.match?(version_regex) @@ -216,7 +212,7 @@ def gitlab_compare_path(new_tag, previous_tag) elsif new_tag "commits/#{new_tag}" else - "commits/master" + "commits/#{default_gitlab_branch}" end end @@ -232,7 +228,7 @@ def fetch_github_commits previous_commit_shas = github_client.commits(repo, **args).map(&:sha) - # Note: We reverse this so it's consistent with the array we get + # NOTE: We reverse this so it's consistent with the array we get # from `github_client.compare(...)` args = { sha: new_tag, path: path }.compact github_client. @@ -327,6 +323,11 @@ def reliable_source_directory? MetadataFinders::Base::PACKAGE_MANAGERS_WITH_RELIABLE_DIRECTORIES. include?(dependency.package_manager) end + + def default_gitlab_branch + @default_gitlab_branch ||= + gitlab_client.fetch_default_branch(source.repo) + end end end end diff --git a/common/lib/dependabot/metadata_finders/base/release_finder.rb b/common/lib/dependabot/metadata_finders/base/release_finder.rb index 40117456656..01d31f69385 100644 --- a/common/lib/dependabot/metadata_finders/base/release_finder.rb +++ b/common/lib/dependabot/metadata_finders/base/release_finder.rb @@ -22,9 +22,8 @@ def releases_url case source.provider when "github" then "#{source.url}/releases" - when "gitlab" then "#{source.url}/tags" - when "bitbucket" then nil - when "azure" then "#{source.url}/tags" + when "gitlab", "azure" then "#{source.url}/tags" + when "bitbucket", "codecommit" then nil else raise "Unexpected repo provider '#{source.provider}'" end end @@ -167,7 +166,7 @@ def release_for_version(version) def serialize_release(release) rel = release - title = "## #{rel.name.to_s != '' ? rel.name : rel.tag_name}\n" + title = "## #{rel.name.to_s == '' ? rel.tag_name : rel.name}\n" body = if rel.body.to_s.gsub(/\n*\z/m, "") == "" "No release notes provided." else @@ -178,7 +177,7 @@ def serialize_release(release) end def release_body_includes_title?(release) - title = release.name.to_s != "" ? release.name : release.tag_name + title = release.name.to_s == "" ? release.tag_name : release.name release.body.to_s.match?(/\A\s*\#*\s*#{Regexp.quote(title)}/m) end @@ -195,9 +194,10 @@ def fetch_dependency_releases case source.provider when "github" then fetch_github_releases - when "bitbucket" then [] # Bitbucket doesn't support releases + # Bitbucket and CodeCommit don't support releases and + # Azure can't list API for annotated tags + when "bitbucket", "azure", "codecommit" then [] when "gitlab" then fetch_gitlab_releases - when "azure" then [] # Azure can't list API for annotated tags else raise "Unexpected repo provider '#{source.provider}'" end end @@ -275,16 +275,16 @@ def new_version end def previous_ref - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end diff --git a/common/lib/dependabot/notifications.rb b/common/lib/dependabot/notifications.rb new file mode 100644 index 00000000000..f398e510a92 --- /dev/null +++ b/common/lib/dependabot/notifications.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "active_support" +require "active_support/notifications" + +module Dependabot + module Notifications + FILE_PARSER_PACKAGE_MANAGER_VERSION_PARSED = "dependabot.file_parser.package_manager_version_parsed" + end + + def self.instrument(name, payload = {}) + ActiveSupport::Notifications.instrument(name, payload) + end + + def self.subscribe(pattern = nil, callback = nil, &block) + ActiveSupport::Notifications.subscribe(pattern, callback, &block) + end +end diff --git a/common/lib/dependabot/pull_request_creator.rb b/common/lib/dependabot/pull_request_creator.rb index f2ee07299ea..a264b8b23dd 100644 --- a/common/lib/dependabot/pull_request_creator.rb +++ b/common/lib/dependabot/pull_request_creator.rb @@ -5,6 +5,7 @@ module Dependabot class PullRequestCreator require "dependabot/pull_request_creator/azure" + require "dependabot/pull_request_creator/bitbucket" require "dependabot/pull_request_creator/codecommit" require "dependabot/pull_request_creator/github" require "dependabot/pull_request_creator/gitlab" @@ -12,18 +13,43 @@ class PullRequestCreator require "dependabot/pull_request_creator/branch_namer" require "dependabot/pull_request_creator/labeler" + # Dependabot programmatically creates PRs which often include a large + # number of links to objects on `github.com`. GitHub hydrates these into + # rich links that leave a 'mention' on target Issues/Pull Requests. + # + # Due to the volume and nature of Dependabot PRs, these mentions are not + # useful and can overwhelm maintainers, so we use a redirection service + # to avoid enrichment. + # + # If you wish to disable this behaviour when using Dependabot Core directly, + # pass a nil value when initialising this class. + DEFAULT_GITHUB_REDIRECTION_SERVICE = "redirect.github.com" + class RepoNotFound < StandardError; end + class RepoArchived < StandardError; end + class RepoDisabled < StandardError; end + class NoHistoryInCommon < StandardError; end + # AnnotationError is raised if a PR was created, but failed annotation + class AnnotationError < StandardError + attr_reader :cause, :pull_request + def initialize(cause, pull_request) + super(cause.message) + @cause = cause + @pull_request = pull_request + end + end + attr_reader :source, :dependencies, :files, :base_commit, :credentials, :pr_message_header, :pr_message_footer, :custom_labels, :author_details, :signature_key, :commit_message_options, :vulnerabilities_fixed, :reviewers, :assignees, :milestone, :branch_name_separator, - :branch_name_prefix, :github_redirection_service, - :custom_headers + :branch_name_prefix, :branch_name_max_length, :github_redirection_service, + :custom_headers, :provider_metadata def initialize(source:, base_commit:, dependencies:, files:, credentials:, pr_message_header: nil, pr_message_footer: nil, @@ -31,9 +57,11 @@ def initialize(source:, base_commit:, dependencies:, files:, credentials:, commit_message_options: {}, vulnerabilities_fixed: {}, reviewers: nil, assignees: nil, milestone: nil, branch_name_separator: "/", branch_name_prefix: "dependabot", - label_language: false, automerge_candidate: false, - github_redirection_service: "github-redirect.dependabot.com", - custom_headers: nil, require_up_to_date_base: false) + branch_name_max_length: nil, label_language: false, + automerge_candidate: false, + github_redirection_service: DEFAULT_GITHUB_REDIRECTION_SERVICE, + custom_headers: nil, require_up_to_date_base: false, + provider_metadata: {}, message: nil) @dependencies = dependencies @source = source @base_commit = base_commit @@ -51,17 +79,20 @@ def initialize(source:, base_commit:, dependencies:, files:, credentials:, @vulnerabilities_fixed = vulnerabilities_fixed @branch_name_separator = branch_name_separator @branch_name_prefix = branch_name_prefix + @branch_name_max_length = branch_name_max_length @label_language = label_language @automerge_candidate = automerge_candidate @github_redirection_service = github_redirection_service @custom_headers = custom_headers @require_up_to_date_base = require_up_to_date_base + @provider_metadata = provider_metadata + @message = message check_dependencies_have_previous_version end def check_dependencies_have_previous_version - return if library? && dependencies.all? { |d| requirements_changed?(d) } + return if dependencies.all? { |d| requirements_changed?(d) } return if dependencies.all?(&:previous_version) raise "Dependencies must have a previous version or changed " \ @@ -73,6 +104,7 @@ def create when "github" then github_creator.create when "gitlab" then gitlab_creator.create when "azure" then azure_creator.create + when "bitbucket" then bitbucket_creator.create when "codecommit" then codecommit_creator.create else raise "Unsupported provider #{source.provider}" end @@ -99,9 +131,9 @@ def github_creator base_commit: base_commit, credentials: credentials, files: files, - commit_message: message_builder.commit_message, - pr_description: message_builder.pr_message, - pr_name: message_builder.pr_name, + commit_message: message.commit_message, + pr_description: message.pr_message, + pr_name: message.pr_name, author_details: author_details, signature_key: signature_key, labeler: labeler, @@ -120,14 +152,15 @@ def gitlab_creator base_commit: base_commit, credentials: credentials, files: files, - commit_message: message_builder.commit_message, - pr_description: message_builder.pr_message, - pr_name: message_builder.pr_name, + commit_message: message.commit_message, + pr_description: message.pr_message, + pr_name: message.pr_name, author_details: author_details, labeler: labeler, approvers: reviewers, assignees: assignees, - milestone: milestone + milestone: milestone, + target_project_id: provider_metadata[:target_project_id] ) end @@ -138,11 +171,30 @@ def azure_creator base_commit: base_commit, credentials: credentials, files: files, - commit_message: message_builder.commit_message, - pr_description: message_builder.pr_message, - pr_name: message_builder.pr_name, + commit_message: message.commit_message, + pr_description: message.pr_message, + pr_name: message.pr_name, author_details: author_details, - labeler: labeler + labeler: labeler, + reviewers: reviewers, + assignees: assignees, + work_item: provider_metadata&.fetch(:work_item, nil) + ) + end + + def bitbucket_creator + Bitbucket.new( + source: source, + branch_name: branch_namer.new_branch_name, + base_commit: base_commit, + credentials: credentials, + files: files, + commit_message: message.commit_message, + pr_description: message.pr_message, + pr_name: message.pr_name, + author_details: author_details, + labeler: nil, + work_item: provider_metadata&.fetch(:work_item, nil) ) end @@ -153,17 +205,17 @@ def codecommit_creator base_commit: base_commit, credentials: credentials, files: files, - commit_message: message_builder.commit_message, - pr_description: message_builder.pr_message, - pr_name: message_builder.pr_name, + commit_message: message.commit_message, + pr_description: message.pr_message, + pr_name: message.pr_name, author_details: author_details, labeler: labeler, require_up_to_date_base: require_up_to_date_base? ) end - def message_builder - @message_builder || + def message + @message ||= MessageBuilder.new( source: source, dependencies: dependencies, @@ -184,7 +236,8 @@ def branch_namer files: files, target_branch: source.branch, separator: branch_name_separator, - prefix: branch_name_prefix + prefix: branch_name_prefix, + max_length: branch_name_max_length ) end @@ -201,12 +254,6 @@ def labeler ) end - def library? - return true if files.any? { |file| file.name.end_with?(".gemspec") } - - dependencies.any? { |d| !d.appears_in_lockfile? } - end - def includes_security_fixes? vulnerabilities_fixed.values.flatten.any? end diff --git a/common/lib/dependabot/pull_request_creator/azure.rb b/common/lib/dependabot/pull_request_creator/azure.rb index cc9613dc404..1a139bf3631 100644 --- a/common/lib/dependabot/pull_request_creator/azure.rb +++ b/common/lib/dependabot/pull_request_creator/azure.rb @@ -8,11 +8,11 @@ class PullRequestCreator class Azure attr_reader :source, :branch_name, :base_commit, :credentials, :files, :commit_message, :pr_description, :pr_name, - :author_details, :labeler + :author_details, :labeler, :reviewers, :assignees, :work_item def initialize(source:, branch_name:, base_commit:, credentials:, files:, commit_message:, pr_description:, pr_name:, - author_details:, labeler:) + author_details:, labeler:, reviewers: nil, assignees: nil, work_item: nil) @source = source @branch_name = branch_name @base_commit = base_commit @@ -23,6 +23,9 @@ def initialize(source:, branch_name:, base_commit:, credentials:, @pr_name = pr_name @author_details = author_details @labeler = labeler + @reviewers = reviewers + @assignees = assignees + @work_item = work_item end def create @@ -46,9 +49,7 @@ def azure_client_for_source end def branch_exists? - @branch_ref ||= azure_client_for_source.branch(branch_name) - - @branch_ref + azure_client_for_source.branch(branch_name) rescue ::Azure::Error::NotFound false end @@ -79,7 +80,10 @@ def create_pull_request branch_name, source.branch || default_branch, pr_description, - labeler.labels_for_pr + labeler.labels_for_pr, + reviewers, + assignees, + work_item ) end diff --git a/common/lib/dependabot/pull_request_creator/bitbucket.rb b/common/lib/dependabot/pull_request_creator/bitbucket.rb new file mode 100644 index 00000000000..c92590b596e --- /dev/null +++ b/common/lib/dependabot/pull_request_creator/bitbucket.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require "dependabot/clients/bitbucket" +require "dependabot/pull_request_creator" + +module Dependabot + class PullRequestCreator + class Bitbucket + attr_reader :source, :branch_name, :base_commit, :credentials, + :files, :commit_message, :pr_description, :pr_name, + :author_details, :labeler, :work_item + + def initialize(source:, branch_name:, base_commit:, credentials:, + files:, commit_message:, pr_description:, pr_name:, + author_details:, labeler: nil, work_item: nil) + @source = source + @branch_name = branch_name + @base_commit = base_commit + @credentials = credentials + @files = files + @commit_message = commit_message + @pr_description = pr_description + @pr_name = pr_name + @author_details = author_details + @labeler = labeler + @work_item = work_item + end + + def create + return if branch_exists? && pull_request_exists? + + # FIXME: Copied from Azure, but not verified whether this is true + # For Bitbucket we create or update a branch in the same request as creating + # a commit (so we don't need create or update branch logic here) + create_commit + + create_pull_request + end + + private + + def bitbucket_client_for_source + @bitbucket_client_for_source ||= + Dependabot::Clients::Bitbucket.for_source( + source: source, + credentials: credentials + ) + end + + def branch_exists? + bitbucket_client_for_source.branch(source.repo, branch_name) + rescue Clients::Bitbucket::NotFound + false + end + + def pull_request_exists? + bitbucket_client_for_source.pull_requests( + source.repo, + branch_name, + source.branch || default_branch + ).any? + end + + def create_commit + author = author_details&.slice(:name, :email) + author = nil unless author&.any? + + bitbucket_client_for_source.create_commit( + source.repo, + branch_name, + base_commit, + commit_message, + files, + author + ) + end + + def create_pull_request + bitbucket_client_for_source.create_pull_request( + source.repo, + pr_name, + branch_name, + source.branch || default_branch, + pr_description, + nil, + work_item + ) + end + + def default_branch + @default_branch ||= + bitbucket_client_for_source.fetch_default_branch(source.repo) + end + end + end +end diff --git a/common/lib/dependabot/pull_request_creator/branch_namer.rb b/common/lib/dependabot/pull_request_creator/branch_namer.rb index 6e4a2b100d2..a494f1d56c3 100644 --- a/common/lib/dependabot/pull_request_creator/branch_namer.rb +++ b/common/lib/dependabot/pull_request_creator/branch_namer.rb @@ -1,23 +1,25 @@ # frozen_string_literal: true +require "digest" + require "dependabot/metadata_finders" require "dependabot/pull_request_creator" module Dependabot class PullRequestCreator class BranchNamer - attr_reader :dependencies, :files, :target_branch, :separator, :prefix + attr_reader :dependencies, :files, :target_branch, :separator, :prefix, :max_length def initialize(dependencies:, files:, target_branch:, separator: "/", - prefix: "dependabot") + prefix: "dependabot", max_length: nil) @dependencies = dependencies @files = files @target_branch = target_branch @separator = separator @prefix = prefix + @max_length = max_length end - # rubocop:disable Metrics/PerceivedComplexity def new_branch_name @name ||= begin @@ -34,22 +36,20 @@ def new_branch_name tr("@", "") end - dep = dependencies.first - - if library? && ref_changed?(dep) && new_ref(dep) - "#{dependency_name_part}-#{new_ref(dep)}" - elsif library? - "#{dependency_name_part}-#{sanitized_requirement(dep)}" - else - "#{dependency_name_part}-#{new_version(dep)}" - end + "#{dependency_name_part}-#{branch_version_suffix}" end # Some users need branch names without slashes - sanitize_ref(File.join(prefixes, @name).gsub("/", separator)) - end + sanitized_name = sanitize_ref(File.join(prefixes, @name).gsub("/", separator)) - # rubocop:enable Metrics/PerceivedComplexity + # Shorten the ref in case users refs have length limits + if @max_length && (sanitized_name.length > @max_length) + sha = Digest::SHA1.hexdigest(sanitized_name)[0, @max_length] + sanitized_name[[@max_length - sha.size, 0].max..] = sha + end + + sanitized_name + end private @@ -98,6 +98,20 @@ def dependency_set @dependency_set end + def branch_version_suffix + dep = dependencies.first + + if dep.removed? + "-removed" + elsif library? && ref_changed?(dep) && new_ref(dep) + new_ref(dep) + elsif library? + sanitized_requirement(dep) + else + new_version(dep) + end + end + def sanitized_requirement(dependency) new_library_requirement(dependency). delete(" "). @@ -116,38 +130,34 @@ def sanitized_requirement(dependency) gsub(",", "-and-") end - # rubocop:disable Metrics/PerceivedComplexity def new_version(dependency) # Version looks like a git SHA and we could be updating to a specific # ref in which case we return that otherwise we return a shorthand sha if dependency.version.match?(/^[0-9a-f]{40}$/) - if ref_changed?(dependency) && new_ref(dependency) - return new_ref(dependency) - end + return new_ref(dependency) if ref_changed?(dependency) && new_ref(dependency) dependency.version[0..6] elsif dependency.version == dependency.previous_version && package_manager == "docker" dependency.requirements. - map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }. - compact.first.split(":").last[0..6] + filter_map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }. + first.split(":").last[0..6] else dependency.version end end - # rubocop:enable Metrics/PerceivedComplexity def previous_ref(dependency) - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref(dependency) - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end @@ -167,12 +177,12 @@ def new_library_requirement(dependency) updated_reqs.first[:requirement] end - # TODO: Look into bringing this in line with existing library checks that - # we do in the update checkers, which are also overriden by passing an - # explicit `requirements_update_strategy`. + # TODO: Bring this in line with existing library checks that we do in the + # update checkers, which are also overriden by passing an explicit + # `requirements_update_strategy`. + # + # TODO re-use in MessageBuilder def library? - return true if files.map(&:name).any? { |nm| nm.end_with?(".gemspec") } - dependencies.any? { |d| !d.appears_in_lockfile? } end @@ -182,17 +192,13 @@ def requirements_changed?(dependency) def sanitize_ref(ref) # This isn't a complete implementation of git's ref validation, but it - # covers most cases that crop up. Its list of allowed charactersr is a + # covers most cases that crop up. Its list of allowed characters is a # bit stricter than git's, but that's for cosmetic reasons. ref. # Remove forbidden characters (those not already replaced elsewhere) gsub(%r{[^A-Za-z0-9/\-_.(){}]}, ""). # Slashes can't be followed by periods - gsub(%r{/\.}, "/dot-"). - # Two or more sequential periods are forbidden - gsub(/\.+/, "."). - # Two or more sequential slashes are forbidden - gsub(%r{/+}, "/"). + gsub(%r{/\.}, "/dot-").squeeze(".").squeeze("/"). # Trailing periods are forbidden sub(/\.$/, "") end diff --git a/common/lib/dependabot/pull_request_creator/codecommit.rb b/common/lib/dependabot/pull_request_creator/codecommit.rb index 4fa8339139a..e7bb305ea33 100644 --- a/common/lib/dependabot/pull_request_creator/codecommit.rb +++ b/common/lib/dependabot/pull_request_creator/codecommit.rb @@ -109,19 +109,19 @@ def unmerged_pull_request_exists? def pull_requests_for_branch @pull_requests_for_branch ||= begin - open_prs = codecommit_client_for_source.pull_requests( - source.repo, - "open", - source.branch || default_branch - ) - closed_prs = codecommit_client_for_source.pull_requests( - source.repo, - "closed", - source.branch || default_branch - ) - - [*open_prs, *closed_prs] - end + open_prs = codecommit_client_for_source.pull_requests( + source.repo, + "open", + source.branch || default_branch + ) + closed_prs = codecommit_client_for_source.pull_requests( + source.repo, + "closed", + source.branch || default_branch + ) + + [*open_prs, *closed_prs] + end end def create_commit diff --git a/common/lib/dependabot/pull_request_creator/github.rb b/common/lib/dependabot/pull_request_creator/github.rb index 472e91572ec..0ea6e2546e6 100644 --- a/common/lib/dependabot/pull_request_creator/github.rb +++ b/common/lib/dependabot/pull_request_creator/github.rb @@ -7,7 +7,10 @@ require "dependabot/pull_request_creator/commit_signer" module Dependabot class PullRequestCreator + # rubocop:disable Metrics/ClassLength class Github + MAX_PR_DESCRIPTION_LENGTH = 65_536 # characters (see #create_pull_request) + attr_reader :source, :branch_name, :base_commit, :credentials, :files, :pr_description, :pr_name, :commit_message, :author_details, :signature_key, :custom_headers, @@ -41,7 +44,7 @@ def create return if require_up_to_date_base? && !base_commit_is_up_to_date? create_annotated_pull_request - rescue Octokit::Error => e + rescue AnnotationError, Octokit::Error => e handle_error(e) end @@ -51,6 +54,7 @@ def require_up_to_date_base? @require_up_to_date_base end + # rubocop:disable Metrics/PerceivedComplexity def branch_exists?(name) git_metadata_fetcher.ref_names.include?(name) rescue Dependabot::GitDependenciesNotReachable => e @@ -66,6 +70,7 @@ def branch_exists?(name) retrying = true retry end + # rubocop:enable Metrics/PerceivedComplexity def unmerged_pull_request_exists? pull_requests_for_branch.reject(&:merged).any? @@ -109,7 +114,11 @@ def create_annotated_pull_request pull_request = create_pull_request return unless pull_request - annotate_pull_request(pull_request) + begin + annotate_pull_request(pull_request) + rescue StandardError => e + raise AnnotationError.new(e, pull_request) + end pull_request end @@ -170,12 +179,23 @@ def create_tree sha: file.content } else + content = if file.operation == Dependabot::DependencyFile::Operation::DELETE + { sha: nil } + elsif file.binary? + sha = github_client_for_source.create_blob( + source.repo, file.content, "base64" + ) + { sha: sha } + else + { content: file.content } + end + { - path: (file.symlink_target || file.path).sub(%r{^/}, ""), - mode: "100644", - type: "blob", - content: file.content - } + path: (file.symlink_target || + file.path).sub(%r{^/}, ""), + mode: (file.mode || "100644"), + type: "blob" + }.merge(content) end end @@ -199,7 +219,7 @@ def create_or_update_branch(commit) retry_count ||= 0 retry_count += 1 if retry_count > 10 - raise "Repeatedly failed to create or update branch #{branch_name} "\ + raise "Repeatedly failed to create or update branch #{branch_name} " \ "with commit #{commit.sha}." end @@ -208,12 +228,12 @@ def create_or_update_branch(commit) end def create_branch(commit) - ref = "heads/#{branch_name}" + ref = "refs/heads/#{branch_name}" begin branch = github_client_for_source.create_ref(source.repo, ref, commit.sha) - @branch_name = ref.gsub(%r{^heads/}, "") + @branch_name = ref.gsub(%r{^refs/heads/}, "") branch rescue Octokit::UnprocessableEntity => e # Return quietly in the case of a race @@ -226,7 +246,7 @@ def create_branch(commit) # Branch creation will fail if a branch called `dependabot` already # exists, since git won't be able to create a dir with the same name - ref = "heads/#{SecureRandom.hex[0..3] + branch_name}" + ref = "refs/heads/#{SecureRandom.hex[0..3] + branch_name}" retry end end @@ -249,7 +269,7 @@ def annotate_pull_request(pull_request) def add_reviewers_to_pull_request(pull_request) reviewers_hash = - Hash[reviewers.keys.map { |k| [k.to_sym, reviewers[k]] }] + reviewers.keys.to_h { |k| [k.to_sym, reviewers[k]] } github_client_for_source.request_pull_request_review( source.repo, @@ -279,7 +299,7 @@ def invalid_reviewer?(message) def comment_with_invalid_reviewer(pull_request, message) reviewers_hash = - Hash[reviewers.keys.map { |k| [k.to_sym, reviewers[k]] }] + reviewers.keys.to_h { |k| [k.to_sym, reviewers[k]] } reviewers = [] reviewers += reviewers_hash[:reviewers] || [] reviewers += (reviewers_hash[:team_reviewers] || []). @@ -295,9 +315,9 @@ def comment_with_invalid_reviewer(pull_request, message) msg = "Dependabot tried to add #{reviewers_string} as " msg += reviewers.count > 1 ? "reviewers" : "a reviewer" - msg += " to this PR, but received the following error from GitHub:\n\n"\ + msg += " to this PR, but received the following error from GitHub:\n\n" \ "```\n" \ - "#{message}\n"\ + "#{message}\n" \ "```" github_client_for_source.add_comment( @@ -329,6 +349,18 @@ def add_milestone_to_pull_request(pull_request) end def create_pull_request + # Limit PR description to MAX_PR_DESCRIPTION_LENGTH (65,536) characters + # and truncate with message if over. The API limit is 262,144 bytes + # (https://github.community/t/maximum-length-for-the-comment-body-in-issues-and-pr/148867/2). + # As Ruby strings are UTF-8 encoded, this is a pessimistic limit: it + # presumes the case where all characters are 4 bytes. + pr_description = @pr_description.dup + if pr_description && pr_description.length > MAX_PR_DESCRIPTION_LENGTH + truncated_msg = "...\n\n_Description has been truncated_" + truncate_length = MAX_PR_DESCRIPTION_LENGTH - truncated_msg.length + pr_description = (pr_description[0, truncate_length] + truncated_msg) + end + github_client_for_source.create_pull_request( source.repo, target_branch, @@ -404,24 +436,47 @@ def github_client_for_source end def handle_error(err) - case err + cause = case err + when AnnotationError + err.cause + else + err + end + + case cause when Octokit::Forbidden - raise RepoDisabled, err.message if err.message.include?("disabled") - raise RepoArchived, err.message if err.message.include?("archived") + if err.message.include?("disabled") + raise_custom_error err, RepoDisabled, err.message + elsif err.message.include?("archived") + raise_custom_error err, RepoArchived, err.message + end raise err when Octokit::NotFound raise err if repo_exists? - raise RepoNotFound, err.message + raise_custom_error err, RepoNotFound, err.message when Octokit::UnprocessableEntity - raise err unless err.message.include?("no history in common") + raise_custom_error err, NoHistoryInCommon, err.message if err.message.include?("no history in common") - raise NoHistoryInCommon, err.message + raise err else raise err end end + + def raise_custom_error(base_err, type, message) + case base_err + when AnnotationError + raise AnnotationError.new( + type.new(message), + base_err.pull_request + ) + else + raise type, message + end + end end + # rubocop:enable Metrics/ClassLength end end diff --git a/common/lib/dependabot/pull_request_creator/gitlab.rb b/common/lib/dependabot/pull_request_creator/gitlab.rb index cf92ea4fe24..f43efefd757 100644 --- a/common/lib/dependabot/pull_request_creator/gitlab.rb +++ b/common/lib/dependabot/pull_request_creator/gitlab.rb @@ -10,25 +10,26 @@ class Gitlab attr_reader :source, :branch_name, :base_commit, :credentials, :files, :pr_description, :pr_name, :commit_message, :author_details, :labeler, :approvers, :assignees, - :milestone + :milestone, :target_project_id def initialize(source:, branch_name:, base_commit:, credentials:, files:, commit_message:, pr_description:, pr_name:, author_details:, labeler:, approvers:, assignees:, - milestone:) - @source = source - @branch_name = branch_name - @base_commit = base_commit - @credentials = credentials - @files = files - @commit_message = commit_message - @pr_description = pr_description - @pr_name = pr_name - @author_details = author_details - @labeler = labeler - @approvers = approvers - @assignees = assignees - @milestone = milestone + milestone:, target_project_id:) + @source = source + @branch_name = branch_name + @base_commit = base_commit + @credentials = credentials + @files = files + @commit_message = commit_message + @pr_description = pr_description + @pr_name = pr_name + @author_details = author_details + @labeler = labeler + @approvers = approvers + @assignees = assignees + @milestone = milestone + @target_project_id = target_project_id end def create @@ -76,7 +77,7 @@ def commit_exists? def merge_request_exists? gitlab_client_for_source.merge_requests( - source.repo, + target_project_id || source.repo, source_branch: branch_name, target_branch: source.branch || default_branch, state: "all" @@ -92,34 +93,37 @@ def create_branch end def create_commit - if files.count == 1 && files.first.type == "submodule" - return create_submodule_update_commit - end - - actions = files.map do |file| - if file.type == "symlink" - { - action: "update", - file_path: file.symlink_target, - content: file.content - } - else - { - action: "update", - file_path: file.path, - content: file.content - } - end - end + return create_submodule_update_commit if files.count == 1 && files.first.type == "submodule" gitlab_client_for_source.create_commit( source.repo, branch_name, commit_message, - actions + file_actions ) end + def file_actions + files.map do |file| + { + action: file_action(file), + file_path: file.type == "symlink" ? file.symlink_target : file.path, + content: file.content + } + end + end + + # @param [DependencyFile] file + def file_action(file) + if file.operation == Dependabot::DependencyFile::Operation::DELETE + "delete" + elsif file.operation == Dependabot::DependencyFile::Operation::CREATE + "create" + else + "update" + end + end + def create_submodule_update_commit file = files.first @@ -142,26 +146,33 @@ def create_merge_request remove_source_branch: true, assignee_ids: assignees, labels: labeler.labels_for_pr.join(","), - milestone_id: milestone + milestone_id: milestone, + target_project_id: target_project_id, + reviewer_ids: approvers_hash[:reviewers] ) end def annotate_merge_request(merge_request) - add_approvers_to_merge_request(merge_request) if approvers&.any? + add_approvers_to_merge_request(merge_request) end def add_approvers_to_merge_request(merge_request) - approvers_hash = - Hash[approvers.keys.map { |k| [k.to_sym, approvers[k]] }] + return unless approvers_hash[:approvers] || approvers_hash[:group_approvers] - gitlab_client_for_source.edit_merge_request_approvers( - source.repo, + gitlab_client_for_source.create_merge_request_level_rule( + target_project_id || source.repo, merge_request.iid, - approver_ids: approvers_hash[:approvers], - approver_group_ids: approvers_hash[:group_approvers] + name: "dependency-updates", + approvals_required: 1, + user_ids: approvers_hash[:approvers], + group_ids: approvers_hash[:group_approvers] ) end + def approvers_hash + @approvers_hash ||= approvers&.transform_keys(&:to_sym) || {} + end + def default_branch @default_branch ||= gitlab_client_for_source.project(source.repo).default_branch diff --git a/common/lib/dependabot/pull_request_creator/labeler.rb b/common/lib/dependabot/pull_request_creator/labeler.rb index 7d160dcee8f..a841fc51cdb 100644 --- a/common/lib/dependabot/pull_request_creator/labeler.rb +++ b/common/lib/dependabot/pull_request_creator/labeler.rb @@ -5,7 +5,7 @@ module Dependabot class PullRequestCreator class Labeler - DEPENDENCIES_LABEL_REGEX = %r{^[^/]*dependenc[^/]+$}i.freeze + DEPENDENCIES_LABEL_REGEX = %r{^[^/]*dependenc[^/]+$}i DEFAULT_DEPENDENCIES_LABEL = "dependencies" DEFAULT_SECURITY_LABEL = "security" @@ -105,7 +105,9 @@ def precision new_version_parts = version(dep).split(/[.+]/) old_version_parts = previous_version(dep)&.split(/[.+]/) || [] all_parts = new_version_parts.first(3) + old_version_parts.first(3) + # rubocop:disable Performance/RedundantEqualityComparisonBlock next 0 unless all_parts.all? { |part| part.to_i.to_s == part } + # rubocop:enable Performance/RedundantEqualityComparisonBlock next 1 if new_version_parts[0] != old_version_parts[0] next 2 if new_version_parts[1] != old_version_parts[1] @@ -113,6 +115,7 @@ def precision end.min end + # rubocop:disable Metrics/PerceivedComplexity def version(dep) return dep.version if version_class.correct?(dep.version) @@ -127,7 +130,9 @@ def version(dep) version_from_ref end + # rubocop:enable Metrics/PerceivedComplexity + # rubocop:disable Metrics/PerceivedComplexity def previous_version(dep) version_str = dep.previous_version return version_str if version_class.correct?(version_str) @@ -144,6 +149,7 @@ def previous_version(dep) version_from_ref end + # rubocop:enable Metrics/PerceivedComplexity def create_default_dependencies_label_if_required return if custom_labels @@ -265,7 +271,7 @@ def fetch_gitlab_labels end def fetch_azure_labels - langauge_name = + language_name = self.class.label_details_for_package_manager(package_manager). fetch(:name) @@ -273,7 +279,7 @@ def fetch_azure_labels *@labels, DEFAULT_DEPENDENCIES_LABEL, DEFAULT_SECURITY_LABEL, - langauge_name + language_name ].uniq end @@ -347,36 +353,37 @@ def create_gitlab_security_label end def create_github_language_label - langauge_name = - self.class.label_details_for_package_manager(package_manager). - fetch(:name) + label = self.class.label_details_for_package_manager(package_manager) + language_name = label.fetch(:name) github_client_for_source.add_label( source.repo, - langauge_name, - self.class.label_details_for_package_manager(package_manager). - fetch(:colour), - description: "Pull requests that update #{langauge_name.capitalize} "\ - "code", + language_name, + label.fetch(:colour), + description: label.fetch(:description) { default_description_for(language_name) }, accept: "application/vnd.github.symmetra-preview+json" ) - @labels = [*@labels, langauge_name].uniq + @labels = [*@labels, language_name].uniq rescue Octokit::UnprocessableEntity => e raise unless e.errors.first.fetch(:code) == "already_exists" - @labels = [*@labels, langauge_name].uniq + @labels = [*@labels, language_name].uniq + end + + def default_description_for(language) + "Pull requests that update #{language.capitalize} code" end def create_gitlab_language_label - langauge_name = + language_name = self.class.label_details_for_package_manager(package_manager). fetch(:name) gitlab_client_for_source.create_label( source.repo, - langauge_name, + language_name, "#" + self.class.label_details_for_package_manager(package_manager). fetch(:colour) ) - @labels = [*@labels, langauge_name].uniq + @labels = [*@labels, language_name].uniq end def github_client_for_source diff --git a/common/lib/dependabot/pull_request_creator/message.rb b/common/lib/dependabot/pull_request_creator/message.rb new file mode 100644 index 00000000000..cc0a8cfed3a --- /dev/null +++ b/common/lib/dependabot/pull_request_creator/message.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Dependabot + class PullRequestCreator + # Message is a static alternative to MessageBuilder + class Message + attr_reader :commit_message, :pr_name, :pr_message + + def initialize(commit_message: nil, pr_name: nil, pr_message: nil) + @commit_message = commit_message + @pr_name = pr_name + @pr_message = pr_message + end + end + end +end diff --git a/common/lib/dependabot/pull_request_creator/message_builder.rb b/common/lib/dependabot/pull_request_creator/message_builder.rb index eb166c1a11d..dcbb6b7fe34 100644 --- a/common/lib/dependabot/pull_request_creator/message_builder.rb +++ b/common/lib/dependabot/pull_request_creator/message_builder.rb @@ -3,13 +3,17 @@ require "pathname" require "dependabot/clients/github_with_retries" require "dependabot/clients/gitlab_with_retries" +require "dependabot/logger" require "dependabot/metadata_finders" require "dependabot/pull_request_creator" +require "dependabot/pull_request_creator/message" # rubocop:disable Metrics/ClassLength module Dependabot class PullRequestCreator + # MessageBuilder builds PR message for a dependency update class MessageBuilder + require_relative "message_builder/metadata_presenter" require_relative "message_builder/issue_linker" require_relative "message_builder/link_and_mention_sanitizer" require_relative "pr_name_prefixer" @@ -22,7 +26,7 @@ class MessageBuilder def initialize(source:, dependencies:, files:, credentials:, pr_message_header: nil, pr_message_footer: nil, commit_message_options: {}, vulnerabilities_fixed: {}, - github_redirection_service: nil) + github_redirection_service:) @dependencies = dependencies @files = files @source = source @@ -35,7 +39,12 @@ def initialize(source:, dependencies:, files:, credentials:, end def pr_name - pr_name = pr_name_prefixer.pr_name_prefix + begin + pr_name = pr_name_prefixer.pr_name_prefix + rescue StandardError => e + Dependabot.logger.error("Error while generating PR name: #{e.message}") + pr_name = "" + end pr_name += library? ? library_pr_name : application_pr_name return pr_name if files.first.directory == "/" @@ -45,6 +54,9 @@ def pr_name def pr_message suffixed_pr_message_header + commit_message_intro + \ metadata_cascades + prefixed_pr_message_footer + rescue StandardError => e + Dependabot.logger.error("Error while generating PR message: #{e.message}") + suffixed_pr_message_header + prefixed_pr_message_footer end def commit_message @@ -53,6 +65,19 @@ def commit_message message += metadata_links message += "\n\n" + message_trailers if message_trailers message + rescue StandardError => e + Dependabot.logger.error("Error while generating commit message: #{e.message}") + message = commit_subject + message += "\n\n" + message_trailers if message_trailers + message + end + + def message + Dependabot::PullRequestCreator::Message.new( + pr_name: pr_name, + pr_message: pr_message, + commit_message: commit_message + ) end private @@ -63,15 +88,20 @@ def library_pr_name pr_name + if dependencies.count == 1 - "#{dependencies.first.display_name} requirement "\ - "#{from_version_msg(old_library_requirement(dependencies.first))}"\ - "to #{new_library_requirement(dependencies.first)}" + "#{dependencies.first.display_name} requirement " \ + "#{from_version_msg(old_library_requirement(dependencies.first))}" \ + "to #{new_library_requirement(dependencies.first)}" else - names = dependencies.map(&:name) - "requirements for #{names[0..-2].join(', ')} and #{names[-1]}" + names = dependencies.map(&:name).uniq + if names.count == 1 + "requirements for #{names.first}" + else + "requirements for #{names[0..-2].join(', ')} and #{names[-1]}" + end end end + # rubocop:disable Metrics/AbcSize def application_pr_name pr_name = "bump " pr_name = pr_name.capitalize if pr_name_prefixer.capitalize_first_word? @@ -79,24 +109,29 @@ def application_pr_name pr_name + if dependencies.count == 1 dependency = dependencies.first - "#{dependency.display_name} "\ - "#{from_version_msg(previous_version(dependency))}"\ - "to #{new_version(dependency)}" + "#{dependency.display_name} " \ + "#{from_version_msg(previous_version(dependency))}" \ + "to #{new_version(dependency)}" elsif updating_a_property? dependency = dependencies.first - "#{property_name} "\ - "#{from_version_msg(previous_version(dependency))}"\ - "to #{new_version(dependency)}" + "#{property_name} " \ + "#{from_version_msg(previous_version(dependency))}" \ + "to #{new_version(dependency)}" elsif updating_a_dependency_set? dependency = dependencies.first - "#{dependency_set.fetch(:group)} dependency set "\ - "#{from_version_msg(previous_version(dependency))}"\ - "to #{new_version(dependency)}" + "#{dependency_set.fetch(:group)} dependency set " \ + "#{from_version_msg(previous_version(dependency))}" \ + "to #{new_version(dependency)}" else - names = dependencies.map(&:name) - "#{names[0..-2].join(', ')} and #{names[-1]}" + names = dependencies.map(&:name).uniq + if names.count == 1 + names.first + else + "#{names[0..-2].join(', ')} and #{names[-1]}" + end end end + # rubocop:enable Metrics/AbcSize def pr_name_prefix pr_name_prefixer.pr_name_prefix @@ -131,6 +166,20 @@ def suffixed_pr_message_header end def message_trailers + return unless signoff_trailers || custom_trailers + + [signoff_trailers, custom_trailers].compact.join("\n") + end + + def custom_trailers + trailers = commit_message_options[:trailers] + return if trailers.nil? + raise("Commit trailers must be a Hash object") unless trailers.is_a?(Hash) + + trailers.compact.map { |k, v| "#{k}: #{v}" }.join("\n") + end + + def signoff_trailers return unless on_behalf_of_message || signoff_message [on_behalf_of_message, signoff_message].compact.join("\n") @@ -149,8 +198,8 @@ def on_behalf_of_message return unless signoff_details.is_a?(Hash) return unless signoff_details[:org_name] && signoff_details[:org_email] - "On-behalf-of: @#{signoff_details[:org_name]} "\ - "<#{signoff_details[:org_email]}>" + "On-behalf-of: @#{signoff_details[:org_name]} " \ + "<#{signoff_details[:org_email]}>" end def requirement_commit_message_intro @@ -167,25 +216,25 @@ def requirement_commit_message_intro end # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize def version_commit_message_intro - if dependencies.count > 1 && updating_a_property? - return multidependency_property_intro - end + return multidependency_property_intro if dependencies.count > 1 && updating_a_property? - if dependencies.count > 1 && updating_a_dependency_set? - return dependency_set_intro - end + return dependency_set_intro if dependencies.count > 1 && updating_a_dependency_set? + + return transitive_removed_dependency_intro if dependencies.count > 1 && removing_a_transitive_dependency? + + return transitive_multidependency_intro if dependencies.count > 1 && + updating_top_level_and_transitive_dependencies? return multidependency_intro if dependencies.count > 1 dependency = dependencies.first - msg = "Bumps #{dependency_links.first} "\ - "#{from_version_msg(previous_version(dependency))}"\ + msg = "Bumps #{dependency_links.first} " \ + "#{from_version_msg(previous_version(dependency))}" \ "to #{new_version(dependency)}." - if switching_from_ref_to_release?(dependency) - msg += " This release includes the previously tagged commit." - end + msg += " This release includes the previously tagged commit." if switching_from_ref_to_release?(dependency) if vulnerabilities_fixed[dependency.name]&.one? msg += " **This update includes a security fix.**" @@ -197,27 +246,60 @@ def version_commit_message_intro end # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/AbcSize def multidependency_property_intro dependency = dependencies.first - "Bumps `#{property_name}` "\ - "#{from_version_msg(previous_version(dependency))}"\ - "to #{new_version(dependency)}." + "Bumps `#{property_name}` " \ + "#{from_version_msg(previous_version(dependency))}" \ + "to #{new_version(dependency)}." end def dependency_set_intro dependency = dependencies.first - "Bumps `#{dependency_set.fetch(:group)}` "\ - "dependency set #{from_version_msg(previous_version(dependency))}"\ - "to #{new_version(dependency)}." + "Bumps `#{dependency_set.fetch(:group)}` " \ + "dependency set #{from_version_msg(previous_version(dependency))}" \ + "to #{new_version(dependency)}." end def multidependency_intro - "Bumps #{dependency_links[0..-2].join(', ')} "\ - "and #{dependency_links[-1]}. These "\ - "dependencies needed to be updated together." + "Bumps #{dependency_links[0..-2].join(', ')} " \ + "and #{dependency_links[-1]}. These " \ + "dependencies needed to be updated together." + end + + def transitive_multidependency_intro + dependency = dependencies.first + + msg = "Bumps #{dependency_links[0]} to #{new_version(dependency)}" + + msg += if dependencies.count > 2 + " and updates ancestor dependencies #{dependency_links[0..-2].join(', ')} " \ + "and #{dependency_links[-1]}. " + else + " and updates ancestor dependency #{dependency_links[1]}. " + end + + msg += "These dependencies need to be updated together.\n" + + msg + end + + def transitive_removed_dependency_intro + msg = "Removes #{dependency_links[0]}. It's no longer used after updating" + + msg += if dependencies.count > 2 + " ancestor dependencies #{dependency_links[0..-2].join(', ')} " \ + "and #{dependency_links[-1]}. " + else + " ancestor dependency #{dependency_links[1]}. " + end + + msg += "These dependencies need to be updated together.\n" + + msg end def from_version_msg(previous_version) @@ -238,6 +320,15 @@ def updating_a_dependency_set? any? { |r| r.dig(:metadata, :dependency_set) } end + def removing_a_transitive_dependency? + dependencies.any?(&:removed?) + end + + def updating_top_level_and_transitive_dependencies? + dependencies.any?(&:top_level?) && + dependencies.any? { |dep| !dep.top_level? } + end + def property_name @property_name ||= dependencies.first.requirements. find { |r| r.dig(:metadata, :property_name) }&. @@ -271,15 +362,17 @@ def dependency_links end def metadata_links - if dependencies.count == 1 - return metadata_links_for_dep(dependencies.first) - end + return metadata_links_for_dep(dependencies.first) if dependencies.count == 1 dependencies.map do |dep| - "\n\nUpdates `#{dep.display_name}` "\ - "#{from_version_msg(previous_version(dep))}to "\ - "#{new_version(dep)}"\ - "#{metadata_links_for_dep(dep)}" + if dep.removed? + "\n\nRemoves `#{dep.display_name}`" + else + "\n\nUpdates `#{dep.display_name}` " \ + "#{from_version_msg(previous_version(dep))}to " \ + "#{new_version(dep)}" \ + "#{metadata_links_for_dep(dep)}" + end end.join end @@ -293,14 +386,16 @@ def metadata_links_for_dep(dep) end def metadata_cascades - if dependencies.one? - return metadata_cascades_for_dep(dependencies.first) - end + return metadata_cascades_for_dep(dependencies.first) if dependencies.one? dependencies.map do |dep| - msg = "\nUpdates `#{dep.display_name}` "\ - "#{from_version_msg(previous_version(dep))}"\ - "to #{new_version(dep)}" + msg = if dep.removed? + "\nRemoves `#{dep.display_name}`\n" + else + "\nUpdates `#{dep.display_name}` " \ + "#{from_version_msg(previous_version(dep))}" \ + "to #{new_version(dep)}" + end if vulnerabilities_fixed[dep.name]&.one? msg += " **This update includes a security fix.**" @@ -312,240 +407,40 @@ def metadata_cascades end.join end - def metadata_cascades_for_dep(dep) - break_tag = source_provider_supports_html? ? "\n
" : "\n\n" - - msg = "" - msg += vulnerabilities_cascade(dep) - msg += release_cascade(dep) - msg += changelog_cascade(dep) - msg += upgrade_guide_cascade(dep) - msg += commits_cascade(dep) - msg += maintainer_changes_cascade(dep) - msg += break_tag unless msg == "" - "\n" + sanitize_links_and_mentions(msg, unsafe: true) - end - - def vulnerabilities_cascade(dep) - fixed_vulns = vulnerabilities_fixed[dep.name] - return "" unless fixed_vulns&.any? + def metadata_cascades_for_dep(dependency) + return "" if dependency.removed? - msg = "" - fixed_vulns.each { |v| msg += serialized_vulnerability_details(v) } - msg = sanitize_template_tags(msg) - msg = sanitize_links_and_mentions(msg) - - build_details_tag(summary: "Vulnerabilities fixed", body: msg) - end - - def release_cascade(dep) - return "" unless releases_text(dep) && releases_url(dep) - - msg = "*Sourced from [#{dep.display_name}'s releases]"\ - "(#{releases_url(dep)}).*\n\n" - msg += - begin - release_note_lines = releases_text(dep).split("\n").first(50) - release_note_lines = release_note_lines.map { |line| "> #{line}\n" } - if release_note_lines.count == 50 - release_note_lines << truncated_line - end - release_note_lines.join - end - msg = link_issues(text: msg, dependency: dep) - msg = fix_relative_links( - text: msg, - base_url: source_url(dep) + "/blob/HEAD/" - ) - msg = sanitize_template_tags(msg) - msg = sanitize_links_and_mentions(msg) - - build_details_tag(summary: "Release notes", body: msg) - end - - def changelog_cascade(dep) - return "" unless changelog_url(dep) && changelog_text(dep) - - msg = "*Sourced from "\ - "[#{dep.display_name}'s changelog](#{changelog_url(dep)}).*\n\n" - msg += - begin - changelog_lines = changelog_text(dep).split("\n").first(50) - changelog_lines = changelog_lines.map { |line| "> #{line}\n" } - changelog_lines << truncated_line if changelog_lines.count == 50 - changelog_lines.join - end - msg = link_issues(text: msg, dependency: dep) - msg = fix_relative_links(text: msg, base_url: changelog_url(dep)) - msg = sanitize_template_tags(msg) - msg = sanitize_links_and_mentions(msg) - - build_details_tag(summary: "Changelog", body: msg) - end - - def upgrade_guide_cascade(dep) - return "" unless upgrade_url(dep) && upgrade_text(dep) - - msg = "*Sourced from "\ - "[#{dep.display_name}'s upgrade guide]"\ - "(#{upgrade_url(dep)}).*\n\n" - msg += - begin - upgrade_lines = upgrade_text(dep).split("\n").first(50) - upgrade_lines = upgrade_lines.map { |line| "> #{line}\n" } - upgrade_lines << truncated_line if upgrade_lines.count == 50 - upgrade_lines.join - end - msg = link_issues(text: msg, dependency: dep) - msg = fix_relative_links(text: msg, base_url: upgrade_url(dep)) - msg = sanitize_template_tags(msg) - msg = sanitize_links_and_mentions(msg) - - build_details_tag(summary: "Upgrade guide", body: msg) - end - - def commits_cascade(dep) - return "" unless commits_url(dep) && commits(dep) - - msg = "" - - commits(dep).reverse.first(10).each do |commit| - title = commit[:message].strip.split("\n").first - title = title.slice(0..76) + "..." if title && title.length > 80 - title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1') - sha = commit[:sha][0, 7] - msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n" - end - - msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" } - - msg += - if commits(dep).count > 10 - "- Additional commits viewable in "\ - "[compare view](#{commits_url(dep)})\n" - else - "- See full diff in [compare view](#{commits_url(dep)})\n" - end - msg = link_issues(text: msg, dependency: dep) - msg = sanitize_links_and_mentions(msg) - - build_details_tag(summary: "Commits", body: msg) - end - - def maintainer_changes_cascade(dep) - return "" unless maintainer_changes(dep) - - build_details_tag( - summary: "Maintainer changes", - body: sanitize_links_and_mentions(maintainer_changes(dep)) + "\n" - ) - end - - def build_details_tag(summary:, body:) - # Azure DevOps does not support
tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html) - # CodeCommit does not support the
tag (no url available) - if source_provider_supports_html? - msg = "
\n#{summary}\n\n" - msg += body - msg + "
\n" - else - "\n\##{summary}\n\n#{body}" - end - end - - def source_provider_supports_html? - !%w(azure codecommit).include?(source.provider) - end - - def serialized_vulnerability_details(details) - msg = vulnerability_source_line(details) - - if details["title"] - msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n" - end - - if (description = details["description"]) - description.strip.lines.first(20).each { |line| msg += "> #{line}" } - msg += truncated_line if description.strip.lines.count > 20 - end - - msg += "\n" unless msg.end_with?("\n") - msg += "> \n" - msg += vulnerability_version_range_lines(details) - msg + "\n" - end - - def vulnerability_source_line(details) - if details["source_url"] && details["source_name"] - "*Sourced from [#{details['source_name']}]"\ - "(#{details['source_url']}).*\n\n" - elsif details["source_name"] - "*Sourced from #{details['source_name']}.*\n\n" - else - "" - end - end - - def vulnerability_version_range_lines(details) - msg = "" - %w(patched_versions unaffected_versions affected_versions).each do |tp| - type = tp.split("_").first.capitalize - next unless details[tp] - - versions_string = details[tp].any? ? details[tp].join("; ") : "none" - versions_string = versions_string.gsub(/(? #{type} versions: #{versions_string}\n" - end - msg - end - - def truncated_line - # Tables can spill out of truncated details, so we close them - "> ... (truncated)\n" - end - - def releases_url(dependency) - metadata_finder(dependency).releases_url - end - - def releases_text(dependency) - metadata_finder(dependency).releases_text + MetadataPresenter.new( + dependency: dependency, + source: source, + metadata_finder: metadata_finder(dependency), + vulnerabilities_fixed: vulnerabilities_fixed[dependency.name], + github_redirection_service: github_redirection_service + ).to_s end def changelog_url(dependency) metadata_finder(dependency).changelog_url end - def changelog_text(dependency) - metadata_finder(dependency).changelog_text - end - - def upgrade_url(dependency) - metadata_finder(dependency).upgrade_guide_url - end - - def upgrade_text(dependency) - metadata_finder(dependency).upgrade_guide_text - end - def commits_url(dependency) metadata_finder(dependency).commits_url end - def commits(dependency) - metadata_finder(dependency).commits + def homepage_url(dependency) + metadata_finder(dependency).homepage_url end - def maintainer_changes(dependency) - metadata_finder(dependency).maintainer_changes + def releases_url(dependency) + metadata_finder(dependency).releases_url end def source_url(dependency) metadata_finder(dependency).source_url end - def homepage_url(dependency) - metadata_finder(dependency).homepage_url + def upgrade_url(dependency) + metadata_finder(dependency).upgrade_guide_url end def metadata_finder(dependency) @@ -567,7 +462,6 @@ def pr_name_prefixer ) end - # rubocop:disable Metrics/PerceivedComplexity def previous_version(dependency) # If we don't have a previous version, we *may* still be able to figure # one out if a ref was provided and has been changed (in which case the @@ -577,9 +471,7 @@ def previous_version(dependency) end if dependency.previous_version.match?(/^[0-9a-f]{40}$/) - if ref_changed?(dependency) && previous_ref(dependency) - return previous_ref(dependency) - end + return previous_ref(dependency) if ref_changed?(dependency) && previous_ref(dependency) "`#{dependency.previous_version[0..6]}`" elsif dependency.version == dependency.previous_version && @@ -590,13 +482,10 @@ def previous_version(dependency) dependency.previous_version end end - # rubocop:enable Metrics/PerceivedComplexity def new_version(dependency) if dependency.version.match?(/^[0-9a-f]{40}$/) - if ref_changed?(dependency) && new_ref(dependency) - return new_ref(dependency) - end + return new_ref(dependency) if ref_changed?(dependency) && new_ref(dependency) "`#{dependency.version[0..6]}`" elsif dependency.version == dependency.previous_version && @@ -610,21 +499,21 @@ def new_version(dependency) def docker_digest_from_reqs(requirements) requirements. - map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }. - compact.first + filter_map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }. + first end def previous_ref(dependency) - previous_refs = dependency.previous_requirements.map do |r| + previous_refs = dependency.previous_requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return previous_refs.first if previous_refs.count == 1 end def new_ref(dependency) - new_refs = dependency.requirements.map do |r| + new_refs = dependency.requirements.filter_map do |r| r.dig(:source, "ref") || r.dig(:source, :ref) - end.compact.uniq + end.uniq return new_refs.first if new_refs.count == 1 end @@ -651,68 +540,32 @@ def new_library_requirement(dependency) req = updated_reqs.first.fetch(:requirement) return req if req - if ref_changed?(dependency) && new_ref(dependency) - return new_ref(dependency) - end + return new_ref(dependency) if ref_changed?(dependency) && new_ref(dependency) raise "No new requirement!" end - def link_issues(text:, dependency:) - IssueLinker. - new(source_url: source_url(dependency)). - link_issues(text: text) - end - - def fix_relative_links(text:, base_url:) - text.gsub(/\[.*?\]\([^)]+\)/) do |link| - next link if link.include?("://") - - relative_path = link.match(/\((.*?)\)/).captures.last - base = base_url.split("://").last.gsub(%r{[^/]*$}, "") - path = File.join(base, relative_path) - absolute_path = - base_url.sub( - %r{(?<=://).*$}, - Pathname.new(path).cleanpath.to_s - ) - link.gsub(relative_path, absolute_path) - end - end - - def sanitize_links_and_mentions(text, unsafe: false) - return text unless source.provider == "github" - - LinkAndMentionSanitizer. - new(github_redirection_service: github_redirection_service). - sanitize_links_and_mentions(text: text, unsafe: unsafe) - end - - def sanitize_template_tags(text) - text.gsub(/\<.*?\>/) do |tag| - tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip - - # Unclosed calls to template overflow out of the blockquote block, - # wrecking the rest of our PRs. Other tags don't share this problem. - next "\\#{tag}" if tag_contents.start_with?("template") - - tag - end - end - def ref_changed?(dependency) previous_ref(dependency) != new_ref(dependency) end + # TODO: Bring this in line with existing library checks that we do in the + # update checkers, which are also overriden by passing an explicit + # `requirements_update_strategy`. + # + # TODO re-use in BranchNamer def library? - return true if files.map(&:name).any? { |nm| nm.end_with?(".gemspec") } + # Reject any nested child gemspecs/vendored git dependencies + root_files = files.map(&:name). + select { |p| Pathname.new(p).dirname.to_s == "." } + return true if root_files.select { |nm| nm.end_with?(".gemspec") }.any? dependencies.any? { |d| previous_version(d).nil? } end def switching_from_ref_to_release?(dependency) unless dependency.previous_version&.match?(/^[0-9a-f]{40}$/) || - dependency.previous_version.nil? && previous_ref(dependency) + (dependency.previous_version.nil? && previous_ref(dependency)) return false end diff --git a/common/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb b/common/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb index 05c380dea1c..ed291a7c894 100644 --- a/common/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb +++ b/common/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb @@ -6,15 +6,15 @@ module Dependabot class PullRequestCreator class MessageBuilder class IssueLinker - REPO_REGEX = %r{(?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)}.freeze - TAG_REGEX = /(?(?:\#|GH-)\d+)/i.freeze + REPO_REGEX = %r{(?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)} + TAG_REGEX = /(?(?:\#|GH-)\d+)/i ISSUE_LINK_REGEXS = [ / (?:(?<=[^A-Za-z0-9\[\\]|^)\\*#{TAG_REGEX}(?=[^A-Za-z0-9\-]|$))| (?:(?<=\s|^)#{REPO_REGEX}#{TAG_REGEX}(?=[^A-Za-z0-9\-]|$)) - /x.freeze, - /\[#{TAG_REGEX}\](?=[^A-Za-z0-9\-\(])/.freeze, - /\[(?(?:\#|GH-)?\d+)\]\(\)/i.freeze + /x, + /\[#{TAG_REGEX}\](?=[^A-Za-z0-9\-\(])/, + /\[(?(?:\#|GH-)?\d+)\]\(\)/i ].freeze attr_reader :source_url diff --git a/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb b/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb index a34223ef1c3..e0810fa60c4 100644 --- a/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +++ b/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb @@ -8,15 +8,19 @@ module Dependabot class PullRequestCreator class MessageBuilder class LinkAndMentionSanitizer - GITHUB_USERNAME = /[a-z0-9]+(-[a-z0-9]+)*/i.freeze + GITHUB_USERNAME = /[a-z0-9]+(-[a-z0-9]+)*/i GITHUB_REF_REGEX = %r{ (?:https?://)? github\.com/(?#{GITHUB_USERNAME}/[^/\s]+)/ (?:issue|pull)s?/(?\d+) - }x.freeze - MENTION_REGEX = %r{(?#{GITHUB_USERNAME}/[^/\s#]+)#(?\d+)} + MENTION_REGEX = %r{(?#{GITHUB_USERNAME})/(?#{GITHUB_USERNAME})/?} # End of string - EOS_REGEX = /\z/.freeze + EOS_REGEX = /\z/ COMMONMARKER_OPTIONS = %i( GITHUB_PRE_LANG FULL_INFO_STRING ).freeze @@ -35,8 +39,11 @@ def sanitize_links_and_mentions(text:, unsafe: false) text, :LIBERAL_HTML_TAG, COMMONMARKER_EXTENSIONS ) + sanitize_team_mentions(doc) sanitize_mentions(doc) sanitize_links(doc) + sanitize_nwo_text(doc) + mode = unsafe ? :UNSAFE : :DEFAULT doc.to_html(([mode] + COMMONMARKER_OPTIONS), COMMONMARKER_EXTENSIONS) end @@ -45,9 +52,13 @@ def sanitize_links_and_mentions(text:, unsafe: false) def sanitize_mentions(doc) doc.walk do |node| - if !parent_node_link?(node) && node.type == :text && + if node.type == :text && node.string_content.match?(MENTION_REGEX) - nodes = build_mention_nodes(node.string_content) + nodes = if parent_node_link?(node) + build_mention_link_text_nodes(node.string_content) + else + build_mention_nodes(node.string_content) + end nodes.each do |n| node.insert_before(n) @@ -58,7 +69,26 @@ def sanitize_mentions(doc) end end - # rubocop:disable Metrics/PerceivedComplexity + # When we come across something that looks like a team mention (e.g. @dependabot/reviewers), + # we replace it with a text node. + # This is because there are ecosystems that have packages that follow the same pattern + # (e.g. @angular/angular-cli), and we don't want to create an invalid link, since + # team mentions link to `https://github.com/org/:organization_name/teams/:team_name`. + def sanitize_team_mentions(doc) + doc.walk do |node| + if node.type == :text && + node.string_content.match?(TEAM_MENTION_REGEX) + + nodes = build_team_mention_nodes(node.string_content) + + nodes.each do |n| + node.insert_before(n) + end + node.delete + end + end + end + def sanitize_links(doc) doc.walk do |node| if node.type == :link && node.url.match?(GITHUB_REF_REGEX) @@ -81,11 +111,29 @@ def sanitize_links(doc) end end end - # rubocop:enable Metrics/PerceivedComplexity + + def sanitize_nwo_text(doc) + doc.walk do |node| + if node.type == :text && + node.string_content.match?(GITHUB_NWO_REGEX) && + !parent_node_link?(node) + replace_nwo_node(node) + end + end + end + + def replace_nwo_node(node) + match = node.string_content.match(GITHUB_NWO_REGEX) + repo = match.named_captures.fetch("repo") + number = match.named_captures.fetch("number") + new_node = build_nwo_text_node("#{repo}##{number}") + node.insert_before(new_node) + node.delete + end def replace_github_host(text) text.gsub( - "github.com", github_redirection_service || "github.com" + /(www\.)?github.com/, github_redirection_service || "github.com" ) end @@ -115,17 +163,61 @@ def build_mention_nodes(text) nodes end + def build_team_mention_nodes(text) + nodes = [] + + scan = StringScanner.new(text) + until scan.eos? + line = scan.scan_until(TEAM_MENTION_REGEX) || + scan.scan_until(EOS_REGEX) + line_match = line.match(TEAM_MENTION_REGEX) + mention = line_match&.to_s + text_node = CommonMarker::Node.new(:text) + + if mention + text_node.string_content = line_match.pre_match + nodes << text_node + nodes += build_mention_link_text_nodes(mention.to_s) + else + text_node.string_content = line + nodes << text_node + end + end + + nodes + end + + def build_mention_link_text_nodes(text) + code_node = CommonMarker::Node.new(:code) + code_node.string_content = insert_zero_width_space_in_mention(text) + [code_node] + end + + def build_nwo_text_node(text) + code_node = CommonMarker::Node.new(:code) + code_node.string_content = text + code_node + end + def create_link_node(url, text) link_node = CommonMarker::Node.new(:link) - text_node = CommonMarker::Node.new(:text) + code_node = CommonMarker::Node.new(:code) link_node.url = url - text_node.string_content = text - link_node.append_child(text_node) + code_node.string_content = insert_zero_width_space_in_mention(text) + link_node.append_child(code_node) link_node end + # NOTE: Add a zero-width space between the @ and the username to prevent + # email replies on dependabot pull requests triggering notifications to + # users who've been mentioned in changelogs etc. PR email replies parse + # the content of the pull request body in plain text. + def insert_zero_width_space_in_mention(mention) + mention.sub("@", "@\u200B").encode("utf-8") + end + def parent_node_link?(node) - node.type == :link || node.parent && parent_node_link?(node.parent) + node.type == :link || (node.parent && parent_node_link?(node.parent)) end end end diff --git a/common/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb b/common/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb new file mode 100644 index 00000000000..68a85a84531 --- /dev/null +++ b/common/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb @@ -0,0 +1,267 @@ +# frozen_string_literal: true + +require "dependabot/pull_request_creator/message_builder" + +module Dependabot + class PullRequestCreator + class MessageBuilder + class MetadataPresenter + extend Forwardable + + attr_reader :dependency, :source, :metadata_finder, + :vulnerabilities_fixed, :github_redirection_service + + def_delegators :metadata_finder, + :changelog_url, + :changelog_text, + :commits_url, + :commits, + :maintainer_changes, + :releases_url, + :releases_text, + :source_url, + :upgrade_guide_url, + :upgrade_guide_text + + def initialize(dependency:, source:, metadata_finder:, + vulnerabilities_fixed:, github_redirection_service:) + @dependency = dependency + @source = source + @metadata_finder = metadata_finder + @vulnerabilities_fixed = vulnerabilities_fixed + @github_redirection_service = github_redirection_service + end + + def to_s + msg = "" + msg += vulnerabilities_cascade + msg += release_cascade + msg += changelog_cascade + msg += upgrade_guide_cascade + msg += commits_cascade + msg += maintainer_changes_cascade + msg += break_tag unless msg == "" + "\n" + sanitize_links_and_mentions(msg, unsafe: true) + end + + private + + def vulnerabilities_cascade + return "" unless vulnerabilities_fixed&.any? + + msg = "" + vulnerabilities_fixed.each do |v| + msg += serialized_vulnerability_details(v) + end + + msg = sanitize_template_tags(msg) + msg = sanitize_links_and_mentions(msg) + + build_details_tag(summary: "Vulnerabilities fixed", body: msg) + end + + def release_cascade + return "" unless releases_text && releases_url + + msg = "*Sourced from [#{dependency.display_name}'s releases]" \ + "(#{releases_url}).*\n\n" + msg += quote_and_truncate(releases_text) + msg = link_issues(text: msg) + msg = fix_relative_links( + text: msg, + base_url: source_url + "/blob/HEAD/" + ) + msg = sanitize_template_tags(msg) + msg = sanitize_links_and_mentions(msg) + + build_details_tag(summary: "Release notes", body: msg) + end + + def changelog_cascade + return "" unless changelog_url && changelog_text + + msg = "*Sourced from " \ + "[#{dependency.display_name}'s changelog]" \ + "(#{changelog_url}).*\n\n" + msg += quote_and_truncate(changelog_text) + msg = link_issues(text: msg) + msg = fix_relative_links(text: msg, base_url: changelog_url) + msg = sanitize_template_tags(msg) + msg = sanitize_links_and_mentions(msg) + + build_details_tag(summary: "Changelog", body: msg) + end + + def upgrade_guide_cascade + return "" unless upgrade_guide_url && upgrade_guide_text + + msg = "*Sourced from " \ + "[#{dependency.display_name}'s upgrade guide]" \ + "(#{upgrade_guide_url}).*\n\n" + msg += quote_and_truncate(upgrade_guide_text) + msg = link_issues(text: msg) + msg = fix_relative_links(text: msg, base_url: upgrade_guide_url) + msg = sanitize_template_tags(msg) + msg = sanitize_links_and_mentions(msg) + + build_details_tag(summary: "Upgrade guide", body: msg) + end + + def commits_cascade + return "" unless commits_url && commits + + msg = "" + + commits.last(10).reverse_each do |commit| + title = commit[:message].strip.split("\n").first + title = title.slice(0..76) + "..." if title && title.length > 80 + title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1') + sha = commit[:sha][0, 7] + msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n" + end + + msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" } + + msg += + if commits.count > 10 + "- Additional commits viewable in " \ + "[compare view](#{commits_url})\n" + else + "- See full diff in [compare view](#{commits_url})\n" + end + msg = link_issues(text: msg) + msg = sanitize_links_and_mentions(msg) + + build_details_tag(summary: "Commits", body: msg) + end + + def maintainer_changes_cascade + return "" unless maintainer_changes + + build_details_tag( + summary: "Maintainer changes", + body: sanitize_links_and_mentions(maintainer_changes) + "\n" + ) + end + + def build_details_tag(summary:, body:) + # Azure DevOps does not support
tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html) + # Bitbucket does not support
tag (https://jira.atlassian.com/browse/BCLOUD-20231) + # CodeCommit does not support the
tag (no url available) + if source_provider_supports_html? + msg = "
\n#{summary}\n\n" + msg += body + msg + "
\n" + else + "\n##{summary}\n\n#{body}" + end + end + + def serialized_vulnerability_details(details) + msg = vulnerability_source_line(details) + + msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n" if details["title"] + + if (description = details["description"]) + description.strip.lines.first(20).each { |line| msg += "> #{line}" } + msg += truncated_line if description.strip.lines.count > 20 + end + + msg += "\n" unless msg.end_with?("\n") + msg += "> \n" + msg += vulnerability_version_range_lines(details) + msg + "\n" + end + + def vulnerability_source_line(details) + if details["source_url"] && details["source_name"] + "*Sourced from [#{details['source_name']}]" \ + "(#{details['source_url']}).*\n\n" + elsif details["source_name"] + "*Sourced from #{details['source_name']}.*\n\n" + else + "" + end + end + + def vulnerability_version_range_lines(details) + msg = "" + %w( + patched_versions + unaffected_versions + affected_versions + ).each do |tp| + type = tp.split("_").first.capitalize + next unless details[tp] + + versions_string = details[tp].any? ? details[tp].join("; ") : "none" + versions_string = versions_string.gsub(/(? #{type} versions: #{versions_string}\n" + end + msg + end + + def link_issues(text:) + IssueLinker. + new(source_url: source_url). + link_issues(text: text) + end + + def fix_relative_links(text:, base_url:) + text.gsub(/\[.*?\]\([^)]+\)/) do |link| + next link if link.include?("://") + + relative_path = link.match(/\((.*?)\)/).captures.last + base = base_url.split("://").last.gsub(%r{[^/]*$}, "") + path = File.join(base, relative_path) + absolute_path = + base_url.sub( + %r{(?<=://).*$}, + Pathname.new(path).cleanpath.to_s + ) + link.gsub(relative_path, absolute_path) + end + end + + def quote_and_truncate(text, limit: 50) + lines = text.split("\n") + lines.first(limit).tap do |limited_lines| + limited_lines.map! { |line| "> #{line}\n" } + limited_lines << truncated_line if lines.count > limit + end.join + end + + def truncated_line + # Tables can spill out of truncated details, so we close them + "> \n ... (truncated)\n" + end + + def break_tag + source_provider_supports_html? ? "\n
" : "\n\n" + end + + def source_provider_supports_html? + !%w(azure bitbucket codecommit).include?(source.provider) + end + + def sanitize_links_and_mentions(text, unsafe: false) + LinkAndMentionSanitizer. + new(github_redirection_service: github_redirection_service). + sanitize_links_and_mentions(text: text, unsafe: unsafe) + end + + def sanitize_template_tags(text) + text.gsub(/\<.*?\>/) do |tag| + tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip + + # Unclosed calls to template overflow out of the blockquote block, + # wrecking the rest of our PRs. Other tags don't share this problem. + next "\\#{tag}" if tag_contents.start_with?("template") + + tag + end + end + end + end + end +end diff --git a/common/lib/dependabot/pull_request_creator/pr_name_prefixer.rb b/common/lib/dependabot/pull_request_creator/pr_name_prefixer.rb index 614b975f843..9cf148e21a1 100644 --- a/common/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +++ b/common/lib/dependabot/pull_request_creator/pr_name_prefixer.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "dependabot/clients/azure" +require "dependabot/clients/bitbucket" require "dependabot/clients/codecommit" require "dependabot/clients/github_with_retries" require "dependabot/clients/gitlab_with_retries" @@ -42,15 +43,12 @@ def pr_name_prefix end def capitalize_first_word? - if commit_message_options.key?(:prefix) - return !commit_message_options[:prefix]&.strip&.match?(/\A[a-z]/) - end - - if last_dependabot_commit_style - return capitalise_first_word_from_last_dependabot_commit_style - end + return capitalise_first_word_from_last_dependabot_commit_style if last_dependabot_commit_style capitalise_first_word_from_previous_commits + rescue StandardError + # ignoring failure due to network call to find out if the PR should be capitalized + false end private @@ -63,15 +61,11 @@ def security_fix? def commit_prefix # If a preferred prefix has been explicitly provided, use it - if commit_message_options.key?(:prefix) - return prefix_from_explicitly_provided_details - end + return prefix_from_explicitly_provided_details if commit_message_options.key?(:prefix) # Otherwise, if there is a previous Dependabot commit and it used a # known style, use that as our model for subsequent commits - if last_dependabot_commit_style - return prefix_for_last_dependabot_commit_style - end + return prefix_for_last_dependabot_commit_style if last_dependabot_commit_style # Otherwise we need to detect the user's preferred style from the # existing commits on their repo @@ -89,9 +83,7 @@ def prefix_from_explicitly_provided_details end def explicitly_provided_prefix_string - unless commit_message_options.key?(:prefix) - raise "No explicitly provided prefix!" - end + raise "No explicitly provided prefix!" unless commit_message_options.key?(:prefix) if dependencies.any?(&:production?) commit_message_options[:prefix].to_s @@ -172,6 +164,7 @@ def last_dependabot_commit_prefix last_dependabot_commit_message&.split(/[:(]/)&.first end + # rubocop:disable Metrics/PerceivedComplexity def using_angular_commit_messages? return false if recent_commit_messages.none? @@ -180,9 +173,7 @@ def using_angular_commit_messages? end # Definitely not using Angular commits if < 30% match angular commits - if angular_messages.count.to_f / recent_commit_messages.count < 0.3 - return false - end + return false if angular_messages.count.to_f / recent_commit_messages.count < 0.3 eslint_only_pres = ESLINT_PREFIXES.map(&:downcase) - ANGULAR_PREFIXES angular_only_pres = ANGULAR_PREFIXES - ESLINT_PREFIXES.map(&:downcase) @@ -202,6 +193,7 @@ def using_angular_commit_messages? true end + # rubocop:enable Metrics/PerceivedComplexity def using_eslint_commit_messages? return false if recent_commit_messages.none? @@ -242,9 +234,7 @@ def angular_commit_prefix "build" end - if capitalize_angular_commit_prefix? - commit_prefix = commit_prefix.capitalize - end + commit_prefix = commit_prefix.capitalize if capitalize_angular_commit_prefix? commit_prefix end @@ -254,9 +244,7 @@ def capitalize_angular_commit_prefix? ANGULAR_PREFIXES.any? { |pre| message.match?(/#{pre}[:(]/i) } end - if semantic_messages.none? - return last_dependabot_commit_message&.start_with?(/[A-Z]/) - end + return last_dependabot_commit_message&.start_with?(/[A-Z]/) if semantic_messages.none? capitalized_msgs = semantic_messages. select { |m| m.start_with?(/[A-Z]/) } @@ -278,6 +266,7 @@ def recent_commit_messages when "github" then recent_github_commit_messages when "gitlab" then recent_gitlab_commit_messages when "azure" then recent_azure_commit_messages + when "bitbucket" then recent_bitbucket_commit_messages when "codecommit" then recent_codecommit_commit_messages else raise "Unsupported provider: #{source.provider}" end @@ -292,8 +281,7 @@ def recent_github_commit_messages reject { |c| c.author&.type == "Bot" }. reject { |c| c.commit&.message&.start_with?("Merge") }. map(&:commit). - map(&:message). - compact. + filter_map(&:message). map(&:strip) end @@ -304,8 +292,7 @@ def recent_gitlab_commit_messages @recent_gitlab_commit_messages. reject { |c| c.author_email == dependabot_email }. reject { |c| c.message&.start_with?("merge !") }. - map(&:message). - compact. + filter_map(&:message). map(&:strip) end @@ -316,8 +303,18 @@ def recent_azure_commit_messages @recent_azure_commit_messages. reject { |c| azure_commit_author_email(c) == dependabot_email }. reject { |c| c.fetch("comment")&.start_with?("Merge") }. - map { |c| c.fetch("comment") }. - compact. + filter_map { |c| c.fetch("comment") }. + map(&:strip) + end + + def recent_bitbucket_commit_messages + @recent_bitbucket_commit_messages ||= + bitbucket_client_for_source.commits(source.repo) + + @recent_bitbucket_commit_messages. + reject { |c| bitbucket_commit_author_email(c) == dependabot_email }. + filter_map { |c| c.fetch("message", nil) }. + reject { |m| m.start_with?("Merge") }. map(&:strip) end @@ -327,8 +324,7 @@ def recent_codecommit_commit_messages @recent_codecommit_commit_messages.commits. reject { |c| c.author.email == dependabot_email }. reject { |c| c.message&.start_with?("Merge") }. - map(&:message). - compact. + filter_map(&:message). map(&:strip) end @@ -338,6 +334,7 @@ def last_dependabot_commit_message when "github" then last_github_dependabot_commit_message when "gitlab" then last_gitlab_dependabot_commit_message when "azure" then last_azure_dependabot_commit_message + when "bitbucket" then last_bitbucket_dependabot_commit_message when "codecommit" then last_codecommit_dependabot_commit_message else raise "Unsupported provider: #{source.provider}" end @@ -379,6 +376,16 @@ def last_azure_dependabot_commit_message strip end + def last_bitbucket_dependabot_commit_message + @recent_bitbucket_commit_messages ||= + bitbucket_client_for_source.commits(source.repo) + + @recent_bitbucket_commit_messages. + find { |c| bitbucket_commit_author_email(c) == dependabot_email }&. + fetch("message", nil)&. + strip + end + def last_codecommit_dependabot_commit_message @recent_codecommit_commit_messages ||= codecommit_client_for_source.commits(source.repo) @@ -393,6 +400,11 @@ def azure_commit_author_email(commit) commit.fetch("author").fetch("email", "") end + def bitbucket_commit_author_email(commit) + matches = commit.fetch("author").fetch("raw").match(/<(.*)>/) + matches ? matches[1] : "" + end + def github_client_for_source @github_client_for_source ||= Dependabot::Clients::GithubWithRetries.for_source( @@ -417,6 +429,14 @@ def azure_client_for_source ) end + def bitbucket_client_for_source + @bitbucket_client_for_source ||= + Dependabot::Clients::Bitbucket.for_source( + source: source, + credentials: credentials + ) + end + def codecommit_client_for_source @codecommit_client_for_source ||= Dependabot::Clients::CodeCommit.for_source( diff --git a/common/lib/dependabot/pull_request_updater.rb b/common/lib/dependabot/pull_request_updater.rb index 22dcfef43fa..4f924de4c4a 100644 --- a/common/lib/dependabot/pull_request_updater.rb +++ b/common/lib/dependabot/pull_request_updater.rb @@ -2,17 +2,19 @@ require "dependabot/pull_request_updater/github" require "dependabot/pull_request_updater/gitlab" +require "dependabot/pull_request_updater/azure" module Dependabot class PullRequestUpdater class BranchProtected < StandardError; end attr_reader :source, :files, :base_commit, :old_commit, :credentials, - :pull_request_number, :author_details, :signature_key + :pull_request_number, :author_details, :signature_key, :provider_metadata def initialize(source:, base_commit:, old_commit:, files:, credentials:, pull_request_number:, - author_details: nil, signature_key: nil) + author_details: nil, signature_key: nil, + provider_metadata: {}) @source = source @base_commit = base_commit @old_commit = old_commit @@ -21,12 +23,14 @@ def initialize(source:, base_commit:, old_commit:, files:, @pull_request_number = pull_request_number @author_details = author_details @signature_key = signature_key + @provider_metadata = provider_metadata end def update case source.provider when "github" then github_updater.update when "gitlab" then gitlab_updater.update + when "azure" then azure_updater.update else raise "Unsupported provider #{source.provider}" end end @@ -53,7 +57,20 @@ def gitlab_updater old_commit: old_commit, files: files, credentials: credentials, - pull_request_number: pull_request_number + pull_request_number: pull_request_number, + target_project_id: provider_metadata[:target_project_id] + ) + end + + def azure_updater + Azure.new( + source: source, + base_commit: base_commit, + old_commit: old_commit, + files: files, + credentials: credentials, + pull_request_number: pull_request_number, + author_details: author_details ) end end diff --git a/common/lib/dependabot/pull_request_updater/azure.rb b/common/lib/dependabot/pull_request_updater/azure.rb new file mode 100644 index 00000000000..b3ecfdc9fd1 --- /dev/null +++ b/common/lib/dependabot/pull_request_updater/azure.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +require "dependabot/clients/azure" +require "securerandom" + +module Dependabot + class PullRequestUpdater + class Azure + class PullRequestUpdateFailed < Dependabot::DependabotError; end + + OBJECT_ID_FOR_BRANCH_DELETE = "0000000000000000000000000000000000000000" + + attr_reader :source, :files, :base_commit, :old_commit, :credentials, + :pull_request_number, :author_details + + def initialize(source:, files:, base_commit:, old_commit:, + credentials:, pull_request_number:, author_details: nil) + @source = source + @files = files + @base_commit = base_commit + @old_commit = old_commit + @credentials = credentials + @pull_request_number = pull_request_number + @author_details = author_details + end + + def update + return unless pull_request_exists? && source_branch_exists? + + update_source_branch + end + + private + + def azure_client_for_source + @azure_client_for_source ||= + Dependabot::Clients::Azure.for_source( + source: source, + credentials: credentials + ) + end + + def pull_request_exists? + pull_request + rescue Dependabot::Clients::Azure::NotFound + false + end + + def source_branch_exists? + azure_client_for_source.branch(source_branch_name) + rescue Dependabot::Clients::Azure::NotFound + false + end + + # Currently the PR diff in ADO shows difference in commits instead of actual diff in files. + # This workaround puts the target branch commit history on the source branch along with the file changes. + def update_source_branch + # 1) Push the file changes to a newly created temporary branch (from base commit) + new_commit = create_temp_branch + # 2) Update PR source branch to point to the temp branch head commit. + response = update_branch(source_branch_name, old_source_branch_commit, new_commit) + # 3) Delete temp branch + update_branch(temp_branch_name, new_commit, OBJECT_ID_FOR_BRANCH_DELETE) + + raise PullRequestUpdateFailed, response.fetch("customMessage", nil) unless response.fetch("success", false) + end + + def pull_request + @pull_request ||= + azure_client_for_source.pull_request(pull_request_number.to_s) + end + + def source_branch_name + @source_branch_name ||= pull_request&.fetch("sourceRefName")&.gsub("refs/heads/", "") + end + + def create_temp_branch + author = author_details&.slice(:name, :email, :date) + author = nil unless author&.any? + + response = azure_client_for_source.create_commit( + temp_branch_name, + base_commit, + commit_message, + files, + author + ) + + JSON.parse(response.body).fetch("refUpdates").first.fetch("newObjectId") + end + + def temp_branch_name + @temp_branch_name ||= + "#{source_branch_name}-temp-#{SecureRandom.uuid[0..6]}" + end + + def update_branch(branch_name, old_commit, new_commit) + azure_client_for_source.update_ref( + branch_name, + old_commit, + new_commit + ) + end + + # For updating source branch, we require the latest commit for the source branch. + def commit_being_updated + @commit_being_updated ||= + azure_client_for_source.commits(source_branch_name).first + end + + def old_source_branch_commit + commit_being_updated.fetch("commitId") + end + + def commit_message + commit_being_updated.fetch("comment") + end + end + end +end diff --git a/common/lib/dependabot/pull_request_updater/github.rb b/common/lib/dependabot/pull_request_updater/github.rb index 135ffda5118..cc835320955 100644 --- a/common/lib/dependabot/pull_request_updater/github.rb +++ b/common/lib/dependabot/pull_request_updater/github.rb @@ -124,14 +124,7 @@ def create_commit def create_tree file_trees = files.map do |file| - if %w(file symlink).include?(file.type) - { - path: (file.symlink_target || file.path).sub(%r{^/}, ""), - mode: "100644", - type: "blob", - content: file.content - } - elsif file.type == "submodule" + if file.type == "submodule" { path: file.path.sub(%r{^/}, ""), mode: "160000", @@ -139,7 +132,23 @@ def create_tree sha: file.content } else - raise "Unknown file type #{file.type}" + content = if file.operation == Dependabot::DependencyFile::Operation::DELETE + { sha: nil } + elsif file.binary? + sha = github_client_for_source.create_blob( + source.repo, file.content, "base64" + ) + { sha: sha } + else + { content: file.content } + end + + { + path: (file.symlink_target || + file.path).sub(%r{^/}, ""), + mode: "100644", + type: "blob" + }.merge(content) end end @@ -164,7 +173,8 @@ def update_branch(commit) if e.message.match?(/protected branch/i) || e.message.match?(/not authorized to push/i) || - e.message.match?(/must not contain merge commits/) + e.message.include?("must not contain merge commits") || + e.message.match?(/required status check/i) raise BranchProtected end @@ -172,28 +182,31 @@ def update_branch(commit) end def commit_message - # Take the commit message from the old commit - commit_being_updated.message + fallback_message = + "#{pull_request.title}" \ + "\n\n" \ + "Dependabot couldn't find the original pull request head commit, " \ + "#{old_commit}." + + # Take the commit message from the old commit. If the old commit can't + # be found, use the PR title as the commit message. + commit_being_updated&.message || fallback_message end def commit_being_updated - @commit_being_updated ||= + return @commit_being_updated if defined?(@commit_being_updated) + + @commit_being_updated = if pull_request.commits == 1 github_client_for_source. git_commit(source.repo, pull_request.head.sha) else - author_name = author_details&.fetch(:name, nil) || "dependabot" commits = github_client_for_source. - pull_request_commits(source.repo, pull_request_number). - reverse - - commit = - commits.find { |c| c.sha == old_commit } || - commits.find { |c| c.commit.author.name.include?(author_name) } || - commits.first + pull_request_commits(source.repo, pull_request_number) - commit.commit + commit = commits.find { |c| c.sha == old_commit } + commit&.commit end end diff --git a/common/lib/dependabot/pull_request_updater/gitlab.rb b/common/lib/dependabot/pull_request_updater/gitlab.rb index 7838e51c8f3..dec033c5ce6 100644 --- a/common/lib/dependabot/pull_request_updater/gitlab.rb +++ b/common/lib/dependabot/pull_request_updater/gitlab.rb @@ -8,16 +8,17 @@ module Dependabot class PullRequestUpdater class Gitlab attr_reader :source, :files, :base_commit, :old_commit, :credentials, - :pull_request_number + :pull_request_number, :target_project_id def initialize(source:, base_commit:, old_commit:, files:, - credentials:, pull_request_number:) + credentials:, pull_request_number:, target_project_id:) @source = source @base_commit = base_commit @old_commit = old_commit @files = files @credentials = credentials @pull_request_number = pull_request_number + @target_project_id = target_project_id end def update @@ -39,7 +40,7 @@ def merge_request_exists? def merge_request @merge_request ||= gitlab_client_for_source.merge_request( - source.repo, + target_project_id || source.repo, pull_request_number ) end @@ -63,23 +64,36 @@ def commit_being_updated end def create_commit - actions = files.map do |file| - { - action: "update", - file_path: file.type == "symlink" ? file.symlink_target : file.path, - content: file.content - } - end - gitlab_client_for_source.create_commit( source.repo, merge_request.source_branch, commit_being_updated.title, - actions, + file_actions, force: true, start_branch: merge_request.target_branch ) end + + def file_actions + files.map do |file| + { + action: file_action(file), + file_path: file.type == "symlink" ? file.symlink_target : file.path, + content: file.content + } + end + end + + # @param [DependencyFile] file + def file_action(file) + if file.operation == Dependabot::DependencyFile::Operation::DELETE + "delete" + elsif file.operation == Dependabot::DependencyFile::Operation::CREATE + "create" + else + "update" + end + end end end end diff --git a/common/lib/dependabot/registry_client.rb b/common/lib/dependabot/registry_client.rb new file mode 100644 index 00000000000..baafd05f4f1 --- /dev/null +++ b/common/lib/dependabot/registry_client.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "dependabot/shared_helpers" + +# This class provides a thin wrapper around our normal usage of Excon as a simple HTTP client in order to +# provide some minor caching functionality. +# +# This is not used to support full response caching currently, we just use it to ensure we detect unreachable +# hosts and fast-fail on any subsequent requests to them to avoid excessive use of retries and connect- or +# read-timeouts as some jobs tend to be sensitive to exceeding our overall 45 minute timeout. +module Dependabot + class RegistryClient + @cached_errors = {} + + def self.get(url:, headers: {}, options: {}) + raise cached_error_for(url) if cached_error_for(url) + + Excon.get( + url, + idempotent: true, + **SharedHelpers.excon_defaults({ headers: headers }.merge(options)) + ) + rescue Excon::Error::Timeout => e + cache_error(url, e) + raise e + end + + def self.head(url:, headers: {}, options: {}) + raise cached_error_for(url) if cached_error_for(url) + + Excon.head( + url, + idempotent: true, + **SharedHelpers.excon_defaults({ headers: headers }.merge(options)) + ) + rescue Excon::Error::Timeout => e + cache_error(url, e) + raise e + end + + def self.clear_cache! + @cached_errors = {} + end + + private_class_method def self.cache_error(url, error) + host = URI(url).host + @cached_errors[host] = error + end + + private_class_method def self.cached_error_for(url) + host = URI(url).host + @cached_errors.fetch(host, nil) + end + end +end diff --git a/common/lib/dependabot/security_advisory.rb b/common/lib/dependabot/security_advisory.rb index 90b3bcb92e1..b5e26ad0300 100644 --- a/common/lib/dependabot/security_advisory.rb +++ b/common/lib/dependabot/security_advisory.rb @@ -5,13 +5,15 @@ module Dependabot class SecurityAdvisory attr_reader :dependency_name, :package_manager, - :vulnerable_versions, :safe_versions + :vulnerable_versions, :safe_versions, + :vulnerable_version_strings def initialize(dependency_name:, package_manager:, vulnerable_versions: [], safe_versions: []) @dependency_name = dependency_name @package_manager = package_manager - @vulnerable_versions = vulnerable_versions || [] + @vulnerable_version_strings = vulnerable_versions || [] + @vulnerable_versions = [] @safe_versions = safe_versions || [] convert_string_version_requirements @@ -43,10 +45,58 @@ def vulnerable?(version) safe_versions.any? end + # Check if the advisory is fixed by the updated dependency + # + # @param dependency [Dependabot::Dependency] Updated dependency + # @return [Boolean] + def fixed_by?(dependency) + # Handle case mismatch between the security advisory and parsed name + return false unless dependency_name.casecmp(dependency.name).zero? + return false unless package_manager == dependency.package_manager + # TODO: Support no previous version to the same level as dependency graph + # and security alerts. We currently ignore dependency updates without a + # previous version because we don't know if the dependency was vulerable. + return false unless dependency.previous_version + return false unless version_class.correct?(dependency.previous_version) + + # Ignore deps that weren't previously vulnerable + return false unless affects_version?(dependency.previous_version) + + # Removing a dependency is a way to fix the vulnerability + return true if dependency.removed? + + # Select deps that are now fixed + !affects_version?(dependency.version) + end + + # Check if the version is affected by the advisory + # + # @param version [Dependabot::::Version] version class + # @return [Boolean] + def affects_version?(version) + return false unless version_class.correct?(version) + return false unless [*safe_versions, *vulnerable_versions].any? + + version = version_class.new(version) + + # If version is known safe for this advisory, it's not vulnerable + return false if safe_versions.any? { |r| r.satisfied_by?(version) } + + # If in the vulnerable range and not known safe, it's vulnerable + return true if vulnerable_versions.any? { |r| r.satisfied_by?(version) } + + # If a vulnerable range present but not met, it's not vulnerable + return false if vulnerable_versions.any? + + # Finally, if no vulnerable range provided, but a safe range provided, + # and this versions isn't included (checked earler), it's vulnerable + safe_versions.any? + end + private def convert_string_version_requirements - @vulnerable_versions = vulnerable_versions.flat_map do |vuln_str| + @vulnerable_versions = vulnerable_version_strings.flat_map do |vuln_str| next vuln_str unless vuln_str.is_a?(String) requirement_class.requirements_array(vuln_str) @@ -62,13 +112,13 @@ def convert_string_version_requirements def check_version_requirements unless vulnerable_versions.is_a?(Array) && vulnerable_versions.all? { |i| requirement_class <= i.class } - raise ArgumentError, "vulnerable_versions must be an array "\ + raise ArgumentError, "vulnerable_versions must be an array " \ "of #{requirement_class} instances" end unless safe_versions.is_a?(Array) && safe_versions.all? { |i| requirement_class <= i.class } - raise ArgumentError, "safe_versions must be an array "\ + raise ArgumentError, "safe_versions must be an array " \ "of #{requirement_class} instances" end end diff --git a/common/lib/dependabot/shared_helpers.rb b/common/lib/dependabot/shared_helpers.rb index 881dc95d1a9..d1c027749f6 100644 --- a/common/lib/dependabot/shared_helpers.rb +++ b/common/lib/dependabot/shared_helpers.rb @@ -1,96 +1,106 @@ # frozen_string_literal: true -require "json" -require "tmpdir" -require "excon" -require "English" +require "active_support/notifications" require "digest" +require "English" +require "excon" +require "fileutils" +require "json" require "open3" require "shellwords" +require "tmpdir" + +require "dependabot/utils" +require "dependabot/errors" +require "dependabot/version" module Dependabot module SharedHelpers - BUMP_TMP_FILE_PREFIX = "dependabot_" - BUMP_TMP_DIR_PATH = "tmp" GIT_CONFIG_GLOBAL_PATH = File.expand_path("~/.gitconfig") - - class ChildProcessFailed < StandardError - attr_reader :error_class, :error_message, :error_backtrace - - def initialize(error_class:, error_message:, error_backtrace:) - @error_class = error_class - @error_message = error_message - @error_backtrace = error_backtrace - - msg = "Child process raised #{error_class} with message: "\ - "#{error_message}" - super(msg) - set_backtrace(error_backtrace) + USER_AGENT = "dependabot-core/#{Dependabot::VERSION} " \ + "#{Excon::USER_AGENT} ruby/#{RUBY_VERSION} " \ + "(#{RUBY_PLATFORM}) " \ + "(+https://github.com/dependabot/dependabot-core)" + SIGKILL = 9 + + def self.in_a_temporary_repo_directory(directory = "/", + repo_contents_path = nil, + &block) + if repo_contents_path + path = Pathname.new(File.join(repo_contents_path, directory)). + expand_path + reset_git_repo(repo_contents_path) + # Handle missing directories by creating an empty one and relying on the + # file fetcher to raise a DependencyFileNotFound error + FileUtils.mkdir_p(path) + Dir.chdir(path) { yield(path) } + else + in_a_temporary_directory(directory, &block) end end def self.in_a_temporary_directory(directory = "/") - Dir.mkdir(BUMP_TMP_DIR_PATH) unless Dir.exist?(BUMP_TMP_DIR_PATH) - Dir.mktmpdir(BUMP_TMP_FILE_PREFIX, BUMP_TMP_DIR_PATH) do |dir| - path = Pathname.new(File.join(dir, directory)).expand_path + FileUtils.mkdir_p(Utils::BUMP_TMP_DIR_PATH) + tmp_dir = Dir.mktmpdir(Utils::BUMP_TMP_FILE_PREFIX, Utils::BUMP_TMP_DIR_PATH) + + begin + path = Pathname.new(File.join(tmp_dir, directory)).expand_path FileUtils.mkpath(path) Dir.chdir(path) { yield(path) } - end - end - - def self.in_a_forked_process - read, write = IO.pipe - - pid = fork do - read.close - result = yield - rescue Exception => e # rubocop:disable Lint/RescueException - result = { _error_details: { error_class: e.class.to_s, - error_message: e.message, - error_backtrace: e.backtrace } } ensure - Marshal.dump(result, write) - exit!(0) + FileUtils.rm_rf(tmp_dir) end - - write.close - result = read.read - Process.wait(pid) - result = Marshal.load(result) # rubocop:disable Security/MarshalLoad - - return result unless result.is_a?(Hash) && result[:_error_details] - - raise ChildProcessFailed, result[:_error_details] end - class HelperSubprocessFailed < StandardError - def initialize(message:, error_context:) + class HelperSubprocessFailed < Dependabot::DependabotError + attr_reader :error_class, :error_context, :trace + + def initialize(message:, error_context:, error_class: nil, trace: nil) super(message) + @error_class = error_class || "" @error_context = error_context - @command = error_context[:command] + @fingerprint = error_context[:fingerprint] || error_context[:command] + @trace = trace end def raven_context - { fingerprint: [@command], extra: @error_context } + { fingerprint: [@fingerprint], extra: @error_context.except(:stderr_output, :fingerprint) } end end # Escapes all special characters, e.g. = & | <> def self.escape_command(command) - command_parts = command.split(" ").map(&:strip).reject(&:empty?) + command_parts = command.split.map(&:strip).reject(&:empty?) Shellwords.join(command_parts) end + # rubocop:disable Metrics/MethodLength def self.run_helper_subprocess(command:, function:, args:, env: nil, stderr_to_stdout: false, - escape_command_str: true) + allow_unsafe_shell_command: false) start = Time.now stdin_data = JSON.dump(function: function, args: args) - cmd = escape_command_str ? escape_command(command) : command + cmd = allow_unsafe_shell_command ? command : escape_command(command) + + # NOTE: For debugging native helpers in specs and dry-run: outputs the + # bash command to run in the tmp directory created by + # in_a_temporary_directory + if ENV["DEBUG_FUNCTION"] == function + puts helper_subprocess_bash_command(stdin_data: stdin_data, command: cmd, env: env) + # Pause execution so we can run helpers inside the temporary directory + debugger # rubocop:disable Lint/Debugger + end + env_cmd = [env, cmd].compact stdout, stderr, process = Open3.capture3(*env_cmd, stdin_data: stdin_data) time_taken = Time.now - start + if ENV["DEBUG_HELPERS"] == "true" + puts env_cmd + puts stdout + puts stderr + end + # Some package managers output useful stuff to stderr instead of stdout so # we want to parse this, most package manager will output garbage here so # would mess up json response from stdout @@ -102,7 +112,8 @@ def self.run_helper_subprocess(command:, function:, args:, env: nil, args: args, time_taken: time_taken, stderr_output: stderr ? stderr[0..50_000] : "", # Truncate to ~100kb - process_exit_value: process.to_s + process_exit_value: process.to_s, + process_termsig: process.termsig } response = JSON.parse(stdout) @@ -110,14 +121,18 @@ def self.run_helper_subprocess(command:, function:, args:, env: nil, raise HelperSubprocessFailed.new( message: response["error"], - error_context: error_context + error_class: response["error_class"], + error_context: error_context, + trace: response["trace"] ) rescue JSON::ParserError raise HelperSubprocessFailed.new( message: stdout || "No output from command", + error_class: "JSON::ParserError", error_context: error_context ) end + # rubocop:enable Metrics/MethodLength def self.excon_middleware Excon.defaults[:middlewares] + @@ -125,58 +140,66 @@ def self.excon_middleware [Excon::Middleware::RedirectFollower] end - def self.excon_defaults + def self.excon_headers(headers = nil) + headers ||= {} + { + "User-Agent" => USER_AGENT + }.merge(headers) + end + + def self.excon_defaults(options = nil) + options ||= {} + headers = options.delete(:headers) { + instrumentor: ActiveSupport::Notifications, connect_timeout: 5, write_timeout: 5, - read_timeout: 5, + read_timeout: 20, + retry_limit: 4, # Excon defaults to four retries, but let's set it explicitly for clarity omit_default_port: true, - middlewares: excon_middleware - } + middlewares: excon_middleware, + headers: excon_headers(headers) + }.merge(options) end def self.with_git_configured(credentials:) - backup_git_config_path = stash_global_git_config - configure_git_to_use_https_with_credentials(credentials) + backup_git_config_path, safe_directories = stash_global_git_config + configure_git_to_use_https_with_credentials(credentials, safe_directories) yield + rescue Errno::ENOSPC => e + raise Dependabot::OutOfDisk, e.message ensure reset_global_git_config(backup_git_config_path) end - def self.configure_git_to_use_https_with_credentials(credentials) - configure_git_to_use_https - configure_git_credentials(credentials) + def self.credential_helper_path + File.join(__dir__, "../../bin/git-credential-store-immutable") end - def self.configure_git_to_use_https - # Note: we use --global here (rather than --system) so that Dependabot - # can be run without privileged access - run_shell_command( - 'git config --global --replace-all url."https://github.com/".'\ - "insteadOf ssh://git@github.com/ && "\ - 'git config --global --add url."https://github.com/".'\ - "insteadOf ssh://git@github.com: && "\ - 'git config --global --add url."https://github.com/".'\ - "insteadOf git@github.com: && "\ - 'git config --global --add url."https://github.com/".'\ - "insteadOf git@github.com/ && "\ - 'git config --global --add url."https://github.com/".'\ - "insteadOf git://github.com/" - ) - end + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/PerceivedComplexity + def self.configure_git_to_use_https_with_credentials(credentials, safe_directories) + File.open(GIT_CONFIG_GLOBAL_PATH, "w") do |file| + file << "# Generated by dependabot/dependabot-core" + end - def self.configure_git_credentials(credentials) # Then add a file-based credential store that loads a file in this repo. # Under the hood this uses git credential-store, but it's invoked through # a wrapper binary that only allows non-mutating commands. Without this, # whenever the credentials are deemed to be invalid, they're erased. - credential_helper_path = - File.join(__dir__, "../../bin/git-credential-store-immutable") run_shell_command( - "git config --global credential.helper "\ - "'!#{credential_helper_path} --file=#{Dir.pwd}/git.store'" + "git config --global credential.helper " \ + "'!#{credential_helper_path} --file #{Dir.pwd}/git.store'", + allow_unsafe_shell_command: true, + fingerprint: "git config --global credential.helper ''" ) + # see https://github.blog/2022-04-12-git-security-vulnerability-announced/ + safe_directories ||= [] + safe_directories.each do |path| + run_shell_command("git config --global --add safe.directory #{path}") + end + github_credentials = credentials. select { |c| c["type"] == "git_source" }. select { |c| c["host"] == "github.com" }. @@ -188,6 +211,9 @@ def self.configure_git_credentials(credentials) github_credentials.find { |c| !c["password"]&.start_with?("v1.") } || github_credentials.first + # Make sure we always have https alternatives for github.com. + configure_git_to_use_https("github.com") if github_credential.nil? + deduped_credentials = credentials - github_credentials + [github_credential].compact @@ -199,15 +225,50 @@ def self.configure_git_credentials(credentials) next unless cred["username"] && cred["password"] authenticated_url = - "https://#{cred.fetch('username')}:#{cred.fetch('password')}"\ + "https://#{cred.fetch('username')}:#{cred.fetch('password')}" \ "@#{cred.fetch('host')}" git_store_content += authenticated_url + "\n" + configure_git_to_use_https(cred.fetch("host")) end # Save the file File.write("git.store", git_store_content) end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/PerceivedComplexity + + def self.configure_git_to_use_https(host) + # NOTE: we use --global here (rather than --system) so that Dependabot + # can be run without privileged access + run_shell_command( + "git config --global --replace-all url.https://#{host}/." \ + "insteadOf ssh://git@#{host}/" + ) + run_shell_command( + "git config --global --add url.https://#{host}/." \ + "insteadOf ssh://git@#{host}:" + ) + run_shell_command( + "git config --global --add url.https://#{host}/." \ + "insteadOf git@#{host}:" + ) + run_shell_command( + "git config --global --add url.https://#{host}/." \ + "insteadOf git@#{host}/" + ) + run_shell_command( + "git config --global --add url.https://#{host}/." \ + "insteadOf git://#{host}/" + ) + end + + def self.reset_git_repo(path) + Dir.chdir(path) do + run_shell_command("git reset HEAD --hard") + run_shell_command("git clean -fx") + end + end def self.stash_global_git_config return unless File.exist?(GIT_CONFIG_GLOBAL_PATH) @@ -216,28 +277,38 @@ def self.stash_global_git_config digest = Digest::SHA2.hexdigest(contents)[0...10] backup_path = GIT_CONFIG_GLOBAL_PATH + ".backup-#{digest}" + # to preserve safe directories from global .gitconfig + output, process = Open3.capture2("git config --global --get-all safe.directory") + safe_directories = [] + safe_directories = output.split("\n").compact if process.success? + FileUtils.mv(GIT_CONFIG_GLOBAL_PATH, backup_path) - backup_path + [backup_path, safe_directories] end def self.reset_global_git_config(backup_path) - return if backup_path.nil? + if backup_path.nil? + FileUtils.rm(GIT_CONFIG_GLOBAL_PATH) + return + end return unless File.exist?(backup_path) FileUtils.mv(backup_path, GIT_CONFIG_GLOBAL_PATH) end - def self.run_shell_command(command) + def self.run_shell_command(command, allow_unsafe_shell_command: false, env: {}, fingerprint: nil) start = Time.now - stdout, process = Open3.capture2e(command) + cmd = allow_unsafe_shell_command ? command : escape_command(command) + stdout, process = Open3.capture2e(env || {}, cmd) time_taken = Time.now - start # Raise an error with the output from the shell session if the # command returns a non-zero status - return if process.success? + return stdout if process.success? error_context = { - command: command, + command: cmd, + fingerprint: fingerprint, time_taken: time_taken, process_exit_value: process.to_s } @@ -247,5 +318,12 @@ def self.run_shell_command(command) error_context: error_context ) end + + def self.helper_subprocess_bash_command(command:, stdin_data:, env:) + escaped_stdin_data = stdin_data.gsub("\"", "\\\"") + env_keys = env ? env.compact.map { |k, v| "#{k}=#{v}" }.join(" ") + " " : "" + "$ cd #{Dir.pwd} && echo \"#{escaped_stdin_data}\" | #{env_keys}#{command}" + end + private_class_method :helper_subprocess_bash_command end end diff --git a/common/lib/dependabot/source.rb b/common/lib/dependabot/source.rb index 6fd0f8f9a28..faeaec5f77b 100644 --- a/common/lib/dependabot/source.rb +++ b/common/lib/dependabot/source.rb @@ -7,40 +7,64 @@ class Source (?:\.com)[/:] (?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+) (?:(?:/tree|/blob)/(?[^/]+)/(?.*)[\#|/])? - }x.freeze + }x + + GITHUB_ENTERPRISE_SOURCE = %r{ + (?(http://|https://|git://|ssh://))* + (?[^@]+@)* + (?[^/]+) + [/:] + (?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+) + (?:(?:/tree|/blob)/(?[^/]+)/(?.*)[\#|/])? + }x GITLAB_SOURCE = %r{ (?gitlab) (?:\.com)[/:] - (?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+) - (?:(?:/tree|/blob)/(?[^/]+)/(?.*)[\#|/])? - }x.freeze + (?[^/]+/(?:(?!\.git)[^/])+((?!/tree|/blob/|/-)/[^/]+)?) + (?:(?:/tree|/blob)/(?[^/]+)/(?.*)[\#|/].*)? + }x BITBUCKET_SOURCE = %r{ (?bitbucket) (?:\.org)[/:] (?[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+) (?:(?:/src)/(?[^/]+)/(?.*)[\#|/])? - }x.freeze + }x AZURE_SOURCE = %r{ (?azure) (?:\.com)[/:] (?[\w.-]+/([\w.-]+/)?(?:_git/)(?:(?!\.git|\.\s)[\w.-])+) - }x.freeze + }x + + CODECOMMIT_SOURCE = %r{ + (?(http://|https://|git://|ssh://)) + git[-] + (?codecommit) + (?:.*) + (?:\.com/v1/repos/) + (?([^/]*)) + (?:/)?(?[^?]*)? + [?]? + (?.*)? + }x SOURCE_REGEX = / (?:#{GITHUB_SOURCE})| (?:#{GITLAB_SOURCE})| (?:#{BITBUCKET_SOURCE})| - (?:#{AZURE_SOURCE}) - /x.freeze + (?:#{AZURE_SOURCE})| + (?:#{CODECOMMIT_SOURCE}) + /x + + IGNORED_PROVIDER_HOSTS = %w(gitbox.apache.org svn.apache.org fuchsia.googlesource.com).freeze attr_accessor :provider, :repo, :directory, :branch, :commit, :hostname, :api_endpoint def self.from_url(url_string) - return unless url_string&.match?(SOURCE_REGEX) + return github_enterprise_from_url(url_string) unless url_string&.match?(SOURCE_REGEX) captures = url_string.match(SOURCE_REGEX).named_captures @@ -52,11 +76,41 @@ def self.from_url(url_string) ) end + def self.github_enterprise_from_url(url_string) + captures = url_string&.match(GITHUB_ENTERPRISE_SOURCE)&.named_captures + return unless captures + return if IGNORED_PROVIDER_HOSTS.include?(captures.fetch("host")) + + base_url = "https://#{captures.fetch('host')}" + + return unless github_enterprise?(base_url) + + new( + provider: "github", + repo: captures.fetch("repo"), + directory: captures.fetch("directory"), + branch: captures.fetch("branch"), + hostname: captures.fetch("host"), + api_endpoint: File.join(base_url, "api", "v3") + ) + end + + def self.github_enterprise?(base_url) + resp = Excon.get(File.join(base_url, "status")) + resp.status == 200 && + # Alternatively: resp.headers["Server"] == "GitHub.com", but this + # currently doesn't work with development environments + resp.headers["X-GitHub-Request-Id"] && + !resp.headers["X-GitHub-Request-Id"].empty? + rescue StandardError + false + end + def initialize(provider:, repo:, directory: nil, branch: nil, commit: nil, hostname: nil, api_endpoint: nil) if (hostname.nil? ^ api_endpoint.nil?) && (provider != "codecommit") - msg = "Both hostname and api_endpoint must be specified if either "\ - "are. Alternatively, both may be left blank to use the "\ + msg = "Both hostname and api_endpoint must be specified if either " \ + "are. Alternatively, both may be left blank to use the " \ "provider's defaults." raise msg end diff --git a/common/lib/dependabot/update_checkers/base.rb b/common/lib/dependabot/update_checkers/base.rb index 7a90a12c535..31c927252a9 100644 --- a/common/lib/dependabot/update_checkers/base.rb +++ b/common/lib/dependabot/update_checkers/base.rb @@ -7,21 +7,25 @@ module Dependabot module UpdateCheckers class Base - attr_reader :dependency, :dependency_files, :credentials, - :ignored_versions, :raise_on_ignored, - :security_advisories, :requirements_update_strategy - - def initialize(dependency:, dependency_files:, credentials:, - ignored_versions: [], raise_on_ignored: false, - security_advisories: [], - requirements_update_strategy: nil) + attr_reader :dependency, :dependency_files, :repo_contents_path, + :credentials, :ignored_versions, :raise_on_ignored, + :security_advisories, :requirements_update_strategy, + :options + + def initialize(dependency:, dependency_files:, repo_contents_path: nil, + credentials:, ignored_versions: [], + raise_on_ignored: false, security_advisories: [], + requirements_update_strategy: nil, + options: {}) @dependency = dependency @dependency_files = dependency_files + @repo_contents_path = repo_contents_path @credentials = credentials @requirements_update_strategy = requirements_update_strategy @ignored_versions = ignored_versions @raise_on_ignored = raise_on_ignored @security_advisories = security_advisories + @options = options end def up_to_date? @@ -34,7 +38,7 @@ def up_to_date? def can_update?(requirements_to_unlock:) # Can't update if all versions are being ignored - return false if ignore_reqs.include?(requirement_class.new(">= 0")) + return false if ignore_requirements.include?(requirement_class.new(">= 0")) if dependency.version version_can_update?(requirements_to_unlock: requirements_to_unlock) @@ -47,9 +51,7 @@ def can_update?(requirements_to_unlock:) end def updated_dependencies(requirements_to_unlock:) - unless can_update?(requirements_to_unlock: requirements_to_unlock) - return [] - end + return [] unless can_update?(requirements_to_unlock: requirements_to_unlock) case requirements_to_unlock&.to_sym when :none then [updated_dependency_without_unlock] @@ -78,6 +80,12 @@ def latest_resolvable_version raise NotImplementedError end + # Lowest available security fix version not checking resolvability + # @return [Dependabot::::Version, #to_s] version class + def lowest_security_fix_version + raise NotImplementedError + end + def lowest_resolvable_security_fix_version raise NotImplementedError end @@ -86,6 +94,16 @@ def latest_resolvable_version_with_no_unlock raise NotImplementedError end + # Finds any dependencies in the lockfile that have a subdependency on the + # given dependency that do not satisfy the target_version. + # @return [Array String}] + # name [String] the blocking dependencies name + # version [String] the version of the blocking dependency + # requirement [String] the requirement on the target_dependency + def conflicting_dependencies + [] # return an empty array for ecosystems that don't support this yet + end + def latest_resolvable_previous_version(_updated_version) dependency.version end @@ -102,7 +120,7 @@ def requirement_class Utils.requirement_class_for_package_manager(dependency.package_manager) end - # For some langauges, the manifest file may be constructed such that + # For some languages, the manifest file may be constructed such that # Dependabot has no way to update it (e.g., if it fetches its versions # from a web API). This method is overridden in those cases. def requirements_unlocked_or_can_be? @@ -119,12 +137,19 @@ def vulnerable? # Can't (currently) detect whether git dependencies are vulnerable return false if existing_version_is_sha? - version = version_class.new(dependency.version) - security_advisories.any? { |a| a.vulnerable?(version) } + active_advisories.any? + end + + def ignore_requirements + ignored_versions.flat_map { |req| requirement_class.requirements_array(req) } end private + def active_advisories + security_advisories.select { |a| a.vulnerable?(current_version) } + end + def latest_version_resolvable_with_full_unlock? raise NotImplementedError end @@ -213,7 +238,7 @@ def numeric_version_up_to_date? # this case we treat the version as up-to-date so that it's ignored. return true if latest_version.to_s.match?(/^[0-9a-f]{40}$/) - latest_version <= version_class.new(dependency.version) + latest_version <= current_version end def numeric_version_can_update?(requirements_to_unlock:) @@ -222,7 +247,7 @@ def numeric_version_can_update?(requirements_to_unlock:) case requirements_to_unlock&.to_sym when :none new_version = latest_resolvable_version_with_no_unlock - new_version && new_version > version_class.new(dependency.version) + new_version && new_version > current_version when :own preferred_version_resolvable_with_unlock? when :all @@ -237,7 +262,7 @@ def preferred_version_resolvable_with_unlock? if existing_version_is_sha? return false if new_version.to_s.start_with?(dependency.version) - elsif new_version <= version_class.new(dependency.version) + elsif new_version <= current_version return false end @@ -253,6 +278,10 @@ def requirements_up_to_date? changed_requirements.none? end + def current_version + @current_version ||= dependency.numeric_version + end + def can_compare_requirements? version_from_requirements && latest_version && @@ -265,7 +294,7 @@ def changed_requirements def version_from_requirements @version_from_requirements ||= - dependency.requirements.map { |r| r.fetch(:requirement) }.compact. + dependency.requirements.filter_map { |r| r.fetch(:requirement) }. flat_map { |req_str| requirement_class.requirements_array(req_str) }. flat_map(&:requirements). reject { |req_array| req_array.first.start_with?("<") }. @@ -278,10 +307,6 @@ def requirements_can_update? changed_requirements.none? { |r| r[:requirement] == :unfixable } end - - def ignore_reqs - ignored_versions.map { |req| requirement_class.new(req.split(",")) } - end end end end diff --git a/common/lib/dependabot/update_checkers/version_filters.rb b/common/lib/dependabot/update_checkers/version_filters.rb new file mode 100644 index 00000000000..09a16bfbc18 --- /dev/null +++ b/common/lib/dependabot/update_checkers/version_filters.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Dependabot + module UpdateCheckers + module VersionFilters + def self.filter_vulnerable_versions(versions_array, security_advisories) + versions_array.reject do |v| + security_advisories.any? do |a| + if v.is_a?(Gem::Version) + a.vulnerable?(v) + else + a.vulnerable?(v.fetch(:version)) + end + end + end + end + end + end +end diff --git a/common/lib/dependabot/utils.rb b/common/lib/dependabot/utils.rb index fad0e2bf41c..b6581266afb 100644 --- a/common/lib/dependabot/utils.rb +++ b/common/lib/dependabot/utils.rb @@ -1,9 +1,14 @@ # frozen_string_literal: true +require "set" + # TODO: in due course, these "registries" should live in a wrapper gem, not # dependabot-core. module Dependabot module Utils + BUMP_TMP_FILE_PREFIX = "dependabot_" + BUMP_TMP_DIR_PATH = "tmp" + @version_classes = {} def self.version_class_for_package_manager(package_manager) @@ -29,5 +34,15 @@ def self.requirement_class_for_package_manager(package_manager) def self.register_requirement_class(package_manager, requirement_class) @requirement_classes[package_manager] = requirement_class end + + @cloning_package_managers = Set[] + + def self.always_clone_for_package_manager?(package_manager) + @cloning_package_managers.include?(package_manager) + end + + def self.register_always_clone(package_manager) + @cloning_package_managers << package_manager + end end end diff --git a/common/lib/dependabot/version.rb b/common/lib/dependabot/version.rb index 54777a43bf2..55b9ed64ee3 100644 --- a/common/lib/dependabot/version.rb +++ b/common/lib/dependabot/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Dependabot - VERSION = "0.118.8" + VERSION = "0.215.0" end diff --git a/common/script/ci-test b/common/script/ci-test new file mode 100755 index 00000000000..c29bd83bf2e --- /dev/null +++ b/common/script/ci-test @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +bundle install +bundle exec rubocop . +bundle exec rspec spec diff --git a/common/spec/dependabot/clients/azure_spec.rb b/common/spec/dependabot/clients/azure_spec.rb index 22bd444b762..414fba8b1e9 100644 --- a/common/spec/dependabot/clients/azure_spec.rb +++ b/common/spec/dependabot/clients/azure_spec.rb @@ -3,6 +3,23 @@ require "spec_helper" require "dependabot/clients/azure" +RSpec.shared_examples "#get using auth headers" do |credential| + before do + stub_request(:get, base_url). + with(headers: credential["headers"]). + to_return(status: 200, body: '{"result": "Success"}') + end + + it "Using #{credential['token_type']} token in credentials" do + client = described_class.for_source( + source: source, + credentials: credential["credentials"] + ) + response = JSON.parse(client.get(base_url).body) + expect(response["result"]).to eq("Success") + end +end + RSpec.describe Dependabot::Clients::Azure do let(:username) { "username" } let(:password) { "password" } @@ -49,6 +66,42 @@ expect { subject }.to raise_error(Dependabot::Clients::Azure::NotFound) end end + + context "when response is 403" do + before do + stub_request(:get, branch_url). + with(basic_auth: [username, password]). + to_return(status: 403) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::Forbidden) + end + end + + context "when response is 401" do + before do + stub_request(:get, branch_url). + with(basic_auth: [username, password]). + to_return(status: 401) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::Unauthorized) + end + end + + context "when response is 400" do + before do + stub_request(:get, branch_url). + with(basic_auth: [username, password]). + to_return(status: 400) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::NotFound) + end + end end describe "#create_commit" do @@ -64,49 +117,281 @@ let(:commit_url) { repo_url + "/pushes?api-version=5.0" } - before do - stub_request(:post, commit_url). - with(basic_auth: [username, password]). - to_return(status: 200) - end - - context "when author_details is nil" do - let(:author_details) { nil } - it "pushes commit without author property" do - create_commit - - expect(WebMock). - to( - have_requested(:post, "#{repo_url}/pushes?api-version=5.0"). - with do |req| - json_body = JSON.parse(req.body) - expect(json_body.fetch("commits").count).to eq(1) - expect(json_body.fetch("commits").first.keys). - to_not include("author") - end - ) + context "when response is 403" do + let(:author_details) do + { email: "support@dependabot.com", name: "dependabot" } + end + + before do + stub_request(:post, commit_url). + with(basic_auth: [username, password]). + to_return(status: 403) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::Forbidden) end end - context "when author_details contains name and email" do - let(:author_details) do - { email: "support@dependabot.com", name: "dependabot" } + context "when response is 200" do + before do + stub_request(:post, commit_url). + with(basic_auth: [username, password]). + to_return(status: 200) end - it "pushes commit with author property containing name and email" do - create_commit + context "when author_details is nil" do + let(:author_details) { nil } + it "pushes commit without author property" do + create_commit - expect(WebMock). - to( - have_requested(:post, "#{repo_url}/pushes?api-version=5.0"). - with do |req| - json_body = JSON.parse(req.body) - expect(json_body.fetch("commits").count).to eq(1) - expect(json_body.fetch("commits").first.fetch("author")). - to eq(author_details.transform_keys(&:to_s)) - end + expect(WebMock). + to( + have_requested(:post, "#{repo_url}/pushes?api-version=5.0"). + with do |req| + json_body = JSON.parse(req.body) + expect(json_body.fetch("commits").count).to eq(1) + expect(json_body.fetch("commits").first.keys). + to_not include("author") + end + ) + end + end + + context "when author_details contains name and email" do + let(:author_details) do + { email: "support@dependabot.com", name: "dependabot" } + end + + it "pushes commit with author property containing name and email" do + create_commit + + expect(WebMock). + to( + have_requested(:post, "#{repo_url}/pushes?api-version=5.0"). + with do |req| + json_body = JSON.parse(req.body) + expect(json_body.fetch("commits").count).to eq(1) + expect(json_body.fetch("commits").first.fetch("author")). + to eq(author_details.transform_keys(&:to_s)) + end + ) + end + end + end + end + + describe "#create_pull_request" do + subject do + client.create_pull_request("pr_name", "source_branch", "target_branch", + "", [], nil) + end + + let(:pull_request_url) { repo_url + "/pullrequests?api-version=5.0" } + + context "when response is 403 & tags creation is forbidden" do + before do + stub_request(:post, pull_request_url). + with(basic_auth: [username, password]). + to_return( + status: 403, + body: { message: "TF401289" }.to_json ) end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::TagsCreationForbidden) + end + end + + context "when response is 403" do + before do + stub_request(:post, pull_request_url). + with(basic_auth: [username, password]). + to_return(status: 403) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::Forbidden) + end + end + end + + describe "#pull_request" do + subject { client.pull_request(pull_request_id) } + + let(:pull_request_id) { "1" } + let(:pull_request_url) { base_url + "/_apis/git/pullrequests/#{pull_request_id}" } + + context "when response is 200" do + response_body = fixture("azure", "pull_request_details.json") + + before do + stub_request(:get, pull_request_url). + with(basic_auth: [username, password]). + to_return(status: 200, body: response_body) + end + + specify { expect { subject }.to_not raise_error } + + it { is_expected.to eq(JSON.parse(response_body)) } + end + + context "when response is 401" do + before do + stub_request(:get, pull_request_url). + with(basic_auth: [username, password]). + to_return(status: 401) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::Unauthorized) + end + end + + context "when response is 404" do + before do + stub_request(:get, pull_request_url). + with(basic_auth: [username, password]). + to_return(status: 404) + end + + it "raises a helpful error" do + expect { subject }.to raise_error(Dependabot::Clients::Azure::NotFound) + end + end + end + + describe "#update_ref" do + subject(:update_ref) do + client.update_ref( + branch, + old_commit_id, + new_commit_id + ) + end + + let(:old_commit_id) { "oldcommitsha" } + let(:new_commit_id) { "newcommitsha" } + let(:update_ref_url) { repo_url + "/refs?api-version=5.0" } + + it "sends update branch request with old and new commit id" do + stub_request(:post, update_ref_url). + with(basic_auth: [username, password]). + to_return(status: 200, body: fixture("azure", "update_ref.json")) + + update_ref + + expect(WebMock). + to( + have_requested(:post, update_ref_url). + with do |req| + json_body = JSON.parse(req.body) + expect(json_body.count).to eq(1) + ref_update_details = json_body.first + expect(ref_update_details.fetch("name")). + to eq("refs/heads/#{branch}") + expect(ref_update_details.fetch("oldObjectId")). + to eq(old_commit_id) + expect(ref_update_details.fetch("newObjectId")). + to eq(new_commit_id) + end + ) + end + end + + describe "#get" do + context "Using auth headers" do + token = ":test_token" + encoded_token = Base64.encode64(":test_token").delete("\n") + bearer_token = "test_token" + basic_non_encoded_token_data = + { + "token_type" => "basic non encoded", + "credentials" => [ + { + "type" => "git_source", + "host" => "dev.azure.com", + "token" => token + } + ], + "headers" => { "Authorization" => "Basic #{encoded_token}" } + } + basic_encoded_token_data = + { + "token_type" => "basic encoded", + "credentials" => [ + { + "type" => "git_source", + "host" => "dev.azure.com", + "token" => encoded_token.to_s + } + ], + "headers" => { "Authorization" => "Basic #{encoded_token}" } + } + bearer_token_data = + { + "token_type" => "bearer", + "credentials" => [ + { + "type" => "git_source", + "host" => "dev.azure.com", + "token" => bearer_token + } + ], + "headers" => { "Authorization" => "Bearer #{bearer_token}" } + } + + include_examples "#get using auth headers", basic_non_encoded_token_data + include_examples "#get using auth headers", basic_encoded_token_data + include_examples "#get using auth headers", bearer_token_data + end + + context "Retries" do + context "for GET" do + it "with failure count <= max_retries" do + # Request succeeds (200) on second attempt. + stub_request(:get, base_url). + with(basic_auth: [username, password]). + to_return({ status: 502 }, { status: 200 }) + + response = client.get(base_url) + expect(response.status).to eq(200) + end + + it "with failure count > max_retries raises error" do + # Request fails (503) multiple times and exceeds max_retry limit + stub_request(:get, base_url). + with(basic_auth: [username, password]). + to_return({ status: 503 }, { status: 503 }, { status: 503 }) + + expect { client.get(base_url) }.to raise_error(Dependabot::Clients::Azure::ServiceNotAvailable) + end + end + + context "for POST" do + before :each do + @request_body = "request body" + end + it "with failure count <= max_retries" do + # Request succeeds on thrid attempt + stub_request(:post, base_url). + with(basic_auth: [username, password], body: @request_body). + to_return({ status: 503 }, { status: 503 }, { status: 200 }) + + response = client.post(base_url, @request_body) + expect(response.status).to eq(200) + end + + it "with failure count > max_retries raises an error" do + stub_request(:post, base_url). + with(basic_auth: [username, password], body: @request_body). + to_return({ status: 503 }, { status: 503 }, { status: 503 }, { status: 503 }) + + expect { client.post(base_url, @request_body) }. + to raise_error(Dependabot::Clients::Azure::ServiceNotAvailable) + end + end end end end diff --git a/common/spec/dependabot/clients/bitbucket_spec.rb b/common/spec/dependabot/clients/bitbucket_spec.rb new file mode 100644 index 00000000000..eb661161299 --- /dev/null +++ b/common/spec/dependabot/clients/bitbucket_spec.rb @@ -0,0 +1,303 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/clients/bitbucket" + +RSpec.describe Dependabot::Clients::Bitbucket do + let(:current_user_url) { "https://api.bitbucket.org/2.0/user?fields=uuid" } + + before(:each) do + stub_request(:get, current_user_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "current_user.json")) + end + let(:access_token) { "access_token" } + let(:credentials) do + [{ + "type" => "git_source", + "host" => "bitbucket.org", + "username" => nil, + "token" => access_token + }] + end + let(:branch) { "master" } + let(:repo) { "test/repo" } + let(:base_url) { "https://bitbucket.org/test/repo" } + let(:api_base_url) { "https://api.bitbucket.org/2.0/repositories/" } + let(:source) { Dependabot::Source.from_url(base_url + "/src/master/") } + let(:client) do + described_class.for_source(source: source, credentials: credentials) + end + + describe "#default_reviewers" do + subject do + client.default_reviewers(repo) + end + + let(:default_reviewers_url) { api_base_url + repo + "/default-reviewers?pagelen=100&fields=values.uuid,next" } + + context "when no default reviewers are defined" do + before do + stub_request(:get, default_reviewers_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "default_reviewers_no_data.json")) + end + + specify { expect { subject }.to_not raise_error } + + it { is_expected.to eq([]) } + end + + context "when default reviewers are defined" do + before do + stub_request(:get, default_reviewers_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "default_reviewers_with_data.json")) + end + + specify { expect { subject }.to_not raise_error } + + it { is_expected.to eq([{ uuid: "{00000000-0000-0000-0000-000000000001}" }]) } + end + end + + describe "#create_pull_request" do + subject do + client.create_pull_request(repo, "pr_name", "source_branch", "target_branch", "pr_description", nil) + end + + let(:default_reviewers_url) { api_base_url + repo + "/default-reviewers?pagelen=100&fields=values.uuid,next" } + let(:pull_request_url) { api_base_url + repo + "/pullrequests" } + + context "create pull request successfully" do + before do + stub_request(:get, default_reviewers_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 201, body: fixture("bitbucket", "default_reviewers_no_data.json")) + + stub_request(:post, pull_request_url). + with( + body: "{\"title\":\"pr_name\",\"source\":{\"branch\":{\"name\":\"source_branch\"}}," \ + "\"destination\":{\"branch\":{\"name\":\"target_branch\"}},\"description\":\"pr_description\"," \ + "\"reviewers\":[],\"close_source_branch\":true}", + headers: { + "Authorization" => "Bearer #{access_token}", + "Content-Type" => "application/json" + } + ). + to_return(status: 201) + end + + specify { expect { subject }.to_not raise_error } + end + end + + describe "#remove_current_user_from_default_reviewer" do + subject do + client.current_user + end + specify { expect { subject }.to_not raise_error } + + it { is_expected.to eq("{11111111-6349-0000-aea6-111111111111}") } + end + + describe "#pull_requests" do + subject do + client.pull_requests(repo, "source_branch", "target_branch") + end + + let(:status_params) { "?status=OPEN&status=MERGED&status=DECLINED&status=SUPERSEDED" } + let(:default_pull_requests_url) { api_base_url + repo + "/pullrequests" + status_params } + + context "no pull requests found with matching source and target branch" do + before do + stub_request(:get, default_pull_requests_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "pull_requests_no_match.json")) + end + + specify { expect { subject }.to_not raise_error } + + it { is_expected.to eq([]) } + end + + context "pull request found with matching source and target branch" do + before do + stub_request(:get, default_pull_requests_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "pull_requests_with_match.json")) + end + + specify { expect { subject }.to_not raise_error } + + it { + is_expected.to eq([ + { + "author" => { + "display_name" => "Author" + }, + "description" => "Second pull request", + "destination" => { + "branch" => { + "name" => "target_branch" + } + }, + "id" => 27, + "source" => { + "branch" => { + "name" => "source_branch" + } + }, + "state" => "OPEN", + "title" => "Second pull request" + } + ]) + } + end + + context "only open pull requests with matching source and target branch" do + let(:pull_requests_url) { api_base_url + repo + "/pullrequests?status=OPEN" } + + before do + stub_request(:get, pull_requests_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "pull_requests_with_match.json")) + end + + subject do + client.pull_requests(repo, "source_branch", "target_branch", %w(OPEN)) + end + + specify { expect { subject }.to_not raise_error } + + it { + is_expected.to eq([ + { + "author" => { + "display_name" => "Author" + }, + "description" => "Second pull request", + "destination" => { + "branch" => { + "name" => "target_branch" + } + }, + "id" => 27, + "source" => { + "branch" => { + "name" => "source_branch" + } + }, + "state" => "OPEN", + "title" => "Second pull request" + } + ]) + } + end + + context "open pull requests where matching target branch" do + let(:pull_requests_url) { api_base_url + repo + "/pullrequests?status=OPEN" } + + before do + stub_request(:get, pull_requests_url). + with(headers: { "Authorization" => "Bearer #{access_token}" }). + to_return(status: 200, body: fixture("bitbucket", "pull_requests_no_match.json")) + end + + subject do + client.pull_requests(repo, nil, "target_branch", %w(OPEN)) + end + + specify { expect { subject }.to_not raise_error } + + it { + is_expected.to eq([ + { + "author" => { + "display_name" => "Pull request Author" + }, + "created_on" => "2021-05-17T14:52:37.237653+00:00", + "description" => "Pull request description", + "destination" => { + "branch" => { + "name" => "target_branch" + } + }, + "id" => 7, + "source" => { + "branch" => { + "name" => "branch_1" + } + }, + "state" => "OPEN", + "title" => "Pull request title", + "updated_on" => "2021-05-17T14:52:37.237653+00:00" + } + ]) + } + end + end + + describe "#decline pull request" do + let(:default_decline_url) { api_base_url + repo + "/pullrequests/15/decline" } + let(:default_comment_url) { api_base_url + repo + "/pullrequests/15/comments" } + + context "with provided comment" do + before do + stub_request(:post, default_decline_url). + with( + headers: { + "Authorization" => "Bearer #{access_token}", + "Accept" => "application/json" + } + ). + to_return(status: 200) + + stub_request(:post, default_comment_url). + with( + body: "{\"content\":{\"raw\":\"Superseded by newer version\"}}", + headers: { + "Authorization" => "Bearer #{access_token}", + "Content-type" => "application/json" + } + ). + to_return(status: 201) + end + + subject do + client.decline_pull_request(repo, 15, "Superseded by newer version") + end + + specify { expect { subject }.to_not raise_error } + end + + context "without provided comment" do + before do + stub_request(:post, default_decline_url). + with( + headers: { + "Authorization" => "Bearer #{access_token}", + "Accept" => "application/json" + } + ). + to_return(status: 200) + + stub_request(:post, default_comment_url). + with( + body: "{\"content\":{\"raw\":\"Dependabot declined the pull request.\"}}", + headers: { + "Authorization" => "Bearer #{access_token}", + "Content-type" => "application/json" + } + ). + to_return(status: 201) + end + + subject do + client.decline_pull_request(repo, 15) + end + + specify { expect { subject }.to_not raise_error } + end + end +end diff --git a/common/spec/dependabot/clients/github_with_retries_spec.rb b/common/spec/dependabot/clients/github_with_retries_spec.rb index 363db7b3613..2931cb95ee4 100644 --- a/common/spec/dependabot/clients/github_with_retries_spec.rb +++ b/common/spec/dependabot/clients/github_with_retries_spec.rb @@ -50,4 +50,40 @@ its(:name) { is_expected.to eq("Gemfile") } end end + + describe ".open_timeout_in_seconds" do + context "when DEPENDABOT_OPEN_TIMEOUT_IN_SECONDS is set" do + it "returns the provided value" do + override_value = 10 + stub_const("ENV", ENV.to_hash.merge("DEPENDABOT_OPEN_TIMEOUT_IN_SECONDS" => override_value)) + + expect(described_class.open_timeout_in_seconds).to eq(override_value) + end + end + + context "when ENV does not provide an override" do + it "falls back to a default value" do + expect(described_class.open_timeout_in_seconds). + to eq(described_class::DEFAULT_OPEN_TIMEOUT_IN_SECONDS) + end + end + end + + describe ".read_timeout_in_seconds" do + context "when DEPENDABOT_READ_TIMEOUT_IN_SECONDS is set" do + it "returns the provided value" do + override_value = 10 + stub_const("ENV", ENV.to_hash.merge("DEPENDABOT_READ_TIMEOUT_IN_SECONDS" => override_value)) + + expect(described_class.read_timeout_in_seconds).to eq(override_value) + end + end + + context "when ENV does not provide an override" do + it "falls back to a default value" do + expect(described_class.read_timeout_in_seconds). + to eq(described_class::DEFAULT_READ_TIMEOUT_IN_SECONDS) + end + end + end end diff --git a/common/spec/dependabot/config/file_fetcher_spec.rb b/common/spec/dependabot/config/file_fetcher_spec.rb new file mode 100644 index 00000000000..6b95ac263b5 --- /dev/null +++ b/common/spec/dependabot/config/file_fetcher_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require "dependabot/source" +require "dependabot/config/file_fetcher" +require "spec_helper" + +RSpec.describe Dependabot::Config::FileFetcher do + let(:repo) { "gocardless/bump" } + let(:source) do + Dependabot::Source.new( + provider: "github", + repo: repo, + directory: "/", + branch: "main", + commit: "sha" + ) + end + let(:credentials) do + [{ + "type" => "git_source", + "host" => "github.com", + "region" => "us-east-1", + "username" => "x-access-token", + "password" => "token" + }] + end + let(:file_fetcher_instance) do + described_class.new( + source: source, + credentials: credentials, + repo_contents_path: nil + ) + end + + describe "#config_file" do + subject(:config_file) { file_fetcher_instance.config_file } + let(:url) { "https://api.github.com/repos/#{repo}/contents/" } + before do + allow(file_fetcher_instance).to receive(:commit).and_return("sha") + stub_request(:get, url + ".github/dependabot.yml?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404) + end + + context "with config file" do + before do + stub_request(:get, url + ".github/dependabot.yaml?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 200, + body: fixture("github", "configfile_content.json"), + headers: { "content-type" => "application/json" }) + end + + it "fetches config file" do + expect(config_file).to be_a(Dependabot::DependencyFile) + end + end + + context "without config file" do + before do + stub_request(:get, url + ".github/dependabot.yaml?ref=sha"). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404) + end + + it "raises DependencyFileNotFound" do + expect { config_file }.to raise_error(Dependabot::DependencyFileNotFound) + end + end + end +end diff --git a/common/spec/dependabot/config/file_spec.rb b/common/spec/dependabot/config/file_spec.rb new file mode 100644 index 00000000000..f64f55fc8cd --- /dev/null +++ b/common/spec/dependabot/config/file_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/config" +require "dependabot/config/file" +require "dependabot/config/update_config" + +RSpec.describe Dependabot::Config::File do + describe "#parse" do + it "parses the config file" do + cfg = Dependabot::Config::File.parse(fixture("configfile", "bundler-daily.yml")) + expect(cfg.updates.size).to eq(1) + end + + it "rejects version:1 config file" do + expect { Dependabot::Config::File.parse("version: 1\n") }. + to raise_error(Dependabot::Config::InvalidConfigError) + end + end + + describe "File" do + let(:config) { Dependabot::Config::File.parse(fixture("configfile", "npm-weekly.yml")) } + + describe "#update_config" do + it "maps package_manager to package-ecosystem" do + update_config = config.update_config("npm_and_yarn") + expect(update_config).to be_a(Dependabot::Config::UpdateConfig) + expect(update_config.commit_message_options.prefix).to eq("no directory") + end + + it "matches directory" do + update_config = config.update_config("npm_and_yarn", directory: "/target") + expect(update_config).to be_a(Dependabot::Config::UpdateConfig) + expect(update_config.commit_message_options.prefix).to eq("with directory") + end + + it "matches target-branch" do + update_config = config.update_config("npm_and_yarn", directory: "/target", target_branch: "the-awesome-branch") + expect(update_config).to be_a(Dependabot::Config::UpdateConfig) + expect(update_config.commit_message_options.prefix).to eq("with directory and branch") + end + + it "returns empty when not found" do + update_config = config.update_config("bundler") + expect(update_config).to be_a(Dependabot::Config::UpdateConfig) + expect(update_config.commit_message_options.prefix).to be_nil + end + end + + describe "#parse" do + let(:config) { Dependabot::Config::File.parse(fixture("configfile", "ignore-conditions.yml")) } + let(:update_config) { config.update_config("npm_and_yarn") } + + it "loads ignore conditions" do + expect(update_config.ignore_conditions.length).to eq(3) + end + + it "passes update-types" do + types_ignore = update_config.ignore_conditions.find { |ic| ic.dependency_name == "@types/node" } + expect(types_ignore.update_types).to eq(["version-update:semver-patch"]) + end + end + end +end diff --git a/common/spec/dependabot/config/ignore_condition_spec.rb b/common/spec/dependabot/config/ignore_condition_spec.rb new file mode 100644 index 00000000000..7667d7d691b --- /dev/null +++ b/common/spec/dependabot/config/ignore_condition_spec.rb @@ -0,0 +1,319 @@ +# frozen_string_literal: true + +require "dependabot/config/ignore_condition" +require "dependabot/dependency" +require "spec_helper" + +RSpec.describe Dependabot::Config::IgnoreCondition do + let(:dependency_name) { "test" } + let(:dependency_version) { "1.2.3" } + let(:ignore_condition) { described_class.new(dependency_name: dependency_name) } + let(:security_updates_only) { false } + + describe "#ignored_versions" do + subject(:ignored_versions) { ignore_condition.ignored_versions(dependency, security_updates_only) } + let(:dependency) do + Dependabot::Dependency.new( + name: dependency_name, + requirements: [], + package_manager: "npm_and_yarn", + version: dependency_version + ) + end + + # Test helpers for reasoning about specific semver versions: + def expect_allowed(versions) + reqs = ignored_versions.map { |v| Gem::Requirement.new(v.split(",").map(&:strip)) } + versions.each do |v| + version = Gem::Version.new(v) + ignored = reqs.any? { |req| req.satisfied_by?(version) } + expect(ignored).to eq(false), "Expected #{v} to be allowed, but was ignored" + end + end + + def expect_ignored(versions) + reqs = ignored_versions.map { |v| Gem::Requirement.new(v.split(",").map(&:strip)) } + versions.each do |v| + version = Gem::Version.new(v) + ignored = reqs.any? { |req| req.satisfied_by?(version) } + expect(ignored).to eq(true), "Expected #{v} to be ignored, but was allowed" + end + end + + context "without versions or update_types" do + let(:ignore_condition) { described_class.new(dependency_name: dependency_name) } + + it "ignores all versions" do + expect(ignored_versions).to eq([">= 0"]) + end + end + + context "with versions" do + let(:ignore_condition) { described_class.new(dependency_name: dependency_name, versions: [">= 2.0.0"]) } + + it "returns the static versions" do + expect(ignored_versions).to eq([">= 2.0.0"]) + end + + it "ignores expected versions" do + expect_allowed(["1.0.0", "1.1.0", "1.1.1"]) + expect_ignored(["2.0", "2.0.0"]) + end + + context "with security_updates_only" do + let(:security_updates_only) { true } + + it "returns the static versions" do + expect(ignored_versions).to eq([">= 2.0.0"]) + end + end + end + + context "with update_types" do + let(:ignore_condition) { described_class.new(dependency_name: dependency_name, update_types: update_types) } + let(:dependency_version) { "1.2.3" } + let(:patch_upgrades) { %w(1.2.4 1.2.5 1.2.4-rc0) } + let(:minor_upgrades) { %w(1.3 1.3.0 1.4 1.4.0) } + let(:major_upgrades) { %w(2 2.0 2.0.0 3 3.0 3.0.0) } + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + + it "ignores expected versions" do + expect_allowed(minor_upgrades + major_upgrades) + expect_ignored(patch_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq(["> 1.2.3, < 1.3"]) + end + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + major_upgrades) + expect_ignored(minor_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 1.3.a, < 2"]) + end + end + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + minor_upgrades) + expect_ignored(major_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 2.a"]) + end + end + + context "with ignore_major_versions and ignore_patch_versions" do + let(:update_types) { %w(version-update:semver-major version-update:semver-patch) } + + it "ignores expected versions" do + expect_allowed(minor_upgrades) + expect_ignored(patch_upgrades + major_upgrades) + expect_allowed([dependency_version]) + end + end + + context "with a 'major.minor' semver dependency" do + let(:dependency_version) { "1.2" } + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + minor_upgrades) + expect_ignored(major_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 2.a"]) + end + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + major_upgrades) + expect_ignored(minor_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 1.3.a, < 2"]) + end + end + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + + it "ignores expected versions" do + expect_allowed(major_upgrades + minor_upgrades) + expect_ignored(patch_upgrades + ["1.2.1"]) + expect_allowed([dependency_version, "1.2.0"]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq(["> 1.2, < 1.3"]) + end + end + end + + context "with a 'major' semver dependency" do + let(:dependency_version) { "1" } + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + minor_upgrades) + expect_ignored(major_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 2.a"]) + end + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 1.1.a, < 2"]) + end + end + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + let(:patch_upgrades) { %w(1.0.2 1.0.5 1.0.4-rc0) } + let(:minor_upgrades) { %w(1.1 1.2.0 1.3 1.4.0) } + + it "ignores expected versions" do + expect_allowed(major_upgrades + minor_upgrades) + expect_ignored(patch_upgrades) + expect_allowed([dependency_version, "1.0.0"]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq(["> 1, < 1.1"]) + end + end + end + + context "with a pre-release semver version" do + let(:dependency_version) { "1.2.3-alpha.1" } + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + minor_upgrades) + expect_ignored(major_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 2.a"]) + end + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + + it "ignores expected versions" do + expect_allowed(patch_upgrades + major_upgrades) + expect_ignored(minor_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq([">= 1.3.a, < 2"]) + end + end + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + + it "ignores expected updates" do + expect_ignored(patch_upgrades + ["1.2.3-alpha.2", "1.2.3-alpha.1.1", "1.2.3-beta"]) + expect_allowed(minor_upgrades + major_upgrades) + expect_allowed([dependency_version]) + end + + it "returns the expected range" do + expect(ignored_versions).to eq(["> 1.2.3-alpha.1, < 1.3"]) + end + end + end + + context "with a non-semver dependency" do + let(:dependency_version) { "Finchley.SR3" } + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + it "returns the expected range" do + expect(ignored_versions).to eq([]) + end + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + it "returns the expected range" do + expect(ignored_versions).to eq([]) + end + end + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + it "returns the expected range" do + expect(ignored_versions).to eq([]) + end + end + end + + context "when the dependency version isn't known" do + let(:dependency_version) { nil } + + context "with ignore_major_versions" do + let(:update_types) { ["version-update:semver-major"] } + it { is_expected.to eq([]) } + end + + context "with ignore_minor_versions" do + let(:update_types) { ["version-update:semver-minor"] } + it { is_expected.to eq([]) } + end + + context "with ignore_patch_versions" do + let(:update_types) { ["version-update:semver-patch"] } + it { is_expected.to eq([]) } + end + end + + context "with security_updates_only" do + let(:security_updates_only) { true } + let(:update_types) { %w(version-update:semver-major version-update:semver-patch) } + + it "allows all " do + expect_allowed(patch_upgrades + minor_upgrades + major_upgrades) + end + end + end + end +end diff --git a/common/spec/dependabot/config/update_config_spec.rb b/common/spec/dependabot/config/update_config_spec.rb new file mode 100644 index 00000000000..f6495d90d46 --- /dev/null +++ b/common/spec/dependabot/config/update_config_spec.rb @@ -0,0 +1,310 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/config" +require "dependabot/config/file" +require "dependabot/config/update_config" + +RSpec.describe Dependabot::Config::UpdateConfig do + describe "#ignored_versions_for" do + subject(:ignored_versions) { config.ignored_versions_for(dependency, security_updates_only: security_updates_only) } + let(:dependency) do + Dependabot::Dependency.new( + name: "@types/node", + requirements: [], + version: "12.12.6", + package_manager: "npm_and_yarn" + ) + end + let(:ignore_conditions) { [] } + let(:config) { described_class.new(ignore_conditions: ignore_conditions) } + let(:security_updates_only) { false } + + it "returns empty when not defined" do + expect(ignored_versions).to eq([]) + end + + context "with ignored versions" do + let(:ignore_conditions) do + [Dependabot::Config::IgnoreCondition.new(dependency_name: "@types/node", + versions: [">= 14.14.x, < 15"])] + end + + it "returns versions" do + expect(ignored_versions).to eq([">= 14.14.x, < 15"]) + end + end + + context "with a wildcard dependency name" do + let(:ignore_conditions) do + [ + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/*", + versions: [">= 14.14.x, < 15"] + ), + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/node", + versions: [">= 15, < 16"] + ), + Dependabot::Config::IgnoreCondition.new( + dependency_name: "eslint", + versions: [">= 2.9.0, < 3"] + ) + ] + end + + it "returns matched versions" do + expect(ignored_versions).to eq([">= 14.14.x, < 15", ">= 15, < 16"]) + end + end + + context "with update_types and versions" do + let(:ignore_conditions) do + [Dependabot::Config::IgnoreCondition.new(dependency_name: "@types/node", + versions: [">= 14.14.x, < 15"], + update_types: ["version-update:semver-minor"])] + end + + it "returns versions" do + expect(ignored_versions).to eq([">= 12.13.a, < 13", ">= 14.14.x, < 15"]) + end + end + + context "with duplicate update_types" do + let(:ignore_conditions) do + [ + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/node", + update_types: ["version-update:semver-minor"] + ), + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/node", + update_types: ["version-update:semver-minor"] + ) + ] + end + + it "returns versions" do + expect(ignored_versions).to eq([">= 12.13.a, < 13"]) + end + end + + context "with multiple update_types" do + let(:ignore_conditions) do + [ + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/*", + update_types: ["version-update:semver-major"] + ), + Dependabot::Config::IgnoreCondition.new( + dependency_name: "@types/node", + update_types: ["version-update:semver-minor"] + ) + ] + end + + it "returns versions" do + expect(ignored_versions).to eq([">= 13.a", ">= 12.13.a, < 13"]) + end + + context "with security_updates_only" do + let(:security_updates_only) { true } + it "does not expand versions" do + expect(ignored_versions).to eq([]) + end + end + end + + context "with an dependency that must be name normalized" do + let(:dependency) do + Dependabot::Dependency.new( + name: "VERY_COOL_PACKAGE", + requirements: [], + version: "1.2.3", + package_manager: "fake-package-manager" + ) + end + before do + Dependabot::Dependency.register_name_normaliser("fake-package-manager", lambda { |name| + name.downcase.gsub(/[_=]/, "-") + }) + end + + let(:ignore_conditions) do + [Dependabot::Config::IgnoreCondition.new(dependency_name: "very-cool-package", versions: [">= 0"])] + end + + it "normalizes the dependency name to match" do + expect(ignored_versions).to eq([">= 0"]) + end + + context "and ignore condition that must be normalized" do + let(:ignore_conditions) do + [Dependabot::Config::IgnoreCondition.new(dependency_name: "very=cool=package", versions: [">= 1"])] + end + + it "normalizes the condition dependency_name to match" do + expect(ignored_versions).to eq([">= 1"]) + end + end + end + + context "when the dependency version isn't known" do + let(:dependency) do + Dependabot::Dependency.new( + name: "actions/checkout", + requirements: [], + version: nil, + package_manager: "github_actions" + ) + end + + let(:ignore_conditions) do + [Dependabot::Config::IgnoreCondition.new(dependency_name: "actions/checkout", + versions: [], update_types: ["version-update:semver-major"])] + end + + it "returns no ignored versions" do + expect(ignored_versions).to eq([]) + end + end + end + + describe "#commit_message_options" do + let(:config) { Dependabot::Config::File.parse(fixture("configfile", "commit-message-options.yml")) } + + it "parses prefix" do + expect(config.update_config("npm_and_yarn").commit_message_options.prefix).to eq("npm") + end + + it "parses prefix-development" do + expect(config.update_config("pip").commit_message_options.prefix_development).to eq("pip dev") + end + + it "includes scope" do + expect(config.update_config("composer").commit_message_options.include_scope?).to eq(true) + end + + it "does not include scope" do + expect(config.update_config("npm_and_yarn").commit_message_options.include_scope?).to eq(false) + end + end + + describe ".wildcard_match?" do + def wildcard_match?(wildcard_string, candidate_string) + described_class.wildcard_match?(wildcard_string, candidate_string) + end + + context "without a wildcard" do + it "with a matching string" do + expect(wildcard_match?("bus", "bus")).to eq(true) + end + + it "with different capitalisation" do + expect(wildcard_match?("bus", "Bus")).to eq(true) + end + + it "with a superstring" do + expect(wildcard_match?("bus", "Business")).to eq(false) + end + + it "with a substring" do + expect(wildcard_match?("bus", "bu")).to eq(false) + end + + it "with a string that ends in the same way" do + expect(wildcard_match?("bus", "blunderbus")).to eq(false) + end + + it "with a regex character and matching string" do + expect(wildcard_match?("bus.", "bus.")).to eq(true) + end + + it "with a regex character and superstring" do + expect(wildcard_match?("bus.", "bus.iness")).to eq(false) + end + end + + context "with a wildcard" do + it "at the start with a matching string" do + expect(wildcard_match?("*bus", "*bus")).to eq(true) + end + + it "at the start with a matching string (except the wildcard)" do + expect(wildcard_match?("*bus", "bus")).to eq(true) + end + + it "at the start with a string that ends in the same way" do + expect(wildcard_match?("*bus", "blunderbus")).to eq(true) + end + + it "at the start with a superstring" do + expect(wildcard_match?("*bus", "*business")).to eq(false) + end + + it "at the start with a substring" do + expect(wildcard_match?("*bus", "bu")).to eq(false) + end + + it "at the end with a matching string" do + expect(wildcard_match?("bus*", "bus*")).to eq(true) + end + + it "at the end with a matching string (except the wildcard)" do + expect(wildcard_match?("bus*", "bus")).to eq(true) + end + + it "at the end with a string that ends in the same way" do + expect(wildcard_match?("bus*", "blunderbus")).to eq(false) + end + + it "at the end with a superstring" do + expect(wildcard_match?("bus*", "bus*iness")).to eq(true) + end + + it "at the end with a substring" do + expect(wildcard_match?("bus*", "bu")).to eq(false) + end + + it "in the middle with a matching string" do + expect(wildcard_match?("bu*s", "bu*s")).to eq(true) + end + + it "in the middle with a matching string (except the wildcard)" do + expect(wildcard_match?("bu*s", "bus")).to eq(true) + end + + it "in the middle with a string that ends in the same way" do + expect(wildcard_match?("bu*s", "blunderbus")).to eq(false) + end + + it "in the middle with a superstring" do + expect(wildcard_match?("bu*s", "bu*sy")).to eq(false) + end + + it "in the middle with a substring" do + expect(wildcard_match?("bu*s", "bu")).to eq(false) + end + + it "in the middle with a string that starts and ends in the right way" do + expect(wildcard_match?("bu*s", "business")).to eq(true) + end + + it "as the only character with a matching string" do + expect(wildcard_match?("*", "*")).to eq(true) + end + + it "as the only character with any string" do + expect(wildcard_match?("*", "bus")).to eq(true) + end + + it "with multiple wildcards and a string that fits" do + expect(wildcard_match?("bu*in*ss", "business")).to eq(true) + end + + it "with multiple wildcards and a string that doesn't" do + expect(wildcard_match?("bu*in*ss", "buspass")).to eq(false) + end + end + end +end diff --git a/common/spec/dependabot/dependency_file_spec.rb b/common/spec/dependabot/dependency_file_spec.rb index 7f5e22075ce..d1341b504db 100644 --- a/common/spec/dependabot/dependency_file_spec.rb +++ b/common/spec/dependabot/dependency_file_spec.rb @@ -76,9 +76,19 @@ "content" => "a", "directory" => "/", "type" => "file", - "support_file" => false + +"mode" => "100644", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => false, + "operation" => Dependabot::DependencyFile::Operation::UPDATE ) end + + it "has the correct operation properties" do + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::UPDATE + end end context "with a symlink" do @@ -96,11 +106,172 @@ "name" => "Gemfile", "content" => "a", "directory" => "/", + "mode" => nil, "type" => "symlink", "support_file" => false, - "symlink_target" => "nested/Gemfile" + "symlink_target" => "nested/Gemfile", + "content_encoding" => "utf-8", + "deleted" => false, + "operation" => Dependabot::DependencyFile::Operation::UPDATE + ) + end + + it "has the correct operation properties" do + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::UPDATE + end + end + + context "with a new file" do + let(:file) do + described_class.new( + name: "Gemfile", + content: "a", + operation: Dependabot::DependencyFile::Operation::CREATE + ) + end + + it "returns the correct array" do + expect(subject).to eq( + "name" => "Gemfile", + "content" => "a", + "directory" => "/", + "mode" => "100644", + "type" => "file", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => false, + "operation" => Dependabot::DependencyFile::Operation::CREATE + ) + end + + it "has the correct operation properties" do + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::CREATE + end + end + + context "with a changed file" do + let(:file) do + described_class.new( + name: "Gemfile", + content: "a", + operation: Dependabot::DependencyFile::Operation::UPDATE + ) + end + + it "returns the correct array" do + expect(subject).to eq( + "name" => "Gemfile", + "content" => "a", + "directory" => "/", + "mode" => "100644", + "type" => "file", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => false, + "operation" => Dependabot::DependencyFile::Operation::UPDATE + ) + end + + it "has the correct operation properties" do + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::UPDATE + end + end + + context "with a deleted file" do + let(:file) do + described_class.new( + name: "Gemfile", + content: "a", + operation: Dependabot::DependencyFile::Operation::DELETE + ) + end + + it "returns the correct array" do + expect(subject).to eq( + "name" => "Gemfile", + "content" => "a", + "directory" => "/", + "mode" => "100644", + "type" => "file", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => true, + "operation" => Dependabot::DependencyFile::Operation::DELETE + ) + end + + it "has the correct operation properties" do + expect(file.deleted).to be_truthy + expect(file.deleted?).to be_truthy + expect(file.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end + end + + context "with a deleted file using the legacy initializer method" do + let(:file) do + described_class.new( + name: "Gemfile", + content: "a", + deleted: true + ) + end + + it "returns the correct array" do + expect(subject).to eq( + "name" => "Gemfile", + "content" => "a", + "directory" => "/", + "mode" => "100644", + "type" => "file", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => true, + "operation" => Dependabot::DependencyFile::Operation::DELETE + ) + end + + it "has the correct operation properties" do + expect(file.deleted).to be_truthy + expect(file.deleted?).to be_truthy + expect(file.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end + end + + context "with a deleted file using the legacy setter method" do + let(:file) do + file = described_class.new( + name: "Gemfile", + content: "a" + ) + file.deleted = true + file + end + + it "returns the correct array" do + expect(subject).to eq( + "name" => "Gemfile", + "content" => "a", + "directory" => "/", + "mode" => "100644", + "type" => "file", + "support_file" => false, + "content_encoding" => "utf-8", + "deleted" => true, + "operation" => Dependabot::DependencyFile::Operation::DELETE ) end + + it "has the correct operation properties" do + expect(file.deleted).to be_truthy + expect(file.deleted?).to be_truthy + expect(file.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end end end @@ -128,4 +299,33 @@ specify { expect(file1).to_not eq(file2) } end end + + describe "#decoded_content" do + context "for base64 encoded content" do + let(:file) do + described_class.new( + name: "example.gem", + content_encoding: described_class::ContentEncoding::BASE64, + content: "YWJj\n" + ) + end + + it "decodes the content to its original encoding" do + expect(file.decoded_content).to eq("abc") + end + end + + context "for utf-8 encoded content" do + let(:file) do + described_class.new( + name: "example.gem", + content: "abc" + ) + end + + it "returns the unencoded content" do + expect(file.decoded_content).to eq("abc") + end + end + end end diff --git a/common/spec/dependabot/dependency_spec.rb b/common/spec/dependabot/dependency_spec.rb index fc4977393c3..45a17786241 100644 --- a/common/spec/dependabot/dependency_spec.rb +++ b/common/spec/dependabot/dependency_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Dependabot::Dependency do describe ".new" do - subject(:dependency) { described_class.new(args) } + subject(:dependency) { described_class.new(**args) } let(:args) do { @@ -90,22 +90,22 @@ end context "when two dependencies are equal" do - let(:dependency1) { described_class.new(args) } - let(:dependency2) { described_class.new(args) } + let(:dependency1) { described_class.new(**args) } + let(:dependency2) { described_class.new(**args) } specify { expect(dependency1).to eq(dependency2) } end context "when two dependencies are not equal" do - let(:dependency1) { described_class.new(args) } - let(:dependency2) { described_class.new(args.merge(name: "dep2")) } + let(:dependency1) { described_class.new(**args) } + let(:dependency2) { described_class.new(**args.merge(name: "dep2")) } specify { expect(dependency1).to_not eq(dependency2) } end end describe "#production?" do - subject(:production?) { described_class.new(dependency_args).production? } + subject(:production?) { described_class.new(**dependency_args).production? } let(:dependency_args) do { @@ -141,7 +141,7 @@ end describe "#display_name" do - subject(:display_name) { described_class.new(dependency_args).display_name } + subject(:display_name) { described_class.new(**dependency_args).display_name } let(:dependency_args) do { @@ -155,7 +155,7 @@ end describe "#to_h" do - subject(:to_h) { described_class.new(dependency_args).to_h } + subject(:to_h) { described_class.new(**dependency_args).to_h } context "with requirements" do let(:dependency_args) do @@ -217,11 +217,32 @@ is_expected.to eq(expected) end end + + context "when removed" do + let(:dependency_args) do + { + name: "dep", + requirements: [], + package_manager: "dummy", + removed: true + } + end + + it do + expected = { + "name" => "dep", + "package_manager" => "dummy", + "requirements" => [], + "removed" => true + } + is_expected.to eq(expected) + end + end end describe "#subdependency_metadata" do subject(:subdependency_metadata) do - described_class.new(dependency_args).subdependency_metadata + described_class.new(**dependency_args).subdependency_metadata end let(:dependency_args) do @@ -249,4 +270,104 @@ it { is_expected.to eq(nil) } end end + + describe "#metadata" do + it "stores metadata given to initialize" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + metadata: { foo: 42 } + ) + expect(dependency.metadata).to eq(foo: 42) + end + + it "is mutable" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + metadata: { foo: 42 } + ) + + dependency.metadata[:all_versions] = [] + expect(dependency.metadata).to eq(foo: 42, all_versions: []) + end + + it "is not serialized" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + metadata: { foo: 42 } + ) + expect(dependency.to_h.keys).not_to include("metadata") + end + + it "isn't utilized by the equality operator" do + dependency1 = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + metadata: { foo: 42 } + ) + dependency2 = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + metadata: { foo: 43 } + ) + expect(dependency1).to eq(dependency2) + end + end + + describe "#all_versions" do + it "returns an empty array by default" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy" + ) + + expect(dependency.all_versions).to eq([]) + end + + it "returns the dependency version if all_version metadata isn't present" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + version: "1.0.0" + ) + + expect(dependency.all_versions).to eq(["1.0.0"]) + end + + it "returns all_version metadata if present" do + dependency = described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + version: "1.0.0", + metadata: { + all_versions: [ + described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + version: "1.0.0" + ), + described_class.new( + name: "dep", + requirements: [], + package_manager: "dummy", + version: "2.0.0" + ) + ] + } + ) + + expect(dependency.all_versions).to eq(["1.0.0", "2.0.0"]) + end + end end diff --git a/common/spec/dependabot/errors_spec.rb b/common/spec/dependabot/errors_spec.rb index 28a4e8bc4c4..4eef71abf92 100644 --- a/common/spec/dependabot/errors_spec.rb +++ b/common/spec/dependabot/errors_spec.rb @@ -3,6 +3,73 @@ require "spec_helper" require "dependabot/errors" +RSpec.describe Dependabot::DependabotError do + let(:error) { described_class.new(message) } + let(:message) do + "some error" + end + + describe "#message" do + subject { error.message } + + it { is_expected.to eq("some error") } + + context "with dependabot temp path" do + let(:message) do + "tmp/dependabot_20201218-14100-y0d218/path error" + end + + it { is_expected.to eq("dependabot_tmp_dir/path error") } + end + + context "with dependabot temp path" do + let(:message) do + "Error (/Users/x/code/dependabot-core/cargo/tmp/dependabot_20201218-14100-y0d218) " \ + "failed to load https://github.com/dependabot" + end + + it do + is_expected.to eq( + "Error (/Users/x/code/dependabot-core/cargo/dependabot_tmp_dir) " \ + "failed to load https://github.com/dependabot" + ) + end + end + + context "without http basic auth token" do + let(:message) do + "git://user@github.com error" + end + + it { is_expected.to eq("git://user@github.com error") } + end + + context "with http basic auth missing username" do + let(:message) do + "git://:token@github.com error" + end + + it { is_expected.to eq("git://github.com error") } + end + + context "with http basic auth" do + let(:message) do + "git://user:token@github.com error" + end + + it { is_expected.to eq("git://github.com error") } + end + + context "with escaped basic auth uri" do + let(:message) do + "git://user:token%40github.com error" + end + + it { is_expected.to eq("git://github.com error") } + end + end +end + RSpec.describe Dependabot::DependencyFileNotFound do let(:error) { described_class.new(file_path) } let(:file_path) { "path/to/Gemfile" } @@ -32,3 +99,104 @@ end end end + +RSpec.describe Dependabot::PrivateSourceAuthenticationFailure do + let(:error) { described_class.new(source) } + let(:source) { "source" } + + describe "#message" do + subject { error.message } + + it do + is_expected.to eq( + "The following source could not be reached as it requires authentication (and any provided details were " \ + "invalid or lacked the required permissions): source" + ) + end + + context "when source includes something that looks like a path" do + let(:source) do + "npm.fury.io/token123/path" + end + + it do + is_expected.to eq( + "The following source could not be reached as it requires authentication (and any provided details were " \ + "invalid or lacked the required permissions): npm.fury.io/" + ) + end + end + end +end + +RSpec.describe Dependabot::PrivateSourceTimedOut do + let(:error) { described_class.new(source) } + let(:source) { "source" } + + describe "#message" do + subject { error.message } + + it do + is_expected.to eq( + "The following source timed out: source" + ) + end + + context "when source includes something that looks like a path" do + let(:source) do + "npm.fury.io/token123/path" + end + + it do + is_expected.to eq( + "The following source timed out: npm.fury.io/" + ) + end + end + end +end + +RSpec.describe Dependabot::PrivateSourceCertificateFailure do + let(:error) { described_class.new(source) } + let(:source) { "source" } + + describe "#message" do + subject { error.message } + + it do + is_expected.to eq( + "Could not verify the SSL certificate for source" + ) + end + + context "when source includes something that looks like a path" do + let(:source) do + "npm.fury.io/token123/path" + end + + it do + is_expected.to eq( + "Could not verify the SSL certificate for npm.fury.io/" + ) + end + end + end +end + +RSpec.describe Dependabot::GitDependenciesNotReachable do + let(:error) { described_class.new(dependency_url) } + let(:dependency_url) do + "https://x-access-token:token@bitbucket.org/gocardless/" + end + + describe "#message" do + subject { error.message } + + it do + is_expected.to eq( + "The following git URLs could not be retrieved: " \ + "https://bitbucket.org/gocardless/" + ) + end + end +end diff --git a/common/spec/dependabot/experiments_spec.rb b/common/spec/dependabot/experiments_spec.rb new file mode 100644 index 00000000000..fc11f012be4 --- /dev/null +++ b/common/spec/dependabot/experiments_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/experiments" + +RSpec.describe Dependabot::Experiments do + before do + described_class.reset! + end + + it "can register experiments as enabled" do + described_class.register(:my_test, true) + + expect(described_class.enabled?(:my_test)).to be_truthy + end + + it "works with string names and symbols" do + described_class.register("my_test", true) + + expect(described_class.enabled?("my_test")).to be_truthy + expect(described_class.enabled?(:my_test)).to be_truthy + end +end diff --git a/common/spec/dependabot/file_fetchers/base_spec.rb b/common/spec/dependabot/file_fetchers/base_spec.rb index 3e6eb7bfd21..b992833517a 100644 --- a/common/spec/dependabot/file_fetchers/base_spec.rb +++ b/common/spec/dependabot/file_fetchers/base_spec.rb @@ -2,10 +2,12 @@ require "aws-sdk-codecommit" require "octokit" +require "fileutils" require "spec_helper" require "dependabot/source" require "dependabot/file_fetchers/base" require "dependabot/clients/codecommit" +require "dependabot/shared_helpers" RSpec.describe Dependabot::FileFetchers::Base do let(:source) do @@ -37,6 +39,7 @@ Dependabot::Clients::CodeCommit ).to receive(:cc_client).and_return(stubbed_cc_client) end + let(:repo_contents_path) { nil } let(:child_class) do Class.new(described_class) do @@ -56,7 +59,11 @@ def fetch_files end end let(:file_fetcher_instance) do - child_class.new(source: source, credentials: credentials) + child_class.new( + source: source, + credentials: credentials, + repo_contents_path: repo_contents_path + ) end describe "#commit" do @@ -280,7 +287,7 @@ def fetch_files end end - # Note: only used locally when testing against specific commits + # NOTE: only used locally when testing against specific commits context "with a source commit" do let(:source_commit) { "0e8b8c801024c811d434660f8cf09809f9eb9540" } @@ -468,7 +475,7 @@ def fetch_files headers: { "content-type" => "application/json" } ) - sub_url = "https://api.github.com/repos/dependabot/"\ + sub_url = "https://api.github.com/repos/dependabot/" \ "manifesto/contents/" stub_request(:get, sub_url + "?ref=sha2"). with(headers: { "Authorization" => "token token" }). @@ -535,7 +542,7 @@ def fetch_files headers: { "content-type" => "application/json" } ) - sub_url = "https://api.github.com/repos/dependabot/"\ + sub_url = "https://api.github.com/repos/dependabot/" \ "manifesto/contents/" stub_request(:get, sub_url + "?ref=sha2"). with(headers: { "Authorization" => "token token" }). @@ -665,8 +672,8 @@ def fetch_files context "when a dependency file is too big to download" do let(:blob_url) do - "https://api.github.com/repos/#{repo}/git/blobs/"\ - "88b4e0a1c8093fae2b4fa52534035f9f85ed0956" + "https://api.github.com/repos/#{repo}/git/blobs/" \ + "88b4e0a1c8093fae2b4fa52534035f9f85ed0956" end before do stub_request(:get, url + "requirements.txt?ref=sha"). @@ -957,7 +964,7 @@ def fetch_files let(:repo_url) { base_url + "/_apis/git/repositories/bump" } let(:url) do repo_url + "/items?path=requirements.txt" \ - "&versionDescriptor.version=sha&versionDescriptor.versionType=commit" + "&versionDescriptor.version=sha&versionDescriptor.versionType=commit" end before do @@ -985,8 +992,8 @@ def fetch_files let(:directory) { "app/" } let(:url) do repo_url + "/items?path=app/requirements.txt" \ - "&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.version=sha" \ + "&versionDescriptor.versionType=commit" end it "hits the right Azure DevOps URL" do @@ -999,8 +1006,8 @@ def fetch_files let(:directory) { "/app" } let(:url) do repo_url + "/items?path=app/requirements.txt" \ - "&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.version=sha" \ + "&versionDescriptor.versionType=commit" end it "hits the right Azure DevOps URL" do @@ -1013,8 +1020,8 @@ def fetch_files let(:directory) { "a/pp" } let(:url) do repo_url + "/items?path=a/pp/requirements.txt" \ - "&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.version=sha" \ + "&versionDescriptor.versionType=commit" end it "hits the right Azure DevOps URL" do @@ -1063,16 +1070,16 @@ def fetch_files let(:repo_contents_tree_url) do repo_url + "/items?path=/&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.versionType=commit" end let(:repo_contents_url) do repo_url + "/trees/9fea8a9fd1877daecde8f80137f9dfee6ec0b01a" \ - "?recursive=false" + "?recursive=false" end let(:repo_file_url) do repo_url + "/items?path=requirements.txt" \ - "&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.version=sha" \ + "&versionDescriptor.versionType=commit" end before do @@ -1115,11 +1122,11 @@ def fetch_files let(:repo_contents_tree_url) do repo_url + "/items?path=app&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.versionType=commit" end let(:repo_contents_url) do repo_url + "/trees/9fea8a9fd1877daecde8f80137f9dfee6ec0b01a" \ - "?recursive=false" + "?recursive=false" end before do @@ -1135,7 +1142,7 @@ def fetch_files let(:url) do repo_url + "/items?path=app&versionDescriptor.version=sha" \ - "&versionDescriptor.versionType=commit" + "&versionDescriptor.versionType=commit" end it "hits the right Azure DevOps URL" do @@ -1313,4 +1320,357 @@ def fetch_files end end end + + context "with repo_contents_path" do + let(:repo_contents_path) { Dir.mktmpdir } + after { FileUtils.rm_rf(repo_contents_path) } + + describe "#files" do + subject(:files) { file_fetcher_instance.files } + + let(:contents) { "foo=1.0.0" } + + # `git clone` against a file:// URL that is filled by the test + let(:repo_path) { Dir.mktmpdir } + after { FileUtils.rm_rf(repo_path) } + let(:fill_repo) { nil } + before do + Dir.chdir(repo_path) do + `git init .` + fill_repo + `git add .` + `git commit --allow-empty -m'fake clone source'` + end + + allow(source). + to receive(:url).and_return("file://#{repo_path}") + allow(file_fetcher_instance).to receive(:commit).and_return("sha") + end + + context "with a git source" do + let(:fill_repo) do + File.write("requirements.txt", contents) + end + + its(:length) { is_expected.to eq(1) } + + describe "the file" do + subject { files.find { |file| file.name == "requirements.txt" } } + + it { is_expected.to be_a(Dependabot::DependencyFile) } + its(:content) { is_expected.to eq(contents) } + its(:directory) { is_expected.to eq("/") } + end + + context "with an optional file" do + let(:child_class) do + Class.new(described_class) do + def self.required_files_in?(filenames) + filenames.include?("requirements.txt") + end + + def self.required_files_message + "Repo must contain a requirements.txt." + end + + private + + def fetch_files + files = [fetch_file_from_host("requirements.txt")] + files << optional if optional + files + end + + def optional + @optional ||= fetch_file_if_present("not-present.txt") + end + end + end + + its(:length) { is_expected.to eq(1) } + + describe "the file" do + subject { files.find { |file| file.name == "requirements.txt" } } + + it { is_expected.to be_a(Dependabot::DependencyFile) } + end + end + end + + context "with an invalid source" do + before do + allow(source). + to receive(:url).and_return("file://does/not/exist") + end + + it "raises RepoNotFound" do + expect { subject }. + to raise_error(Dependabot::RepoNotFound) + end + end + + context "file not found" do + it "raises DependencyFileNotFound" do + expect { subject }. + to raise_error(Dependabot::DependencyFileNotFound) do |error| + expect(error.file_path).to eq("/requirements.txt") + end + end + end + + context "symlink" do + let(:fill_repo) do + Dir.mkdir("symlinked") + file_path = File.join("symlinked", "requirements.txt") + File.write(file_path, contents) + File.symlink(file_path, "requirements.txt") + end + + describe "the file" do + subject { files.find { |file| file.name == "requirements.txt" } } + + it { is_expected.to be_a(Dependabot::DependencyFile) } + its(:type) { is_expected.to include("symlink") } + its(:symlink_target) do + is_expected.to include("symlinked/requirements.txt") + end + end + end + + context "when the file is in a directory" do + let(:child_class) do + Class.new(described_class) do + def self.required_files_in?(filenames) + filenames.include?("nested/requirements.txt") + end + + def self.required_files_message + "Repo must contain a nested/requirements.txt." + end + + private + + def fetch_files + [fetch_file_from_host("nested/requirements.txt")] + end + end + end + + context "file not found" do + it "raises DependencyFileNotFound" do + expect { subject }. + to raise_error(Dependabot::DependencyFileNotFound) do |error| + expect(error.file_path).to eq("/nested/requirements.txt") + end + end + end + + context "with a git source" do + let(:fill_repo) do + Dir.mkdir("nested") + path = File.join("nested", "requirements.txt") + File.write(path, contents) + end + + its(:length) { is_expected.to eq(1) } + + describe "the file" do + subject do + files.find { |file| file.name == "nested/requirements.txt" } + end + + it { is_expected.to be_a(Dependabot::DependencyFile) } + its(:content) { is_expected.to eq(contents) } + its(:directory) { is_expected.to eq("/") } + end + end + end + + context "with a directory specified" do + let(:directory) { "/nested" } + + context "file not found" do + it "raises DependencyFileNotFound" do + expect { subject }. + to raise_error(Dependabot::DependencyFileNotFound) do |error| + expect(error.file_path).to eq("/nested/requirements.txt") + end + end + end + + context "with a git source" do + let(:fill_repo) do + Dir.mkdir("nested") + path = File.join("nested", "requirements.txt") + File.write(path, contents) + end + + its(:length) { is_expected.to eq(1) } + + describe "the file" do + subject do + files.find { |file| file.name == "requirements.txt" } + end + + it { is_expected.to be_a(Dependabot::DependencyFile) } + its(:content) { is_expected.to eq(contents) } + its(:directory) { is_expected.to eq(directory) } + end + end + end + end + + describe "#clone_repo_contents" do + subject(:clone_repo_contents) do + file_fetcher_instance.clone_repo_contents + end + + let(:repo) do + "dependabot-fixtures/go-modules-app" + end + + it "clones the repo" do + clone_repo_contents + expect(`ls #{repo_contents_path}`).to include("README") + end + + context "with a branch name including bash command" do + let(:branch) do + "\"$(time)\"" + end + + it "clones the repo with branch checked out" do + clone_repo_contents + expect(`ls #{repo_contents_path}`).to include("time.md") + end + end + + context "when the repo can't be found" do + let(:repo) do + "dependabot-fixtures/not-found" + end + + it "raises a not found error" do + expect { subject }.to raise_error(Dependabot::RepoNotFound) + end + end + + context "when the branch can't be found" do + let(:branch) do + "notfound" + end + + it "raises a not found error" do + expect { subject }.to raise_error(Dependabot::BranchNotFound) + end + end + + context "when the submodule can't be reached" do + let(:repo) do + "dependabot-fixtures/go-modules-app-with-inaccessible-submodules" + end + let(:branch) do + "with-git-urls" + end + + it "does not raise an error" do + clone_repo_contents + expect(`ls #{repo_contents_path}`).to include("README") + end + end + end + end + + context "with submodules" do + let(:repo) { "dependabot-fixtures/go-modules-app-with-git-submodules" } + let(:repo_contents_path) { Dir.mktmpdir } + let(:submodule_contents_path) { File.join(repo_contents_path, "examplelib") } + + before do + allow(Dependabot::SharedHelpers). + to receive(:run_shell_command).and_call_original + end + + after { FileUtils.rm_rf(repo_contents_path) } + + describe "#clone_repo_contents" do + it "does not clone submodules by default" do + file_fetcher_instance.clone_repo_contents + + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit clone .* --no-recurse-submodules/ + ) + expect(`ls -1 #{submodule_contents_path}`.split).to_not include("go.mod") + end + + context "with a source commit" do + let(:source_commit) { "5c7e92a4860382fd31336872f0fe79a848669c4d" } + + it "does not fetch/reset submodules by default" do + file_fetcher_instance.clone_repo_contents + + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit fetch .* --no-recurse-submodules/ + ) + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit reset .* --no-recurse-submodules/ + ) + end + end + + context "when #recurse_submodules_when_cloning? returns true" do + let(:child_class) do + Class.new(described_class) do + def self.required_files_in?(filenames) + filenames.include?("go.mod") + end + + def self.required_files_message + "Repo must contain a go.mod." + end + + private + + def fetch_files + [fetch_file_from_host("go.mod")] + end + + def recurse_submodules_when_cloning? + true + end + end + end + + it "clones submodules" do + file_fetcher_instance.clone_repo_contents + + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit clone .* --recurse-submodules --shallow-submodules/ + ) + expect(`ls -1 #{submodule_contents_path}`.split).to include("go.mod") + end + + context "with a source commit" do + let(:source_commit) { "5c7e92a4860382fd31336872f0fe79a848669c4d" } + + it "fetches/resets submodules if necessary" do + file_fetcher_instance.clone_repo_contents + + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit fetch .* --recurse-submodules=on-demand/ + ) + expect(Dependabot::SharedHelpers). + to have_received(:run_shell_command).with( + /\Agit reset .* --recurse-submodules/ + ) + end + end + end + end + end end diff --git a/common/spec/dependabot/file_parsers/base/dependency_set_spec.rb b/common/spec/dependabot/file_parsers/base/dependency_set_spec.rb index bd0fe52a273..f6c4b0161b8 100644 --- a/common/spec/dependabot/file_parsers/base/dependency_set_spec.rb +++ b/common/spec/dependabot/file_parsers/base/dependency_set_spec.rb @@ -234,4 +234,134 @@ end end end + + context "when multiple versions of a dependency are added" do + let(:foo_v1) do + Dependabot::Dependency.new( + name: "foo", + version: "1.0", + requirements: [], + package_manager: "dummy" + ) + end + + let(:foo_v1_1) do # rubocop:disable Naming/VariableNumber + Dependabot::Dependency.new( + name: "foo", + version: "1.1", + requirements: [{ + requirement: "^1", + file: "Dummyfile", + groups: nil, + source: nil + }], + package_manager: "dummy" + ) + end + + let(:foo_v1_1_alt) do + Dependabot::Dependency.new( + name: "foo", + version: "1.1", + requirements: [{ + requirement: "^1", + file: "Dummyfile.lock", + groups: ["prod"], + source: { + type: "registry", + url: "https://registry.dummy.org" + } + }], + package_manager: "dummy" + ) + end + + let(:foo_sha) do + Dependabot::Dependency.new( + name: "foo", + version: "d5ac0584ee9ae7bd9288220a39780f155b9ad4c8", + requirements: [{ + requirement: "^1", + file: "Dummyfile.lock", + groups: ["prod"], + source: { + type: "git", + url: "https://github.com/acme-inc/foo", + branch: nil, + ref: "main" + } + }], + package_manager: "dummy" + ) + end + + it "merges each into a single combined dependency" do + dependency_set = described_class.new << foo_v1 << foo_sha << foo_v1_1 + + expect(dependency_set.dependency_for_name("foo")).to eq( + Dependabot::Dependency.new( + name: "foo", + version: "1.0", + requirements: ( + foo_v1.requirements + + foo_sha.requirements + + foo_v1_1.requirements + ).uniq, + package_manager: "dummy" + ) + ) + end + + it "returns all versions in the order they were added by default" do + dependency_set = described_class.new << foo_v1_1 << foo_sha << foo_v1 + expect(dependency_set.all_versions_for_name("foo")).to eq([foo_v1_1, foo_sha, foo_v1]) + end + + it "preserves all versions when combined with another dependency set" do + set_a = described_class.new << foo_v1 + set_b = described_class.new << foo_sha << foo_v1_1 << foo_v1_1_alt + combined_set = set_a + set_b + + expect(combined_set.dependency_for_name("foo")).to eq( + Dependabot::Dependency.new( + name: "foo", + version: "1.0", + requirements: ( + foo_v1.requirements + + foo_sha.requirements + + foo_v1_1.requirements + + foo_v1_1_alt.requirements + ).uniq, + package_manager: "dummy" + ) + ) + + expect(combined_set.all_versions_for_name("foo")).to eq([ + foo_v1, + foo_sha, + Dependabot::Dependency.new( + name: "foo", + version: "1.1", + package_manager: "dummy", + requirements: (foo_v1_1.requirements + foo_v1_1_alt.requirements).uniq + ) + ]) + end + + context "and the same version is added multiple times" do + it "combines each into the the existing version" do + dependency_set = described_class.new << foo_v1_1 << foo_v1_1_alt << foo_sha + + expect(dependency_set.all_versions_for_name("foo")).to eq([ + Dependabot::Dependency.new( + name: "foo", + version: "1.1", + package_manager: "dummy", + requirements: (foo_v1_1.requirements + foo_v1_1_alt.requirements).uniq + ), + foo_sha + ]) + end + end + end end diff --git a/common/spec/dependabot/file_updaters/vendor_updater_spec.rb b/common/spec/dependabot/file_updaters/vendor_updater_spec.rb new file mode 100644 index 00000000000..7a5d199a774 --- /dev/null +++ b/common/spec/dependabot/file_updaters/vendor_updater_spec.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/file_updaters/vendor_updater" + +RSpec.describe Dependabot::FileUpdaters::VendorUpdater do + let(:updater) do + described_class.new( + repo_contents_path: repo_contents_path, + vendor_dir: vendor_dir + ) + end + + let(:vendor_dir) do + File.join(repo_contents_path, directory, "vendor/cache") + end + let(:project_name) { "vendor_gems" } + let(:repo_contents_path) { build_tmp_repo(project_name) } + let(:directory) { "/" } + + let(:updated_files) do + updater.updated_vendor_cache_files(base_directory: directory) + end + + after do + FileUtils.remove_entry repo_contents_path + end + + describe "#updated_vendor_cache_files" do + before do + in_cloned_repository(repo_contents_path) do + # change a vendor file like an updater would + next unless File.exist?("vendor/cache/business-1.4.0.gem") + + `mv vendor/cache/business-1.4.0.gem vendor/cache/business-1.5.0.gem` + `echo change >> vendor/cache/test-change.txt` + end + end + + it "returns the updated files" do + expect(updated_files.map(&:name)).to eq( + %w( + vendor/cache/business-1.4.0.gem + vendor/cache/test-change.txt + vendor/cache/business-1.5.0.gem + ) + ) + end + + it "marks binary files as such" do + file = updated_files.find do |f| + f.name == "vendor/cache/business-1.5.0.gem" + end + + expect(file.binary?).to be_truthy + end + + it "marks created files as such" do + file = updated_files.find do |f| + f.name == "vendor/cache/business-1.5.0.gem" + end + + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::CREATE + end + + it "marks updated files as such" do + file = updated_files.find do |f| + f.name == "vendor/cache/test-change.txt" + end + + expect(file.deleted).to be_falsey + expect(file.deleted?).to be_falsey + expect(file.operation).to eq Dependabot::DependencyFile::Operation::UPDATE + end + + it "marks deleted files as such" do + file = updated_files.find do |f| + f.name == "vendor/cache/business-1.4.0.gem" + end + + expect(file.deleted).to be_truthy + expect(file.deleted?).to be_truthy + expect(file.operation).to eq Dependabot::DependencyFile::Operation::DELETE + end + + it "base64 encodes binary files" do + file = updated_files.find do |f| + f.name == "vendor/cache/business-1.5.0.gem" + end + + expect(file.content_encoding).to eq("base64") + end + + it "ignores files that are in the .gitignore" do + in_cloned_repository(repo_contents_path) do + `touch vendor/cache/ignored.txt` + end + + expect(updated_files.map(&:name)).to_not include( + "vendor/cache/ignored.txt" + ) + end + + it "ignores files that are not in the vendor directory" do + in_cloned_repository(repo_contents_path) do + `touch some-file.txt` + end + + expect(updated_files.map(&:name)).to_not include( + "some-file.txt" + ) + end + + context "with iso-8859 files" do + before do + in_cloned_repository(repo_contents_path) do + File.write("vendor/cache/utf8.txt", "special Ãŧ".encode("utf-8")) + File.write("vendor/cache/iso8859.txt", "special Ãŧ".encode("iso-8859-1")) + end + end + + it "marks binary files as such" do + file = updated_files.find do |f| + f.name == "vendor/cache/iso8859.txt" + end + + expect(file.binary?).to be_truthy + end + + it "does not mark all files as binary" do + file = updated_files.find do |f| + f.name == "vendor/cache/utf8.txt" + end + + expect(file.binary?).to be_falsy + end + end + + context "in a directory" do + let(:project_name) { "nested_vendor_gems" } + let(:directory) { "nested" } + + before do + in_cloned_repository(repo_contents_path) do + # change a vendor file like an updater would + `mv nested/vendor/cache/business-1.4.0.gem \ + nested/vendor/cache/business-1.5.0.gem` + end + end + + it "does not include the directory in the name" do + expect(updated_files.first.name).to_not include("nested") + end + + it "sets the right directory" do + expect(updated_files.first.directory).to eq("/nested") + end + end + end + + describe "binary encoding" do + let(:project_name) { "binary_files" } + + %w(test.zip test_bin test.png test.gem .bundlecache).each do |name| + it "marks #{name} files correctly" do + in_cloned_repository(repo_contents_path) do + `mv vendor/cache/#{name} vendor/cache/new_#{name}` + end + + file = updated_files.find { |f| f.name == "vendor/cache/new_#{name}" } + + expect(file.binary?).to be_truthy + end + end + end + + private + + def in_cloned_repository(repo_contents_path, &block) + Dir.chdir(repo_contents_path, &block) + end +end diff --git a/common/spec/dependabot/git_commit_checker_spec.rb b/common/spec/dependabot/git_commit_checker_spec.rb index 3d6bc6d41ec..a04a2e4bf8b 100644 --- a/common/spec/dependabot/git_commit_checker_spec.rb +++ b/common/spec/dependabot/git_commit_checker_spec.rb @@ -58,6 +58,27 @@ it { is_expected.to eq(false) } end + context "with a non-git dependency that has multiple sources" do + let(:requirements) do + [ + { + file: "package.json", + requirement: "0.1.0", + groups: ["dependencies"], + source: { type: "registry", url: "https://registry.npmjs.org" } + }, + { + file: "package.json", + requirement: "0.1.0", + groups: ["devDependencies"], + source: { type: "registry", url: "https://registry.yarnpkg.com" } + } + ] + end + + it { is_expected.to eq(false) } + end + context "with a git dependency" do let(:source) do { @@ -107,7 +128,7 @@ end context "with multiple source types" do - let(:s2) { { type: "path" } } + let(:s2) { { type: "git", url: "https://github.com/dependabot/dependabot-core" } } it "raises a helpful error" do expect { checker.git_dependency? }. @@ -148,8 +169,8 @@ context "with source code hosted on GitHub" do let(:repo_url) { "https://api.github.com/repos/gocardless/business" } let(:service_pack_url) do - "https://github.com/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://github.com/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end before do stub_request(:get, service_pack_url). @@ -169,7 +190,16 @@ end context "but GitHub returns a 404" do - before { stub_request(:get, service_pack_url).to_return(status: 404) } + let(:url) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) + end + it { is_expected.to eq(false) } end @@ -259,12 +289,12 @@ end let(:source_url) { "https://bitbucket.org/gocardless/business" } let(:service_pack_url) do - "https://bitbucket.org/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://bitbucket.org/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:bitbucket_url) do - "https://api.bitbucket.org/2.0/repositories/"\ - "gocardless/business/commits/?exclude=v1.5.0&include=df9f605" + "https://api.bitbucket.org/2.0/repositories/" \ + "gocardless/business/commits/?exclude=v1.5.0&include=df9f605" end before do stub_request(:get, service_pack_url). @@ -412,6 +442,12 @@ git_url = "https://github.com/gocardless/business.git" stub_request(:get, git_url + "/info/refs?service=git-upload-pack"). to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3). + with(anything, "git ls-remote #{git_url}"). + and_return(["", "", exit_status]) end let(:ref) { "my_ref" } @@ -474,31 +510,32 @@ ref: "v1.0.0" } end - it { is_expected.to eq(dependency.version) } - context "without a version" do - let(:version) { nil } - - let(:git_header) do - { "content-type" => "application/x-git-upload-pack-advertisement" } - end - let(:auth_header) { "Basic eC1hY2Nlc3MtdG9rZW46dG9rZW4=" } + let(:git_header) do + { "content-type" => "application/x-git-upload-pack-advertisement" } + end + let(:auth_header) { "Basic eC1hY2Nlc3MtdG9rZW46dG9rZW4=" } - let(:git_url) do - "https://github.com/gocardless/business.git" \ + let(:git_url) do + "https://github.com/gocardless/business.git" \ "/info/refs?service=git-upload-pack" + end + + context "that can be reached just fine" do + before do + stub_request(:get, git_url). + with(headers: { "Authorization" => auth_header }). + to_return( + status: 200, + body: fixture("git", "upload_packs", "business"), + headers: git_header + ) end - context "that can be reached just fine" do - before do - stub_request(:get, git_url). - with(headers: { "Authorization" => auth_header }). - to_return( - status: 200, - body: fixture("git", "upload_packs", "business"), - headers: git_header - ) - end + it { is_expected.to eq(dependency.version) } + + context "without a version" do + let(:version) { nil } it { is_expected.to eq("df9f605d7111b6814fe493cf8f41de3f9f0978b2") } @@ -527,7 +564,7 @@ let(:git_url) do "https://github.com/gocardless/business.git" \ - "/info/refs?service=git-upload-pack" + "/info/refs?service=git-upload-pack" end context "that can be reached just fine" do @@ -608,10 +645,16 @@ end context "that results in a 403" do + let(:url) { "https://github.com/gocardless/business.git" } + before do stub_request(:get, git_url). with(headers: { "Authorization" => auth_header }). to_return(status: 403) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it "raises a helpful error" do @@ -631,7 +674,7 @@ end let(:git_url) do "https://bitbucket.org/gocardless/business.git" \ - "/info/refs?service=git-upload-pack" + "/info/refs?service=git-upload-pack" end context "that needs credentials to succeed" do @@ -669,7 +712,7 @@ let(:source) do { type: "git", - url: "https://x-access-token:token@bitbucket.org/gocardless/"\ + url: "https://x-access-token:token@bitbucket.org/gocardless/" \ "business", branch: "master", ref: "master" @@ -842,6 +885,29 @@ end end + describe "#head_commit_for_local_branch" do + let(:tip_of_example) { "303b8a83c87d5c6d749926cf02620465a5dcd0f2" } + + subject { checker.head_commit_for_local_branch("example") } + + let(:repo_url) { "https://github.com/gocardless/business.git" } + let(:service_pack_url) { repo_url + "/info/refs?service=git-upload-pack" } + before do + stub_request(:get, service_pack_url). + to_return( + status: 200, + body: fixture("git", "upload_packs", upload_pack_fixture), + headers: { + "content-type" => "application/x-git-upload-pack-advertisement" + } + ) + end + + let(:upload_pack_fixture) { "monolog" } + + it { is_expected.to eq(tip_of_example) } + end + describe "#local_tag_for_latest_version" do subject { checker.local_tag_for_latest_version } let(:repo_url) { "https://github.com/gocardless/business.git" } @@ -863,7 +929,15 @@ end context "but GitHub returns a 404" do - before { stub_request(:get, service_pack_url).to_return(status: 404) } + let(:url) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) + end it "raises a helpful error" do expect { checker.local_tag_for_latest_version }. @@ -920,11 +994,48 @@ its([:tag]) { is_expected.to eq("gatsby-transformer-sqip@2.0.40") } end + context "raise_on_ignored when later versions are allowed" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + + context "already on the latest version" do + let(:version) { "1.13.0" } + its([:tag]) { is_expected.to eq("v1.13.0") } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "doesn't raise an error" do + expect { subject }.to_not raise_error + end + end + end + + context "all later versions ignored" do + let(:version) { "1.0.0" } + let(:ignored_versions) { ["> 1.0.0"] } + its([:tag]) { is_expected.to eq("v1.0.0") } + + context "raise_on_ignored" do + let(:raise_on_ignored) { true } + it "raises an error" do + expect { subject }.to raise_error(Dependabot::AllVersionsIgnored) + end + end + end + context "and an ignore condition" do let(:ignored_versions) { [">= 1.12.0"] } its([:tag]) { is_expected.to eq("v1.11.1") } end + context "multiple ignore conditions" do + let(:ignored_versions) { [">= 1.11.2, < 1.12.0"] } + its([:tag]) { is_expected.to eq("v1.13.0") } + end + context "all versions ignored" do let(:ignored_versions) { [">= 0"] } it "returns nil" do @@ -955,6 +1066,214 @@ end end + describe "#local_ref_for_latest_version_matching_existing_precision" do + subject { checker.local_ref_for_latest_version_matching_existing_precision } + let(:repo_url) { "https://github.com/gocardless/business.git" } + let(:service_pack_url) { repo_url + "/info/refs?service=git-upload-pack" } + before do + stub_request(:get, service_pack_url). + to_return( + status: 200, + body: fixture("git", "upload_packs", upload_pack_fixture), + headers: { + "content-type" => "application/x-git-upload-pack-advertisement" + } + ) + end + + context "with no tags, nor version branches" do + let(:upload_pack_fixture) { "no_tags" } + it { is_expected.to be_nil } + end + + context "with no version tags nor version branches" do + let(:upload_pack_fixture) { "no_versions" } + it { is_expected.to be_nil } + end + + context "with version tags, and some version branches not matching pinned schema" do + let(:upload_pack_fixture) { "actions-checkout" } + let(:version) { "1.1.1" } + + let(:source) do + { + type: "git", + url: "https://github.com/gocardless/business", + branch: "master", + ref: "v#{version}" + } + end + + let(:latest_patch) do + { + commit_sha: "5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f", + tag: "v2.3.4", + tag_sha: anything, + version: anything + } + end + + it { is_expected.to match(latest_patch) } + end + + context "with a version branch higher than the latest version tag, and pinned to the commit sha of a version tag" do + let(:upload_pack_fixture) { "actions-checkout-2022-12-01" } + let(:version) { "1.1.0" } + + let(:source) do + { + type: "git", + url: "https://github.com/gocardless/business", + branch: "master", + ref: "0b496e91ec7ae4428c3ed2eeb4c3a40df431f2cc" + } + end + + let(:latest_patch) do + { + commit_sha: "93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8", + tag: "v3.1.0", + tag_sha: anything, + version: anything + } + end + + it { is_expected.to match(latest_patch) } + end + + context "with tags for minor versions and branches for major versions" do + let(:upload_pack_fixture) { "run-vcpkg" } + + context "when pinned to a major" do + let(:version) { "7" } + + let(:latest_major_branch) do + { + commit_sha: "831e6cd560cc8688a4967c5766e4215afbd196d9", + tag: "v10", + tag_sha: anything, + version: anything + } + end + + it { is_expected.to match(latest_major_branch) } + end + + context "when pinned to a minor" do + let(:version) { "7.0" } + + let(:latest_minor_tag) do + { + commit_sha: "831e6cd560cc8688a4967c5766e4215afbd196d9", + tag: "v10.6", + tag_sha: anything, + version: anything + } + end + + it { is_expected.to match(latest_minor_tag) } + end + end + end + + describe "#local_tag_for_pinned_sha" do + subject { checker.local_tag_for_pinned_sha } + + context "with a git commit pin" do + let(:source) do + { + type: "git", + url: "https://github.com/actions/checkout", + branch: "main", + ref: source_commit + } + end + + let(:repo_url) { "https://github.com/actions/checkout.git" } + let(:service_pack_url) { repo_url + "/info/refs?service=git-upload-pack" } + before do + stub_request(:get, service_pack_url). + to_return( + status: 200, + body: fixture("git", "upload_packs", upload_pack_fixture), + headers: { + "content-type" => "application/x-git-upload-pack-advertisement" + } + ) + end + let(:upload_pack_fixture) { "actions-checkout" } + + context "that is a tag" do + let(:source_commit) { "a81bbbf8298c0fa03ea29cdc473d45769f953675" } + + it { is_expected.to eq("v2.3.3") } + end + + context "that is not a tag" do + let(:source_commit) { "25a956c84d5dd820d28caab9f86b8d183aeeff3d" } + + it { is_expected.to be_nil } + end + + context "that is an invalid tag" do + let(:source_commit) { "18217bbd6de24e775799c3d99058f167ad168624" } + + it { is_expected.to be_nil } + end + + context "that is not found" do + let(:source_commit) { "f0987d27b23cb3fd0e97eb7908c1a27df5bf8329" } + + it { is_expected.to be_nil } + end + + context "that is multiple tags" do + let(:source_commit) { "5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f" } + + it { is_expected.to eq("v2.3.4") } + end + end + end + + describe "#most_specific_tag_equivalent_to_pinned_ref" do + subject { checker.most_specific_tag_equivalent_to_pinned_ref } + + let(:source) do + { + type: "git", + url: "https://github.com/actions/checkout", + branch: "main", + ref: source_ref + } + end + + let(:repo_url) { "https://github.com/actions/checkout.git" } + let(:service_pack_url) { repo_url + "/info/refs?service=git-upload-pack" } + before do + stub_request(:get, service_pack_url). + to_return( + status: 200, + body: fixture("git", "upload_packs", upload_pack_fixture), + headers: { + "content-type" => "application/x-git-upload-pack-advertisement" + } + ) + end + let(:upload_pack_fixture) { "actions-checkout-moving-v2" } + + context "for a moving major tag" do + let(:source_ref) { "v2" } + + it { is_expected.to eq("v2.3.4") } + end + + context "for a fixed patch tag" do + let(:source_ref) { "v2.3.4" } + + it { is_expected.to eq("v2.3.4") } + end + end + describe "#git_repo_reachable?" do subject { checker.git_repo_reachable? } @@ -973,7 +1292,7 @@ let(:git_url) do "https://github.com/gocardless/business.git" \ - "/info/refs?service=git-upload-pack" + "/info/refs?service=git-upload-pack" end context "that can be reached just fine" do @@ -991,10 +1310,16 @@ end context "that results in a 403" do + let(:url) { "https://github.com/gocardless/business.git" } + before do stub_request(:get, git_url). with(headers: { "Authorization" => auth_header }). to_return(status: 403) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it { is_expected.to eq(false) } diff --git a/common/spec/dependabot/git_metadata_fetcher_spec.rb b/common/spec/dependabot/git_metadata_fetcher_spec.rb index cb6e99342e8..ed868b13125 100644 --- a/common/spec/dependabot/git_metadata_fetcher_spec.rb +++ b/common/spec/dependabot/git_metadata_fetcher_spec.rb @@ -35,8 +35,8 @@ context "with source code hosted on GitHub" do let(:service_pack_url) do - "https://github.com/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://github.com/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "no_tags" } @@ -61,7 +61,15 @@ end context "but GitHub returns a 404" do - before { stub_request(:get, service_pack_url).to_return(status: 404) } + let(:uri) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{uri}").and_return(["", "", exit_status]) + end it "raises a helpful error" do expect { tags }. @@ -70,7 +78,15 @@ end context "but GitHub returns a 401" do - before { stub_request(:get, service_pack_url).to_return(status: 401) } + let(:uri) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 401) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{uri}").and_return(["", "", exit_status]) + end it "raises a helpful error" do expect { tags }. @@ -79,7 +95,15 @@ end context "but GitHub returns a 500" do - before { stub_request(:get, service_pack_url).to_return(status: 500) } + let(:uri) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 500) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{uri}").and_return(["", "", exit_status]) + end it "raises a helpful error" do expect { tags }.to raise_error(Octokit::InternalServerError) @@ -101,6 +125,23 @@ ) end + context "when HTTP returns a 500 but git ls-remote succeeds" do + let(:uri) { "https://github.com/gocardless/business.git" } + let(:stdout) { fixture("git", "upload_packs", upload_pack_fixture) } + + before do + stub_request(:get, service_pack_url).to_return(status: 500) + + exit_status = double(success?: true) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3). + with(anything, "git ls-remote #{uri}"). + and_return([stdout, "", exit_status]) + end + + its(:count) { is_expected.to eq(14) } + end + context "when there is no github.com credential" do let(:credentials) do [{ @@ -143,8 +184,8 @@ context "with source code not hosted on GitHub" do let(:url) { "https://bitbucket.org/gocardless/business" } let(:service_pack_url) do - "https://bitbucket.org/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://bitbucket.org/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "business" } @@ -155,8 +196,8 @@ context "with source code hosted on a HTTP host" do let(:url) { "http://bitbucket.org/gocardless/business" } let(:service_pack_url) do - "http://bitbucket.org/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "http://bitbucket.org/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "business" } @@ -181,11 +222,28 @@ context "with source code hosted on GitHub" do let(:service_pack_url) do - "https://github.com/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://github.com/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "no_tags" } + context "when HTTP returns a 500 but git ls-remote succeeds" do + let(:uri) { "https://github.com/gocardless/business.git" } + let(:stdout) { fixture("git", "upload_packs", upload_pack_fixture) } + + before do + stub_request(:get, service_pack_url).to_return(status: 500) + + exit_status = double(success?: true) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3). + with(anything, "git ls-remote #{uri}"). + and_return([stdout, "", exit_status]) + end + + it { is_expected.to eq(%w(master rails5)) } + end + context "with tags on GitHub" do let(:upload_pack_fixture) { "no_versions" } it { is_expected.to eq(%w(master imported release)) } @@ -197,7 +255,15 @@ end context "but GitHub returns a 404" do - before { stub_request(:get, service_pack_url).to_return(status: 404) } + let(:uri) { "https://github.com/gocardless/business.git" } + + before do + stub_request(:get, service_pack_url).to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{uri}").and_return(["", "", exit_status]) + end it "raises a helpful error" do expect { ref_names }. @@ -223,8 +289,8 @@ end let(:service_pack_url) do - "https://github.com/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://github.com/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "business" } @@ -234,6 +300,24 @@ to eq("df9f605d7111b6814fe493cf8f41de3f9f0978b2") end + context "when HTTP returns a 500 but git ls-remote succeeds" do + let(:uri) { "https://github.com/gocardless/business.git" } + let(:stdout) { fixture("git", "upload_packs", upload_pack_fixture) } + + before do + stub_request(:get, service_pack_url).to_return(status: 500) + + exit_status = double(success?: true) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{uri}").and_return([stdout, "", exit_status]) + end + + it "gets the correct commit SHA (not the tag SHA)" do + expect(head_commit_for_ref). + to eq("df9f605d7111b6814fe493cf8f41de3f9f0978b2") + end + end + context "with a branch" do let(:ref) { "master" } diff --git a/common/spec/dependabot/metadata_finders/base/changelog_finder_spec.rb b/common/spec/dependabot/metadata_finders/base/changelog_finder_spec.rb index 0a0709129b4..e78be573a00 100644 --- a/common/spec/dependabot/metadata_finders/base/changelog_finder_spec.rb +++ b/common/spec/dependabot/metadata_finders/base/changelog_finder_spec.rb @@ -196,7 +196,7 @@ it "falls back to looking for the changelog as usual" do expect(subject). to eq( - "https://github.com/gocardless/business/"\ + "https://github.com/gocardless/business/" \ "blob/master/CHANGELOG.md" ) end @@ -235,7 +235,7 @@ it "gets the right URL" do expect(subject). to eq( - "https://github.com/gocardless/business/blob/v1.4.0/"\ + "https://github.com/gocardless/business/blob/v1.4.0/" \ "CHANGELOG.md" ) end @@ -334,7 +334,7 @@ it "gets the right URL" do expect(subject). - to eq("https://github.com/gocardless/business/blob/master/module"\ + to eq("https://github.com/gocardless/business/blob/master/module" \ "/CHANGELOG.md") end @@ -362,7 +362,7 @@ it "gets the right URL" do expect(subject). - to eq("https://github.com/gocardless/business/blob/master"\ + to eq("https://github.com/gocardless/business/blob/master" \ "/CHANGELOG.md") end end @@ -418,7 +418,7 @@ it "gets the right URL" do expect(subject). - to eq("https://github.com/gocardless/business/blob/master/"\ + to eq("https://github.com/gocardless/business/blob/master/" \ "CHANGELOG.md") end end @@ -474,7 +474,7 @@ it "finds the changelog as normal" do expect(subject). - to eq("https://github.com/gocardless/business/blob/master/"\ + to eq("https://github.com/gocardless/business/blob/master/" \ "CHANGELOG.md") end end @@ -485,7 +485,7 @@ it "finds the changelog as normal" do expect(subject). - to eq("https://github.com/gocardless/business/blob/master/"\ + to eq("https://github.com/gocardless/business/blob/master/" \ "CHANGELOG.md") end end @@ -499,6 +499,9 @@ let(:gitlab_raw_changelog_url) do "https://gitlab.com/org/business/raw/master/CHANGELOG.md" end + let(:gitlab_repo_url) do + "https://gitlab.com/api/v4/projects/org%2Fbusiness" + end let(:gitlab_status) { 200 } let(:gitlab_response) { fixture("gitlab", "business_files.json") } @@ -514,6 +517,10 @@ to_return(status: gitlab_status, body: gitlab_response, headers: { "Content-Type" => "application/json" }) + stub_request(:get, gitlab_repo_url). + to_return(status: 200, + body: fixture("gitlab", "bump_repo.json"), + headers: { "Content-Type" => "application/json" }) stub_request(:get, gitlab_raw_changelog_url). to_return(status: 200, body: fixture("raw", "changelog.md"), @@ -544,8 +551,8 @@ context "with a bitbucket source" do let(:bitbucket_url) do - "https://api.bitbucket.org/2.0/repositories/org/business/src"\ - "?pagelen=100" + "https://api.bitbucket.org/2.0/repositories/org/business/src" \ + "?pagelen=100" end let(:bitbucket_repo_url) do "https://api.bitbucket.org/2.0/repositories/org/business" @@ -651,15 +658,15 @@ let(:dependency_previous_version) { "1.0.0" } let(:expected_pruned_changelog) do - "## 1.4.0 - December 24, 2014\n\n"\ - "- Add support for custom calendar load paths\n"\ - "- Remove the 'sepa' calendar\n\n\n"\ - "## 1.3.0 - December 2, 2014\n\n"\ - "- Add `Calendar#previous_business_day`\n\n\n"\ - "## 1.2.0 - November 15, 2014\n\n"\ - "- Add TARGET calendar\n\n\n"\ - "## 1.1.0 - September 30, 2014\n\n"\ - "- Add 2015 holiday definitions" + "## 1.4.0 - December 24, 2014\n\n" \ + "- Add support for custom calendar load paths\n" \ + "- Remove the 'sepa' calendar\n\n\n" \ + "## 1.3.0 - December 2, 2014\n\n" \ + "- Add `Calendar#previous_business_day`\n\n\n" \ + "## 1.2.0 - November 15, 2014\n\n" \ + "- Add TARGET calendar\n\n\n" \ + "## 1.1.0 - September 30, 2014\n\n" \ + "- Add 2015 holiday definitions" end context "with a github repo" do @@ -667,8 +674,8 @@ "https://api.github.com/repos/gocardless/business/contents/" end let(:github_changelog_url) do - "https://api.github.com/repos/gocardless/business/contents/"\ - "CHANGELOG.md?ref=master" + "https://api.github.com/repos/gocardless/business/contents/" \ + "CHANGELOG.md?ref=master" end let(:github_contents_response) do fixture("github", "business_files.json") @@ -766,9 +773,9 @@ include_context "with multiple git sources" let(:expected_pruned_changelog) do - "## v2.2.0\n"\ - "- [Fetch all history for all tags and branches when "\ - "fetch-depth=0](https://github.com/actions/checkout/pull/258)\n"\ + "## v2.2.0\n" \ + "- [Fetch all history for all tags and branches when " \ + "fetch-depth=0](https://github.com/actions/checkout/pull/258)\n" \ end context "when there's a new ref" do @@ -781,8 +788,8 @@ fixture("github", "scrapy_docs_files.json") end let(:github_changelog_url) do - "https://api.github.com/repos/scrapy/scrapy/contents/docs/"\ - "news.rst?ref=master" + "https://api.github.com/repos/scrapy/scrapy/contents/docs/" \ + "news.rst?ref=master" end let(:changelog_body) do fixture("github", "changelog_contents_rst.json") @@ -791,25 +798,16 @@ let(:dependency_previous_version) { "1.15.1" } let(:unconverted_text) do - "1.16.0 (2019-02-12)\n"\ - "-------------------\n"\ - "\n"\ - "* ``pytest-selenium`` now requires pytest 3.6 or later.\n"\ - "* Fixed `issue `_ with TestingBot local tunnel." - end - let(:converted_text) do - "1.16.0 (2019-02-12)\n"\ - "===================\n"\ - "\n"\ - "- `pytest-selenium` now requires pytest 3.6 or later.\n"\ - "- Fixed [issue](https://github.com/pytest-dev/"\ - "pytest-selenium/issues/216) with TestingBot local tunnel.\n" + "1.16.0 (2019-02-12)\n" \ + "-------------------\n" \ + "\n" \ + "* ``pytest-selenium`` now requires pytest 3.6 or later.\n" \ + "* Fixed `issue `_ with TestingBot local tunnel." end - it "converts the rst properly (or falls back)" do - expect([converted_text, unconverted_text]). - to include(changelog_text) + it "does not convert the rst" do + expect(changelog_text).to eq(unconverted_text) end end end @@ -851,8 +849,8 @@ end let(:github_changelog_url) do - "https://api.github.com/repos/mperham/sidekiq/contents/"\ - "Pro-Changes.md?ref=master" + "https://api.github.com/repos/mperham/sidekiq/contents/" \ + "Pro-Changes.md?ref=master" end it { is_expected.to eq(expected_pruned_changelog) } @@ -866,6 +864,9 @@ let(:gitlab_raw_changelog_url) do "https://gitlab.com/org/business/raw/master/CHANGELOG.md" end + let(:gitlab_repo_url) do + "https://gitlab.com/api/v4/projects/org%2Fbusiness" + end let(:gitlab_contents_response) do fixture("gitlab", "business_files.json") @@ -882,6 +883,10 @@ to_return(status: 200, body: gitlab_contents_response, headers: { "Content-Type" => "application/json" }) + stub_request(:get, gitlab_repo_url). + to_return(status: 200, + body: fixture("gitlab", "bump_repo.json"), + headers: { "Content-Type" => "application/json" }) stub_request(:get, gitlab_raw_changelog_url). to_return(status: 200, body: fixture("raw", "changelog.md"), @@ -893,8 +898,8 @@ context "with a bitbucket source" do let(:bitbucket_url) do - "https://api.bitbucket.org/2.0/repositories/org/business/src"\ - "?pagelen=100" + "https://api.bitbucket.org/2.0/repositories/org/business/src" \ + "?pagelen=100" end let(:bitbucket_repo_url) do "https://api.bitbucket.org/2.0/repositories/org/business" @@ -1031,8 +1036,8 @@ "https://api.github.com/repos/gocardless/business/contents/" end let(:github_upgrade_guide_url) do - "https://api.github.com/repos/gocardless/business/contents/"\ - "UPGRADE.md?ref=master" + "https://api.github.com/repos/gocardless/business/contents/" \ + "UPGRADE.md?ref=master" end let(:github_contents_response) do fixture("github", "business_files_with_upgrade_guide.json") diff --git a/common/spec/dependabot/metadata_finders/base/changelog_pruner_spec.rb b/common/spec/dependabot/metadata_finders/base/changelog_pruner_spec.rb index d232d652cdd..5b5598072e9 100644 --- a/common/spec/dependabot/metadata_finders/base/changelog_pruner_spec.rb +++ b/common/spec/dependabot/metadata_finders/base/changelog_pruner_spec.rb @@ -141,15 +141,15 @@ let(:dependency_previous_version) { "1.0.0" } let(:expected_pruned_changelog) do - "## 1.4.0 - December 24, 2014\n\n"\ - "- Add support for custom calendar load paths\n"\ - "- Remove the 'sepa' calendar\n\n\n"\ - "## 1.3.0 - December 2, 2014\n\n"\ - "- Add `Calendar#previous_business_day`\n\n\n"\ - "## 1.2.0 - November 15, 2014\n\n"\ - "- Add TARGET calendar\n\n\n"\ - "## 1.1.0 - September 30, 2014\n\n"\ - "- Add 2015 holiday definitions" + "## 1.4.0 - December 24, 2014\n\n" \ + "- Add support for custom calendar load paths\n" \ + "- Remove the 'sepa' calendar\n\n\n" \ + "## 1.3.0 - December 2, 2014\n\n" \ + "- Add `Calendar#previous_business_day`\n\n\n" \ + "## 1.2.0 - November 15, 2014\n\n" \ + "- Add TARGET calendar\n\n\n" \ + "## 1.1.0 - September 30, 2014\n\n" \ + "- Add 2015 holiday definitions" end it { is_expected.to eq(expected_pruned_changelog) } @@ -183,10 +183,10 @@ # Ideally we'd prune the 1.10.0 entry off, but it's tricky. let(:expected_pruned_changelog) do - "## 1.10.0 - September 20, 2017\n\n"\ - "- Add 2018-2019 Betalingsservice holiday definitions\n\n"\ - "## 1.11.1 - December 20, 2017\n\n"\ - "- Add 2017-2018 BECS holiday definitions" + "## 1.10.0 - September 20, 2017\n\n" \ + "- Add 2018-2019 Betalingsservice holiday definitions\n\n" \ + "## 1.11.1 - December 20, 2017\n\n" \ + "- Add 2017-2018 BECS holiday definitions" end it { is_expected.to eq(expected_pruned_changelog) } @@ -224,7 +224,7 @@ it "gets the right content" do expect(pruned_text). to eq( - "* 2.9.1\n"\ + "* 2.9.1\n" \ " * IPv6 support. Thanks https://github.com/amashinchi" ) end @@ -276,7 +276,7 @@ it "includes the changelog up to the new version" do expect(pruned_text).to start_with("## v2.2.0") expect(pruned_text).to end_with( - "Refer [here](https://github.com/actions/checkout/blob/v1/"\ + "Refer [here](https://github.com/actions/checkout/blob/v1/" \ "CHANGELOG.md) for the V1 changelog" ) end diff --git a/common/spec/dependabot/metadata_finders/base/commits_finder_spec.rb b/common/spec/dependabot/metadata_finders/base/commits_finder_spec.rb index 1194c7edd43..1896db23ccb 100644 --- a/common/spec/dependabot/metadata_finders/base/commits_finder_spec.rb +++ b/common/spec/dependabot/metadata_finders/base/commits_finder_spec.rb @@ -52,8 +52,8 @@ ) end let(:service_pack_url) do - "https://github.com/gocardless/business.git/info/refs"\ - "?service=git-upload-pack" + "https://github.com/gocardless/business.git/info/refs" \ + "?service=git-upload-pack" end let(:upload_pack_fixture) { "business" } @@ -65,7 +65,7 @@ let(:upload_pack_fixture) { "business" } it do - is_expected.to eq("https://github.com/gocardless/business/"\ + is_expected.to eq("https://github.com/gocardless/business/" \ "compare/v1.3.0...v1.4.0") end @@ -89,7 +89,7 @@ let(:dependency_previous_version) { nil } it do - is_expected.to eq("https://github.com/gocardless/business/"\ + is_expected.to eq("https://github.com/gocardless/business/" \ "compare/v1.3.0...v1.4.0") end end @@ -122,7 +122,7 @@ it "includes the directory" do expect(commits_url). to eq( - "https://github.com/gocardless/business/commits/"\ + "https://github.com/gocardless/business/commits/" \ "v1.4.0/my/directory" ) end @@ -133,7 +133,7 @@ it "joins the directory correctly" do expect(commits_url). to eq( - "https://github.com/gocardless/business/commits/"\ + "https://github.com/gocardless/business/commits/" \ "v1.4.0/my/directory" ) end @@ -159,7 +159,7 @@ end it do - is_expected.to eq("https://github.com/gocardless/business/"\ + is_expected.to eq("https://github.com/gocardless/business/" \ "commits/business-1.4") end @@ -221,7 +221,7 @@ end it do - is_expected.to eq("https://github.com/netflix/pollyjs/"\ + is_expected.to eq("https://github.com/netflix/pollyjs/" \ "commits/@pollyjs/ember@0.2.0/packages/ember") end @@ -229,7 +229,7 @@ let(:dependency_previous_version) { "0.0.3" } it do - is_expected.to eq("https://github.com/netflix/pollyjs/"\ + is_expected.to eq("https://github.com/netflix/pollyjs/" \ "commits/@pollyjs/ember@0.2.0/packages/ember") end end @@ -238,7 +238,7 @@ let(:dependency_previous_version) { "master" } it do - is_expected.to eq("https://github.com/netflix/pollyjs/"\ + is_expected.to eq("https://github.com/netflix/pollyjs/" \ "commits/@pollyjs/ember@0.2.0/packages/ember") end end @@ -253,12 +253,13 @@ end it do - is_expected.to eq("https://github.com/gocardless/business/"\ + is_expected.to eq("https://github.com/gocardless/business/" \ "commits/1.4.0") end end context "with a github repo that has a DMCA takedown notice" do + let(:url) { "https://github.com/gocardless/business.git" } before do stub_request(:get, service_pack_url). to_return( @@ -268,6 +269,10 @@ "content-type" => "application/x-git-upload-pack-advertisement" } ) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it { is_expected.to eq("https://github.com/gocardless/business/commits") } @@ -302,8 +307,8 @@ it "uses the SHA-1 hashes to build the compare URL" do expect(builder.commits_url). to eq( - "https://github.com/gocardless/business/compare/"\ - "7638417db6d59f3c431d3e1f261cc637155684cd..."\ + "https://github.com/gocardless/business/compare/" \ + "7638417db6d59f3c431d3e1f261cc637155684cd..." \ "cd8274d15fa3ae2ab983129fb037999f264ba9a7" ) end @@ -401,7 +406,7 @@ it "includes the commit in the commits URL" do expect(builder.commits_url). to eq( - "https://github.com/actions/checkout/commits/"\ + "https://github.com/actions/checkout/commits/" \ "aabbfeb2ce60b5bd82389903509092c4648a9713" ) end @@ -435,7 +440,7 @@ it "includes the previous ref and new version in the compare URL" do expect(builder.commits_url). to eq( - "https://github.com/gocardless/business/compare/"\ + "https://github.com/gocardless/business/compare/" \ "v1.1.0...v1.8.0" ) end @@ -469,7 +474,7 @@ it "includes the previous version and new commit in the compare URL" do expect(builder.commits_url). to eq( - "https://github.com/gocardless/business/compare/"\ + "https://github.com/gocardless/business/compare/" \ "v1.1.0...aabbfeb2ce60b5bd82389903509092c4648a9713" ) end @@ -480,7 +485,7 @@ it "uses the new SHA1 hash to build the compare URL" do expect(builder.commits_url). - to eq("https://github.com/gocardless/business/commits/"\ + to eq("https://github.com/gocardless/business/commits/" \ "cd8274d15fa3ae2ab983129fb037999f264ba9a7") end end @@ -494,7 +499,7 @@ it do is_expected. - to eq("https://github.com/gocardless/business/compare/"\ + to eq("https://github.com/gocardless/business/compare/" \ "7638417db6d59f3c431d3e1f261cc637155684cd...v1.4.0") end @@ -511,6 +516,13 @@ context "when authentication fails" do before do stub_request(:get, service_pack_url).to_return(status: 404) + + url = "https://github.com/gocardless/business.git" + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3). + with(anything, "git ls-remote #{url}"). + and_return(["", "", exit_status]) end it do @@ -524,7 +536,7 @@ it do is_expected. - to eq("https://github.com/gocardless/business/compare/"\ + to eq("https://github.com/gocardless/business/compare/" \ "7638417db6d59f3c431d3e1f261cc637155684cd...v1.4.0") end end @@ -556,7 +568,7 @@ # TODO: Figure out if we need to do a pinend? check here expect(builder.commits_url). to eq( - "https://github.com/gocardless/business/compare/"\ + "https://github.com/gocardless/business/compare/" \ "7638417...v1.4.0" ) end @@ -567,8 +579,11 @@ context "with a gitlab repo" do let(:service_pack_url) do - "https://gitlab.com/org/business.git/info/refs"\ - "?service=git-upload-pack" + "https://gitlab.com/org/business.git/info/refs" \ + "?service=git-upload-pack" + end + let(:gitlab_repo_url) do + "https://gitlab.com/api/v4/projects/org%2Fbusiness" end let(:source) do @@ -578,11 +593,18 @@ ) end + before do + stub_request(:get, gitlab_repo_url). + to_return(status: 200, + body: fixture("gitlab", "bump_repo.json"), + headers: { "Content-Type" => "application/json" }) + end + context "with old and new tags" do let(:dependency_previous_version) { "1.3.0" } it "gets the right URL" do - is_expected.to eq("https://gitlab.com/org/business/"\ + is_expected.to eq("https://gitlab.com/org/business/" \ "compare/v1.3.0...v1.4.0") end end @@ -607,8 +629,8 @@ context "with a bitbucket repo" do let(:service_pack_url) do - "https://bitbucket.org/org/business.git/info/refs"\ - "?service=git-upload-pack" + "https://bitbucket.org/org/business.git/info/refs" \ + "?service=git-upload-pack" end let(:source) do @@ -645,7 +667,7 @@ let(:dependency_previous_version) { "1.3.0" } it "gets the right URL" do - is_expected.to eq("https://bitbucket.org/org/business/"\ + is_expected.to eq("https://bitbucket.org/org/business/" \ "branches/compare/v1.4.0..v1.3.0") end end @@ -694,7 +716,7 @@ before do stub_request( :get, - "https://api.github.com/repos/gocardless/business/commits?"\ + "https://api.github.com/repos/gocardless/business/commits?" \ "sha=v1.3.0" ).to_return( status: 200, @@ -703,7 +725,7 @@ ) stub_request( :get, - "https://api.github.com/repos/gocardless/business/commits?"\ + "https://api.github.com/repos/gocardless/business/commits?" \ "sha=v1.4.0" ).to_return( status: 200, @@ -718,45 +740,45 @@ { message: "[12]() Remove _SEPA_ calendar (replaced by TARGET)", sha: "d2eb29beda934c14220146c82f830de2edd63a25", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "d2eb29beda934c14220146c82f830de2edd63a25" }, { - message: "Merge pull request #8 from gocardless/"\ - "rename-sepa-to-ecb\n\nRemove _SEPA_ calendar "\ - "(replaced by TARGET)", + message: "Merge pull request #8 from gocardless/" \ + "rename-sepa-to-ecb\n\nRemove _SEPA_ calendar " \ + "(replaced by TARGET)", sha: "a5970daf0b824e4c3974e57474b6cf9e39a11d0f", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "a5970daf0b824e4c3974e57474b6cf9e39a11d0f" }, { message: "Spacing: https://github.com/my/repo/pull/5", sha: "0bfb8c3f0d2701abf9248185beeb8adf643374f6", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "0bfb8c3f0d2701abf9248185beeb8adf643374f6" }, { message: "\n", sha: "5555535ff2aa9d7ce0403d7fd4aa010d94723076", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "5555535ff2aa9d7ce0403d7fd4aa010d94723076" }, { message: "Allow custom calendars", sha: "1c72c35ff2aa9d7ce0403d7fd4aa010d94723076", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "1c72c35ff2aa9d7ce0403d7fd4aa010d94723076" }, { message: "[Fix #9] Allow custom calendars", sha: "7abe4c2dc0161904c40c221a48999d12995fbea7", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "7abe4c2dc0161904c40c221a48999d12995fbea7" }, { message: "Bump version to v1.4.0", sha: "26f4887ec647493f044836363537e329d9d213aa", - html_url: "https://github.com/gocardless/business/commit/"\ + html_url: "https://github.com/gocardless/business/commit/" \ "26f4887ec647493f044836363537e329d9d213aa" } ] @@ -771,7 +793,7 @@ stub_request( :get, - "https://api.github.com/repos/gocardless/business/commits?"\ + "https://api.github.com/repos/gocardless/business/commits?" \ "sha=v1.3.0" ).to_return( status: 404, @@ -822,7 +844,7 @@ before do stub_request( :get, - "https://api.github.com/repos/netflix/pollyjs/commits?"\ + "https://api.github.com/repos/netflix/pollyjs/commits?" \ "path=packages/@pollyjs/ember&sha=@pollyjs/ember@0.2.0" ).to_return( status: 200, @@ -832,7 +854,7 @@ stub_request( :get, - "https://api.github.com/repos/netflix/pollyjs/commits?"\ + "https://api.github.com/repos/netflix/pollyjs/commits?" \ "path=packages/@pollyjs/ember&sha=@pollyjs/ember@0.1.0" ).to_return( status: 200, @@ -845,29 +867,29 @@ is_expected.to match_array( [ { - message: "feat: Custom persister support\n\n"\ - "* feat: Custom persister support\r\n\r\n"\ - "* Create a @pollyjs/persister package\r\n"\ - "* Move out shared utils into their own "\ - "@pollyjs/utils package\r\n"\ - "* Add support to register a custom persister "\ - "(same way as an adapter)\r\n"\ - "* Add more tests\r\n\r\n"\ - "* docs: Custom adapter & persister docs\r\n\r\n"\ + message: "feat: Custom persister support\n\n" \ + "* feat: Custom persister support\r\n\r\n" \ + "* Create a @pollyjs/persister package\r\n" \ + "* Move out shared utils into their own " \ + "@pollyjs/utils package\r\n" \ + "* Add support to register a custom persister " \ + "(same way as an adapter)\r\n" \ + "* Add more tests\r\n\r\n" \ + "* docs: Custom adapter & persister docs\r\n\r\n" \ "* test: Add custom persister test", sha: "8bb313cc08716b80076c6f68d056396ce4b4d282", - html_url: "https://github.com/Netflix/pollyjs/commit/"\ + html_url: "https://github.com/Netflix/pollyjs/commit/" \ "8bb313cc08716b80076c6f68d056396ce4b4d282" }, { - message: "chore: Publish\n\n"\ - " - @pollyjs/adapter@0.2.0\n"\ - " - @pollyjs/core@0.2.0\n"\ - " - @pollyjs/ember@0.2.0\n"\ - " - @pollyjs/persister@0.1.0\n"\ + message: "chore: Publish\n\n" \ + " - @pollyjs/adapter@0.2.0\n" \ + " - @pollyjs/core@0.2.0\n" \ + " - @pollyjs/ember@0.2.0\n" \ + " - @pollyjs/persister@0.1.0\n" \ " - @pollyjs/utils@0.1.0", sha: "ebf6474d0008e9e76249a78473263894dd0668dc", - html_url: "https://github.com/Netflix/pollyjs/commit/"\ + html_url: "https://github.com/Netflix/pollyjs/commit/" \ "ebf6474d0008e9e76249a78473263894dd0668dc" } ] @@ -878,8 +900,8 @@ context "with a bitbucket repo" do let(:bitbucket_compare_url) do - "https://api.bitbucket.org/2.0/repositories/org/business/commits/"\ - "?exclude=v1.3.0&include=v1.4.0" + "https://api.bitbucket.org/2.0/repositories/org/business/commits/" \ + "?exclude=v1.3.0&include=v1.4.0" end let(:bitbucket_compare) do @@ -893,8 +915,8 @@ ) end let(:service_pack_url) do - "https://bitbucket.org/org/business.git/info/refs"\ - "?service=git-upload-pack" + "https://bitbucket.org/org/business.git/info/refs" \ + "?service=git-upload-pack" end before do @@ -910,14 +932,14 @@ { message: "Added signature for changeset f275e318641f", sha: "deae742eacfa985bd20f47a12a8fee6ce2e0447c", - html_url: "https://bitbucket.org/ged/ruby-pg/commits/"\ + html_url: "https://bitbucket.org/ged/ruby-pg/commits/" \ "deae742eacfa985bd20f47a12a8fee6ce2e0447c" }, { - message: "Eliminate use of deprecated PGError constant from "\ - "specs", + message: "Eliminate use of deprecated PGError constant from " \ + "specs", sha: "f275e318641f185b8a15a2220e7c189b1769f84c", - html_url: "https://bitbucket.org/ged/ruby-pg/commits/"\ + html_url: "https://bitbucket.org/ged/ruby-pg/commits/" \ "f275e318641f185b8a15a2220e7c189b1769f84c" } ] @@ -927,12 +949,12 @@ context "with a gitlab repo" do let(:gitlab_compare_url) do - "https://gitlab.com/api/v4/projects/org%2Fbusiness/repository/"\ - "compare?from=v1.3.0&to=v1.4.0" + "https://gitlab.com/api/v4/projects/org%2Fbusiness/repository/" \ + "compare?from=v1.3.0&to=v1.4.0" end let(:service_pack_url) do - "https://gitlab.com/org/business.git/info/refs"\ - "?service=git-upload-pack" + "https://gitlab.com/org/business.git/info/refs" \ + "?service=git-upload-pack" end let(:gitlab_compare) do @@ -957,27 +979,27 @@ { message: "Add find command\n", sha: "8d7d08fb9a7a439b3e6a1e6a1a34cbdb4273de87", - html_url: "https://gitlab.com/org/business/commit/"\ + html_url: "https://gitlab.com/org/business/commit/" \ "8d7d08fb9a7a439b3e6a1e6a1a34cbdb4273de87" }, { message: "...\n", sha: "4ac81646582f254b3e86653b8fcd5eda6d8bb45d", - html_url: "https://gitlab.com/org/business/commit/"\ + html_url: "https://gitlab.com/org/business/commit/" \ "4ac81646582f254b3e86653b8fcd5eda6d8bb45d" }, { message: "MP version\n", sha: "4e5081f867631f10d8a29dc6853a052f52241fab", - html_url: "https://gitlab.com/org/business/commit/"\ + html_url: "https://gitlab.com/org/business/commit/" \ "4e5081f867631f10d8a29dc6853a052f52241fab" }, { - message: "BUG: added 'force_consistent' keyword argument "\ - "with default True\n\nThe bug fix is necessary to "\ - "pass the test turbomole_h3o2m.py.\n", + message: "BUG: added 'force_consistent' keyword argument " \ + "with default True\n\nThe bug fix is necessary to " \ + "pass the test turbomole_h3o2m.py.\n", sha: "e718899ddcdc666311d08497401199e126428163", - html_url: "https://gitlab.com/org/business/commit/"\ + html_url: "https://gitlab.com/org/business/commit/" \ "e718899ddcdc666311d08497401199e126428163" } ] @@ -1008,9 +1030,9 @@ before do response = { message: "404 Project Not Found" }.to_json gitlab_compare_url = - "https://gitlab.com/api/v4/projects/"\ - "org%2Fbusiness/repository/compare"\ - "?from=7638417db6d59f3c431d3e1f261cc637155684cd"\ + "https://gitlab.com/api/v4/projects/" \ + "org%2Fbusiness/repository/compare" \ + "?from=7638417db6d59f3c431d3e1f261cc637155684cd" \ "&to=cd8274d15fa3ae2ab983129fb037999f264ba9a7" stub_request(:get, gitlab_compare_url). to_return(status: 404, diff --git a/common/spec/dependabot/metadata_finders/base/release_finder_spec.rb b/common/spec/dependabot/metadata_finders/base/release_finder_spec.rb index ce4d88bc3ee..ea626d79aa9 100644 --- a/common/spec/dependabot/metadata_finders/base/release_finder_spec.rb +++ b/common/spec/dependabot/metadata_finders/base/release_finder_spec.rb @@ -80,6 +80,17 @@ to eq("https://dev.azure.com/saigkill/_git/hoe-manns/tags") end end + + context "with a codecommit source" do + let(:source) do + Dependabot::Source.new( + provider: "codecommit", + repo: "repos/#{dependency_name}" + ) + end + + it { is_expected.to be_nil } + end end describe "#releases_text" do @@ -87,8 +98,8 @@ context "with a github repo" do let(:github_url) do - "https://api.github.com/repos/gocardless/#{dependency_name}/"\ - "releases?per_page=100" + "https://api.github.com/repos/gocardless/#{dependency_name}/" \ + "releases?per_page=100" end let(:github_status) { 200 } @@ -112,8 +123,8 @@ it "gets the right text" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -159,8 +170,8 @@ it "gets the right text" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -174,8 +185,8 @@ it "still gets the right text" do expect(subject). to eq( - "## business-1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## business-1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -203,8 +214,8 @@ it "falls back to the tag name" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -228,16 +239,16 @@ it "falls back to the tag name" do expect(subject). to eq( - "## JasperReports 6.5.1\n"\ - "Body for 6.5.1\n"\ - "\n"\ - "## JasperReports 6.5.0\n"\ - "Body for 6.5.0\n"\ - "\n"\ - "## JasperReports 6.4.3\n"\ - "Body for 6.4.3\n"\ - "\n"\ - "## JasperReports 6.4.1\n"\ + "## JasperReports 6.5.1\n" \ + "Body for 6.5.1\n" \ + "\n" \ + "## JasperReports 6.5.0\n" \ + "Body for 6.5.0\n" \ + "\n" \ + "## JasperReports 6.4.3\n" \ + "Body for 6.4.3\n" \ + "\n" \ + "## JasperReports 6.4.1\n" \ "Body for 6.4.1" ) end @@ -250,17 +261,17 @@ it "gets the right text" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ - "- Add 2018-2027 Bankgirot holiday defintions\n"\ - "\n"\ - "## v1.7.0\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.beta\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.alpha\n"\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ + "- Add 2018-2027 Bankgirot holiday defintions\n" \ + "\n" \ + "## v1.7.0\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.beta\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.alpha\n" \ "No release notes provided." ) end @@ -277,19 +288,19 @@ it "gets the right text" do expect(subject). to eq( - "## v1.7.0\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.beta\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.alpha\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.6.0\n"\ - "Mad props to @greysteil and "\ - "[@hmarr](https://github.com/hmarr) for the "\ - "@angular/scope work - "\ + "## v1.7.0\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.beta\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.alpha\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.6.0\n" \ + "Mad props to @greysteil and " \ + "[@hmarr](https://github.com/hmarr) for the " \ + "@angular/scope work - " \ "see [changelog](CHANGELOG.md)." ) end @@ -302,23 +313,23 @@ it "uses the version number to filter the releases" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ - "- Add 2018-2027 Bankgirot holiday defintions\n"\ - "\n"\ - "## v1.7.0\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.beta\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.7.0.alpha\n"\ - "No release notes provided.\n"\ - "\n"\ - "## v1.6.0\n"\ - "Mad props to @greysteil and "\ - "[@hmarr](https://github.com/hmarr) for the "\ - "@angular/scope work - "\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ + "- Add 2018-2027 Bankgirot holiday defintions\n" \ + "\n" \ + "## v1.7.0\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.beta\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.7.0.alpha\n" \ + "No release notes provided.\n" \ + "\n" \ + "## v1.6.0\n" \ + "Mad props to @greysteil and " \ + "[@hmarr](https://github.com/hmarr) for the " \ + "@angular/scope work - " \ "see [changelog](CHANGELOG.md)." ) end @@ -427,8 +438,8 @@ it "gets the right text" do expect(subject). to eq( - "## v1.7.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## v1.7.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -442,7 +453,7 @@ it "gets the right text" do expect(subject). to eq( - "## Flurl.Http 2.4.0\n"\ + "## Flurl.Http 2.4.0\n" \ "- Improved `ConnectionLeaseTimeout` implementation (#330)" ) end @@ -481,8 +492,8 @@ it "gets the right text" do expect(subject). to eq( - "## v1.8.0\n"\ - "- Add 2018-2027 TARGET holiday defintions\n"\ + "## v1.8.0\n" \ + "- Add 2018-2027 TARGET holiday defintions\n" \ "- Add 2018-2027 Bankgirot holiday defintions" ) end @@ -524,7 +535,7 @@ it "gets the right text" do expect(subject). to eq( - "## v1.4.0\n"\ + "## v1.4.0\n" \ "Some release notes" ) end diff --git a/common/spec/dependabot/pull_request_creator/azure_spec.rb b/common/spec/dependabot/pull_request_creator/azure_spec.rb index c2db9ed6f68..1996ad7a38d 100644 --- a/common/spec/dependabot/pull_request_creator/azure_spec.rb +++ b/common/spec/dependabot/pull_request_creator/azure_spec.rb @@ -17,7 +17,10 @@ pr_description: pr_description, pr_name: pr_name, author_details: author_details, - labeler: labeler + labeler: labeler, + reviewers: reviewers, + assignees: assignees, + work_item: work_item ) end @@ -39,8 +42,8 @@ let(:pr_description) { "PR msg" } let(:pr_name) { "PR name" } let(:author_details) { nil } - let(:approvers) { nil } - let(:assignee) { nil } + let(:reviewers) { nil } + let(:assignees) { nil } let(:milestone) { nil } let(:labeler) do Dependabot::PullRequestCreator::Labeler.new( @@ -53,6 +56,7 @@ automerge_candidate: false ) end + let(:work_item) { 123 } let(:custom_labels) { nil } let(:dependency) do Dependabot::Dependency.new( @@ -122,6 +126,65 @@ to have_requested(:post, "#{repo_api_url}/pullrequests?api-version=5.0") end + context "with reviewers" do + let(:reviewers) { ["0013-0006-1980"] } + it "pushes a commit to Azure and creates a pull request with assigned reviewers" do + creator.create + + expect(WebMock). + to( + have_requested(:post, "#{repo_api_url}/pullrequests?api-version=5.0"). + with do |req| + reviewers = JSON.parse(req.body).fetch("reviewers") + expect(reviewers.count).to eq(1) + first_participant = reviewers.first + expect(first_participant.fetch("id")). + to eq("0013-0006-1980") + expect(first_participant.fetch("isRequired")). + to eq(true) + end + ) + end + end + + context "with assignees" do + let(:assignees) { ["0013-0006-1980"] } + it "pushes a commit to Azure and creates a pull request with assigned optional reviewers" do + creator.create + + expect(WebMock). + to( + have_requested(:post, "#{repo_api_url}/pullrequests?api-version=5.0"). + with do |req| + reviewers = JSON.parse(req.body).fetch("reviewers") + expect(reviewers.count).to eq(1) + first_participant = reviewers.first + expect(first_participant.fetch("id")). + to eq("0013-0006-1980") + expect(first_participant.fetch("isRequired")). + to eq(false) + end + ) + end + end + + context "with e very long pr description" do + let(:pr_description) { ("a" * 3997) + "đŸ’Ŗ kaboom" } + it "truncates the description respecting azures encoding" do + creator.create + + expect(WebMock). + to( + have_requested(:post, "#{repo_api_url}/pullrequests?api-version=5.0"). + with do |req| + description = JSON.parse(req.body).fetch("description") + expect(description.length).to eq 4000 + expect(description).to end_with("\n\n_Description has been truncated_") + end + ) + end + end + context "with author details provided" do let(:author_details) do { email: "support@dependabot.com", name: "dependabot" } @@ -179,7 +242,7 @@ stub_request( :get, "#{repo_api_url}/pullrequests?" \ - "searchCriteria.sourceRefName=refs/heads/" + branch_name + + "searchCriteria.sourceRefName=refs/heads/" + branch_name + "&searchCriteria.status=all" \ "&searchCriteria.targetRefName=refs/heads/master" ).to_return( @@ -210,7 +273,7 @@ stub_request( :get, "#{repo_api_url}/pullrequests?searchCriteria.status=all" \ - "&searchCriteria.sourceRefName=refs/heads/" + branch_name + + "&searchCriteria.sourceRefName=refs/heads/" + branch_name + "&searchCriteria.targetRefName=refs/heads/master" ).to_return( status: 200, diff --git a/common/spec/dependabot/pull_request_creator/branch_namer_spec.rb b/common/spec/dependabot/pull_request_creator/branch_namer_spec.rb index 9824e8fd45b..3b6d8b1170c 100644 --- a/common/spec/dependabot/pull_request_creator/branch_namer_spec.rb +++ b/common/spec/dependabot/pull_request_creator/branch_namer_spec.rb @@ -104,6 +104,49 @@ it { is_expected.to eq("dependabot-dummy-business-1.5.0") } end + context "with a maximum length" do + let(:namer) do + described_class.new( + dependencies: dependencies, + files: files, + target_branch: target_branch, + max_length: max_length + ) + end + + context "with a maximum length longer than branch name" do + let(:max_length) { 35 } + + it { is_expected.to eq("dependabot/dummy/business-1.5.0") } + its(:length) { is_expected.to eq(31) } + end + + context "with a maximum length shorter than branch name" do + let(:dependency_name) { "business-and-work-and-desks-and-tables-and-chairs-and-lunch" } + + context "with a maximum length longer than sha1 length" do + let(:max_length) { 50 } + + it { is_expected.to eq("dependabot#{Digest::SHA1.hexdigest("dependabot/dummy/#{dependency_name}-1.5.0")}") } + its(:length) { is_expected.to eq(50) } + end + + context "with a maximum length equal than sha1 length" do + let(:max_length) { 40 } + + it { is_expected.to eq(Digest::SHA1.hexdigest("dependabot/dummy/#{dependency_name}-1.5.0")) } + its(:length) { is_expected.to eq(40) } + end + + context "with a maximum length shorter than sha1 length" do + let(:max_length) { 20 } + + it { is_expected.to eq(Digest::SHA1.hexdigest("dependabot/dummy/#{dependency_name}-1.5.0")[0...20]) } + its(:length) { is_expected.to eq(20) } + end + end + end + context "with multiple dependencies" do let(:dependencies) { [dependency, dep2] } let(:dep2) do @@ -247,6 +290,43 @@ end end + context "with a removed transitive dependency" do + let(:dependencies) { [removed_dep, parent_dep] } + let(:removed_dep) do + Dependabot::Dependency.new( + name: "business", + version: nil, + previous_version: "1.4.0", + package_manager: "dummy", + requirements: [], + previous_requirements: [], + removed: true + ) + end + let(:parent_dep) do + Dependabot::Dependency.new( + name: "statesman", + version: "1.5.0", + previous_version: "1.4.0", + package_manager: "dummy", + requirements: [{ + file: "Gemfile", + requirement: "~> 1.5.0", + groups: [], + source: nil + }], + previous_requirements: [{ + file: "Gemfile", + requirement: "~> 1.4.0", + groups: [], + source: nil + }] + ) + end + + it { is_expected.to eq("dependabot/dummy/business-and-statesman--removed") } + end + context "with a : in the name" do let(:dependency) do Dependabot::Dependency.new( @@ -416,7 +496,7 @@ groups: [], source: { type: "digest", - digest: "sha256:18305429afa14ea462f810146ba44d4363ae76e4c8d"\ + digest: "sha256:18305429afa14ea462f810146ba44d4363ae76e4c8d" \ "fc38288cf73aa07485005" } }], @@ -426,7 +506,7 @@ groups: [], source: { type: "digest", - digest: "sha256:2167a21baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + digest: "sha256:2167a21baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ "aaaaaaaaaaaaaaaaaaaaa" } }] diff --git a/common/spec/dependabot/pull_request_creator/commit_signer_spec.rb b/common/spec/dependabot/pull_request_creator/commit_signer_spec.rb index 654fc157148..80b5f4f6420 100644 --- a/common/spec/dependabot/pull_request_creator/commit_signer_spec.rb +++ b/common/spec/dependabot/pull_request_creator/commit_signer_spec.rb @@ -30,12 +30,12 @@ subject(:signature) { signer.signature } let(:text_to_sign) do - "tree tree_sha\n"\ - "parent parent_sha\n"\ - "author dependabot 1519342187 +0000\n"\ - "committer dependabot 1519342187 +0000\n"\ - "\n"\ - "commit_message" + "tree tree_sha\n" \ + "parent parent_sha\n" \ + "author dependabot 1519342187 +0000\n" \ + "committer dependabot 1519342187 +0000\n" \ + "\n" \ + "commit_message" end it "signs the correct text, correctly" do diff --git a/common/spec/dependabot/pull_request_creator/github_spec.rb b/common/spec/dependabot/pull_request_creator/github_spec.rb index 7355c336cab..ba472aa6b09 100644 --- a/common/spec/dependabot/pull_request_creator/github_spec.rb +++ b/common/spec/dependabot/pull_request_creator/github_spec.rb @@ -120,9 +120,13 @@ to_return(status: 200, body: fixture("github", "create_label.json"), headers: json_header) + stub_request(:post, "#{repo_api_url}/git/blobs"). + to_return(status: 200, + body: fixture("github", "create_blob.json"), + headers: json_header) service_pack_url = - "https://github.com/gocardless/bump.git/info/refs"\ + "https://github.com/gocardless/bump.git/info/refs" \ "?service=git-upload-pack" stub_request(:get, service_pack_url). to_return( @@ -141,30 +145,30 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/trees"). with(body: { - base_tree: "basecommitsha", - tree: [ - { - path: "Gemfile", - mode: "100644", - type: "blob", - content: fixture("ruby", "gemfiles", "Gemfile") - }, - { - path: "Gemfile.lock", - mode: "100644", - type: "blob", - content: fixture("ruby", "gemfiles", "Gemfile") - } - ] - }) + base_tree: "basecommitsha", + tree: [ + { + path: "Gemfile", + mode: "100644", + type: "blob", + content: fixture("ruby", "gemfiles", "Gemfile") + }, + { + path: "Gemfile.lock", + mode: "100644", + type: "blob", + content: fixture("ruby", "gemfiles", "Gemfile") + } + ] + }) expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/commits"). with(body: { - parents: ["basecommitsha"], - tree: "cd8274d15fa3ae2ab983129fb037999f264ba9a7", - message: "Commit msg" - }) + parents: ["basecommitsha"], + tree: "cd8274d15fa3ae2ab983129fb037999f264ba9a7", + message: "Commit msg" + }) end context "with a submodule" do @@ -184,14 +188,14 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/trees"). with(body: { - base_tree: "basecommitsha", - tree: [{ - path: "manifesto", - mode: "160000", - type: "commit", - sha: "sha1" - }] - }) + base_tree: "basecommitsha", + tree: [{ + path: "manifesto", + mode: "160000", + type: "commit", + sha: "sha1" + }] + }) expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/commits") @@ -216,14 +220,93 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/trees"). with(body: { - base_tree: "basecommitsha", - tree: [{ - path: "nested/manifesto", - mode: "100644", - type: "blob", - content: "codes" - }] - }) + base_tree: "basecommitsha", + tree: [{ + path: "nested/manifesto", + mode: "100644", + type: "blob", + content: "codes" + }] + }) + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/git/commits") + end + end + + context "with a binary file" do + let(:gem_content) do + Base64.encode64(fixture("ruby", "gems", "addressable-2.7.0.gem")) + end + + let(:files) do + [ + Dependabot::DependencyFile.new( + name: "addressable-2.7.0.gem", + directory: "vendor/cache", + content: gem_content, + content_encoding: + Dependabot::DependencyFile::ContentEncoding::BASE64 + ) + ] + end + let(:sha) { "3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15" } + + it "creates a git blob and pushes a commit to GitHub" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/git/blobs"). + with(body: { + content: gem_content, + encoding: "base64" + }) + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/git/trees"). + with(body: { + base_tree: "basecommitsha", + tree: [{ + path: "vendor/cache/addressable-2.7.0.gem", + mode: "100644", + type: "blob", + sha: sha + }] + }) + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/git/commits") + end + end + + context "with a deleted file" do + let(:files) do + [ + Dependabot::DependencyFile.new( + name: "addressable-2.7.0.gem", + directory: "vendor/cache", + content: nil, + operation: Dependabot::DependencyFile::Operation::DELETE, + content_encoding: + Dependabot::DependencyFile::ContentEncoding::BASE64 + ) + ] + end + + it "pushes a commit to GitHub" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/git/trees"). + with(body: { + base_tree: "basecommitsha", + tree: [{ + path: "vendor/cache/addressable-2.7.0.gem", + mode: "100644", + type: "blob", + sha: nil + }] + }) expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/commits") @@ -242,7 +325,7 @@ headers: json_header) service_pack_url = - "https://github.com/gocardless/bump.git/info/refs"\ + "https://github.com/gocardless/bump.git/info/refs" \ "?service=git-upload-pack" stub_request(:get, service_pack_url).to_return(status: 404) end @@ -255,10 +338,14 @@ context "when we got a 401" do before do - service_pack_url = - "https://github.com/gocardless/bump.git/info/refs"\ - "?service=git-upload-pack" + url = "https://github.com/gocardless/bump.git" + service_pack_url = "#{url}/info/refs?service=git-upload-pack" + stub_request(:get, service_pack_url).to_return(status: 401) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it "raises a normal error" do @@ -273,10 +360,14 @@ body: fixture("github", "bump_repo.json"), headers: json_header) - service_pack_url = - "https://github.com/gocardless/bump.git/info/refs"\ - "?service=git-upload-pack" + url = "https://github.com/gocardless/bump.git" + service_pack_url = "#{url}/info/refs?service=git-upload-pack" + stub_request(:get, service_pack_url).to_return(status: 404) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it "raises a normal error" do @@ -286,15 +377,19 @@ context "when the repo exists but is disabled" do before do - service_pack_url = - "https://github.com/gocardless/bump.git/info/refs"\ - "?service=git-upload-pack" + url = "https://github.com/gocardless/bump.git" + service_pack_url = "#{url}/info/refs?service=git-upload-pack" + stub_request(:get, service_pack_url). to_return( status: 403, - body: "Account `gocardless' is disabled. Please ask the owner to "\ + body: "Account `gocardless' is disabled. Please ask the owner to " \ "check their account." ) + + exit_status = double(success?: false) + allow(Open3).to receive(:capture3).and_call_original + allow(Open3).to receive(:capture3).with(anything, "git ls-remote #{url}").and_return(["", "", exit_status]) end it "raises a helpful error" do @@ -375,7 +470,7 @@ context "but a PR to this branch doesn't" do before do - url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}"\ + url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}" \ "&state=all" stub_request(:get, url). to_return(status: 200, body: "[]", headers: json_header) @@ -407,7 +502,7 @@ context "and a PR to this branch already exists" do before do - url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}"\ + url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}" \ "&state=all" stub_request(:get, url). to_return(status: 200, body: "[{}]", headers: json_header) @@ -420,7 +515,7 @@ context "but isn't initially returned (a race)" do before do - url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}"\ + url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}" \ "&state=all" stub_request(:get, url). to_return(status: 200, body: "[]", headers: json_header) @@ -448,7 +543,7 @@ context "but is merged" do before do - url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}"\ + url = "#{repo_api_url}/pulls?head=gocardless:#{branch_name}" \ "&state=all" stub_request(:get, url).to_return( status: 200, @@ -559,25 +654,25 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/commits"). with(body: { - parents: anything, - tree: anything, - message: anything, - author: { email: "support@dependabot.com", name: "dependabot" } - }) + parents: anything, + tree: anything, + message: anything, + author: { email: "support@dependabot.com", name: "dependabot" } + }) end context "with a signature key" do let(:signature_key) { fixture("keys", "pgp.key") } let(:public_key) { fixture("keys", "pgp.pub") } let(:text_to_sign) do - "tree cd8274d15fa3ae2ab983129fb037999f264ba9a7\n"\ - "parent basecommitsha\n"\ - "author dependabot 978307200 +0000\n"\ - "committer dependabot 978307200 +0000\n"\ - "\n"\ - "Commit msg" + "tree cd8274d15fa3ae2ab983129fb037999f264ba9a7\n" \ + "parent basecommitsha\n" \ + "author dependabot 978307200 +0000\n" \ + "committer dependabot 978307200 +0000\n" \ + "\n" \ + "Commit msg" end - before { allow(Time).to receive(:now).and_return(Time.new(2001, 1, 1)) } + before { allow(Time).to receive(:now).and_return(Time.new(2001, 1, 1, 0, 0, 0, "+00:00")) } it "passes the author details and signature to GitHub" do creator.create @@ -634,9 +729,9 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/git/refs"). with(body: { - ref: "refs/heads/dependabot/bundler/business-1.5.0", - sha: "7638417db6d59f3c431d3e1f261cc637155684cd" - }) + ref: "refs/heads/dependabot/bundler/business-1.5.0", + sha: "7638417db6d59f3c431d3e1f261cc637155684cd" + }) end it "creates a PR with the right details" do @@ -847,16 +942,16 @@ stub_request(:post, "#{repo_api_url}/issues/1347/comments") end let(:expected_comment_body) do - "Dependabot tried to add `@greysteil` as a reviewer to this PR, "\ - "but received the following error from GitHub:\n\n"\ - "```\n"\ - "POST https://api.github.com/repos/gocardless/bump/pulls"\ - "/1347/requested_reviewers: 422 - Reviews may only be requested "\ - "from collaborators. One or more of the users or teams you "\ - "specified is not a collaborator of the example/repo repository. "\ - "// See: https://developer.github.com/v3/pulls/review_requests/"\ - "#create-a-review-request\n"\ - "```" + "Dependabot tried to add `@greysteil` as a reviewer to this PR, " \ + "but received the following error from GitHub:\n\n" \ + "```\n" \ + "POST https://api.github.com/repos/gocardless/bump/pulls" \ + "/1347/requested_reviewers: 422 - Reviews may only be requested " \ + "from collaborators. One or more of the users or teams you " \ + "specified is not a collaborator of the example/repo repository. " \ + "// See: https://developer.github.com/v3/pulls/review_requests/" \ + "#create-a-review-request\n" \ + "```" end it "comments on the PR with details of the failure" do @@ -938,5 +1033,80 @@ end end end + + context "when labelling fails" do + context "with internal server error" do + before do + stub_request(:post, "#{repo_api_url}/issues/1347/labels"). + to_return(status: 500, + body: "{}", + headers: json_header) + end + + it "raises helpful error" do + msg = "POST https://api.github.com/repos/gocardless/bump/issues/" \ + "1347/labels: 500 - " + expect { creator.create }.to raise_error( + (an_instance_of(Dependabot::PullRequestCreator::AnnotationError). + and having_attributes(message: msg). + and having_attributes( + cause: an_instance_of(Octokit::InternalServerError) + ). + and having_attributes( + pull_request: having_attributes(number: 1347) + ) + ) + ) + end + end + + context "with disabled account error" do + before do + stub_request(:post, "#{repo_api_url}/issues/1347/labels"). + to_return(status: 403, + body: '{"error":"Account `gocardless\' is disabled. ' \ + 'Please ask the owner to check their account."}', + headers: json_header) + end + + it "raises helpful error" do + msg = "POST https://api.github.com/repos/gocardless/bump/issues/" \ + "1347/labels: 403 - Error: Account `gocardless' is disabled. " \ + "Please ask the owner to check their account." + expect { creator.create }.to raise_error( + (an_instance_of(Dependabot::PullRequestCreator::AnnotationError). + and having_attributes(message: msg). + and having_attributes( + cause: an_instance_of( + Dependabot::PullRequestCreator::RepoDisabled + ) + ). + and having_attributes( + pull_request: having_attributes(number: 1347) + ) + ) + ) + end + end + + context "the PR description is too long" do + let(:pr_description) { "a" * (described_class::MAX_PR_DESCRIPTION_LENGTH + 1) } + + it "truncates the description" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/pulls"). + with( + body: { + base: "master", + head: "dependabot/bundler/business-1.5.0", + title: "PR name", + body: ->(body) { expect(body.length).to be <= described_class::MAX_PR_DESCRIPTION_LENGTH } + } + ) + end + end + end end end diff --git a/common/spec/dependabot/pull_request_creator/gitlab_spec.rb b/common/spec/dependabot/pull_request_creator/gitlab_spec.rb index d775e407b37..4a376eb9a48 100644 --- a/common/spec/dependabot/pull_request_creator/gitlab_spec.rb +++ b/common/spec/dependabot/pull_request_creator/gitlab_spec.rb @@ -20,7 +20,8 @@ labeler: labeler, approvers: approvers, assignees: assignees, - milestone: milestone + milestone: milestone, + target_project_id: target_project_id ) end @@ -37,7 +38,7 @@ "password" => "token" }] end - let(:files) { [gemfile, gemfile_lock] } + let(:files) { [gemfile, gemfile_lock, created_file, deleted_file] } let(:commit_message) { "Commit msg" } let(:pr_description) { "PR msg" } let(:pr_name) { "PR name" } @@ -45,6 +46,7 @@ let(:approvers) { nil } let(:assignees) { nil } let(:milestone) { nil } + let(:target_project_id) { nil } let(:labeler) do Dependabot::PullRequestCreator::Labeler.new( source: source, @@ -80,6 +82,20 @@ content: fixture("ruby", "gemfiles", "Gemfile") ) end + let(:created_file) do + Dependabot::DependencyFile.new( + name: "created-file", + content: "created", + operation: Dependabot::DependencyFile::Operation::CREATE + ) + end + let(:deleted_file) do + Dependabot::DependencyFile.new( + name: "deleted-file", + content: nil, + operation: Dependabot::DependencyFile::Operation::DELETE + ) + end let(:json_header) { { "Content-Type" => "application/json" } } let(:repo_api_url) do @@ -123,11 +139,68 @@ creator.create expect(WebMock). - to have_requested(:post, "#{repo_api_url}/repository/commits") + to have_requested(:post, "#{repo_api_url}/repository/commits"). + with( + body: { + branch: branch_name, + commit_message: commit_message, + actions: [ + { + action: "update", + file_path: gemfile.path, + content: gemfile.content + }, + { + action: "update", + file_path: gemfile_lock.path, + content: gemfile_lock.content + }, + { + action: "create", + file_path: created_file.path, + content: created_file.content + }, + { + action: "delete", + file_path: deleted_file.path, + content: "" + } + ] + } + ) + expect(WebMock). to have_requested(:post, "#{repo_api_url}/merge_requests") end + context "with reviewers" do + let(:approvers) { { "reviewers" => [1_394_555] } } + + it "pushes a commit to GitLab and creates a merge request with assigned reviewers" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/merge_requests"). + with( + body: a_string_including("reviewer_ids%5B%5D=#{approvers['reviewers'].first}") + ) + end + end + + context "with forked project" do + let(:target_project_id) { 1 } + + it "pushes a commit to GitLab and creates a merge request in upstream project" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{repo_api_url}/merge_requests"). + with( + body: a_string_including("target_project_id=#{target_project_id}") + ) + end + end + context "with a submodule" do let(:files) do [ @@ -180,7 +253,21 @@ creator.create expect(WebMock). - to have_requested(:post, "#{repo_api_url}/repository/commits") + to have_requested(:post, "#{repo_api_url}/repository/commits"). + with( + body: { + branch: branch_name, + commit_message: commit_message, + actions: [ + { + action: "update", + file_path: files[0].symlink_target, + content: files[0].content + } + ] + } + ) + expect(WebMock). to have_requested(:post, "#{repo_api_url}/merge_requests") end @@ -274,8 +361,12 @@ context "when a approvers has been requested" do let(:approvers) { { "approvers" => [1_394_555] } } + let(:mr_api_url) do + "https://gitlab.com/api/v4/projects/#{target_project_id || CGI.escape(source.repo)}/merge_requests" + end + before do - stub_request(:put, "#{repo_api_url}/merge_requests/5/approvers"). + stub_request(:post, "#{mr_api_url}/5/approval_rules"). to_return( status: 200, body: fixture("gitlab", "merge_request.json"), @@ -287,7 +378,30 @@ creator.create expect(WebMock). - to have_requested(:put, "#{repo_api_url}/merge_requests/5/approvers") + to have_requested(:post, "#{mr_api_url}/5/approval_rules"). + with(body: { + name: "dependency-updates", + approvals_required: 1, + user_ids: approvers["approvers"], + group_ids: "" + }) + end + + context "with forked project" do + let(:target_project_id) { 1 } + + it "adds the approvers to upstream project MR" do + creator.create + + expect(WebMock). + to have_requested(:post, "#{mr_api_url}/5/approval_rules"). + with(body: { + name: "dependency-updates", + approvals_required: 1, + user_ids: approvers["approvers"], + group_ids: "" + }) + end end end end diff --git a/common/spec/dependabot/pull_request_creator/labeler_spec.rb b/common/spec/dependabot/pull_request_creator/labeler_spec.rb index 3d98f489e6a..bf727e3fa46 100644 --- a/common/spec/dependabot/pull_request_creator/labeler_spec.rb +++ b/common/spec/dependabot/pull_request_creator/labeler_spec.rb @@ -228,6 +228,39 @@ to_not have_requested(:post, "#{repo_api_url}/labels") end end + + context "when the 'github_actions' label doesn't yet exist" do + before do + allow(described_class).to receive(:label_details_for_package_manager). + with("github_actions"). + and_return({ + colour: "000000", + name: "github_actions", + description: "Pull requests that update GitHub Actions code" + }) + allow(dependency).to receive(:package_manager).and_return("github_actions") + + stub_request(:get, "https://api.github.com/repos/#{source.repo}/labels?per_page=100"). + to_return(status: 200, headers: { "Content-Type" => "application/json" }, body: JSON.generate([])) + stub_request(:post, "https://api.github.com/repos/#{source.repo}/labels"). + to_return( + status: 201, + headers: { "Content-Type" => "application/json" }, + body: JSON.generate({ id: 1, name: "github_actions", color: "000000" }) + ) + end + + it "creates a label" do + labeler.create_default_labels_if_required + + expect(WebMock).to have_requested(:post, "https://api.github.com/repos/#{source.repo}/labels"). + with(body: { + name: "github_actions", + color: "000000", + description: "Pull requests that update GitHub Actions code" + }) + end + end end context "when a custom dependencies label has been requested" do @@ -281,7 +314,7 @@ body: { name: "security", color: "ee0701", - description: "Pull requests that address a security "\ + description: "Pull requests that address a security " \ "vulnerability" } ) @@ -337,7 +370,7 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/labels"). with( - body: "description=Pull%20requests%20that%20update%20a"\ + body: "description=Pull%20requests%20that%20update%20a" \ "%20dependency%20file&name=dependencies&color=%230366d6" ) expect(labeler.labels_for_pr).to include("dependencies") @@ -399,8 +432,8 @@ expect(WebMock). to have_requested(:post, "#{repo_api_url}/labels"). with( - body: "description=Pull%20requests%20that%20address%20a"\ - "%20security%20vulnerability&name=security&color=%23ee0701" + body: "description=Pull%20requests%20that%20address%20a" \ + "%20security%20vulnerability&name=security&color=%23ee0701" ) expect(labeler.labels_for_pr).to include("security") end @@ -698,7 +731,7 @@ let(:pagination_header) do { "Content-Type" => "application/json", - "Link" => "<#{repo_api_url}/labels?page=2&per_page=100>; "\ + "Link" => "<#{repo_api_url}/labels?page=2&per_page=100>; " \ "rel=\"next\"" } end diff --git a/common/spec/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer_spec.rb b/common/spec/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer_spec.rb index ade5932298f..fb8614d8dbc 100644 --- a/common/spec/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer_spec.rb +++ b/common/spec/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer_spec.rb @@ -1,11 +1,10 @@ # frozen_string_literal: true require "spec_helper" -require "dependabot/pull_request_creator/message_builder/"\ +require "dependabot/pull_request_creator/message_builder/" \ "link_and_mention_sanitizer" -namespace = Dependabot::PullRequestCreator::MessageBuilder -RSpec.describe namespace::LinkAndMentionSanitizer do +RSpec.describe Dependabot::PullRequestCreator::MessageBuilder::LinkAndMentionSanitizer do subject(:sanitizer) do described_class.new(github_redirection_service: github_redirection_service) end @@ -21,8 +20,8 @@ it "sanitizes the text" do expect(sanitize_links_and_mentions). - to eq("

Great work "\ - "@greysteil!

\n") + to eq("

Great work " \ + "@\u200Bgreysteil!

\n") end context "that includes a dash" do @@ -30,24 +29,19 @@ it "sanitizes the text" do expect(sanitize_links_and_mentions).to eq( - "

Great work "\ - "@greysteil-work!

\n" + "

Great work " \ + "@\u200Bgreysteil-work!

\n" ) end end - context "that includes a slash" do - let(:text) { "Great work on @greysteil/repo!" } - it { is_expected.to eq("

Great work on @greysteil/repo!

\n") } - end - context "that is in brackets" do let(:text) { "The team (by @greysteil) etc." } it "sanitizes the text" do expect(sanitize_links_and_mentions).to eq( - "

The team (by "\ - "@greysteil) etc.

\n" + "

The team (by " \ + "@\u200Bgreysteil) etc.

\n" ) end end @@ -57,7 +51,7 @@ it "sanitizes the text" do expect(sanitize_links_and_mentions).to eq( - "

[@hmarr]

\n" + "

[@\u200Bhmarr]

\n" ) end end @@ -67,8 +61,8 @@ it "sanitizes the mention" do expect(sanitize_links_and_mentions).to eq( - "

@hmarr "\ - "@feelepxyz

\n" + "

@\u200Bhmarr " \ + "@\u200Bfeelepxyz

\n" ) end end @@ -87,7 +81,7 @@ let(:text) { fixture("changelogs", "sentry.md") } it do is_expected.to include( - "@halkeye" + "@\u200Bhalkeye" ) end end @@ -107,15 +101,15 @@ context "with a mention before" do let(:text) do - "@greysteil wrote this:\n\n```\n @model ||= 123\n```\n\n"\ - "Review by @hmarr!" + "@greysteil wrote this:\n\n```\n @model ||= 123\n```\n\n" \ + "Review by @hmarr!" end it "sanitizes the text" do expect(sanitize_links_and_mentions).to eq( - "

@greysteil "\ - "wrote this:

\n
 @model ||= 123\n
\n

"\ - "Review by @hmarr!"\ + "

@\u200Bgreysteil " \ + "wrote this:

\n
 @model ||= 123\n
\n

" \ + "Review by @\u200Bhmarr!" \ "

\n" ) end @@ -128,10 +122,10 @@ it "sanitizes the mention" do expect(sanitize_links_and_mentions).to eq( - "

@command\nThanks to "\ - "@feelepxyz"\ - "@other "\ - "@escape

\n" + "

@command\nThanks to " \ + "@\u200Bfeelepxyz" \ + "@other " \ + "@\u200Bescape

\n" ) end end @@ -141,36 +135,36 @@ it "sanitizes the mention" do expect(sanitize_links_and_mentions).to eq( - "

@command \n @test "\ - "@feelepxyz

\n" + "

@command \n @test " \ + "@\u200Bfeelepxyz

\n" ) end end context "with mentions inside a complex code fence" do let(:text) do - "Take a look at this code: ```` @not-a-mention "\ - "```@not-a-mention``` ````" + "Take a look at this code: ```` @not-a-mention " \ + "```@not-a-mention``` ````" end it "sanitizes the text without touching the code fence" do expect(sanitize_links_and_mentions).to eq( - "

Take a look at this code: @not-a-mention "\ + "

Take a look at this code: @not-a-mention " \ "```@not-a-mention```

\n" ) end context "and a real mention after" do let(:text) do - "Take a look at this code: ```` @not-a-mention "\ - "```@not-a-mention``` ```` This is a @mention!" + "Take a look at this code: ```` @not-a-mention " \ + "```@not-a-mention``` ```` This is a @mention!" end it "sanitizes the text without touching the code fence" do expect(sanitize_links_and_mentions).to eq( - "

Take a look at this code: @not-a-mention "\ - "```@not-a-mention``` This is a "\ - "@mention!

\n" + "

Take a look at this code: @not-a-mention " \ + "```@not-a-mention``` This is a " \ + "@\u200Bmention!

\n" ) end end @@ -181,9 +175,9 @@ it "sanitizes the mention" do expect(sanitize_links_and_mentions).to eq( - "

@command

\n
@test\n"\
-              "
\n"\ - "

@feelepxyz

\n" + "

@command

\n
@test\n" \
+              "
\n" \ + "

@\u200Bfeelepxyz

\n" ) end end @@ -193,13 +187,43 @@ it "sanitizes the mentions" do expect(sanitize_links_and_mentions).to eq( - "

@command "\ - "``` "\ - "@feelepxyz

\n" + "

@\u200Bcommand " \ + "``` " \ + "@\u200Bfeelepxyz

\n" ) end end end + + context "team mentions" do + let(:text) { "Thanks @dependabot/reviewers" } + + it "sanitizes the team mention" do + expect(sanitize_links_and_mentions).to eq( + "

Thanks @\u200Bdependabot/reviewers

\n" + ) + end + end + + context "multiple team mentions" do + let(:text) { "Thanks @dependabot/reviewers @dependabot/developers" } + + it "sanitizes the team mentions" do + expect(sanitize_links_and_mentions).to eq( + "

Thanks @\u200Bdependabot/reviewers @\u200Bdependabot/developers

\n" + ) + end + end + + context "team mention and non-mention line" do + let(:text) { "Thanks @dependabot/reviewers\n\nAnd more regular text" } + + it "sanitizes the team mention" do + expect(sanitize_links_and_mentions).to eq( + "

Thanks @\u200Bdependabot/reviewers

\n

And more regular text

\n" + ) + end + end end context "with empty text" do @@ -216,7 +240,7 @@ let(:text) { "Contact support@dependabot.com for details" } it do is_expected.to eq( - "

Contact "\ + "

Contact " \ "support@dependabot.com for details

\n" ) end @@ -227,7 +251,18 @@ it do is_expected.to eq( - "

Check out Check out my/repo#5

\n" + ) + end + end + + context "with a GitHub link including www" do + let(:text) { "Check out https://www.github.com/my/repo/issues/5" } + + it do + is_expected.to eq( + "

Check out my/repo#5

\n" ) end @@ -240,12 +275,23 @@ it do is_expected.to eq( - "

rust-num/num-traits#144

\n" ) end end + context "with a GitHub NWO and PR number" do + let(:text) do + "dsp-testing/dependabot-ts-definitely-typed#25" + end + it do + is_expected.to eq( + "

dsp-testing/dependabot-ts-definitely-typed#25

\n" + ) + end + end + context "with a GitHub link in rdoc" do let(:text) do "{Issue 111}[https://github.com/dependabot/dependabot-core/issues/111]" @@ -253,8 +299,8 @@ it do is_expected.to eq( - "

{Issue 111}[https://github-redirect.com/dependabot/"\ - "dependabot-core/issues/111\]

\n" + "

{Issue 111}[https://github-redirect.com/dependabot/" \ + "dependabot-core/issues/111]

\n" ) end end @@ -266,7 +312,7 @@ it do is_expected.to eq( - "

"\ + "

" \ "https://github.com/rust-num/num-traits/settings

\n" ) end @@ -274,13 +320,13 @@ context "with a markdown footer" do let(:text) do - "[Updated the `libm` dependency to 0.2][144]\n\n"\ - "[144]: https://github.com/rust-num/num-traits/pull/144" + "[Updated the `libm` dependency to 0.2][144]\n\n" \ + "[144]: https://github.com/rust-num/num-traits/pull/144" end it do is_expected.to eq( - "

Updated the libm dependency to 0.2

\n" ) end @@ -293,7 +339,7 @@ it do is_expected.to eq( - "

\n#144\n

\n" ) end @@ -312,7 +358,7 @@ let(:text) { "This contains \"