Skip to content

Unexpected differences between the new Gemfile.lock and the one generated by the existing Bundler #2

@TaKO8Ki

Description

@TaKO8Ki

Gemfile:

gem 'google-cloud-artifact_registry-v1', '~> 0.11.0'

Differences:

-    googleapis-common-protos (1.8.0)
+    googleapis-common-protos (1.7.0)
      google-protobuf (>= 3.18, < 5.a)
-      googleapis-common-protos-types (~> 1.20)
+      googleapis-common-protos-types (~> 1.7)
      grpc (~> 1.41)
    googleapis-common-protos-types (1.20.0)
      google-protobuf (>= 3.18, < 5.a)
    googleauth (1.14.0)
      faraday (>= 1.0, < 3.a)
      google-cloud-env (~> 2.2)
      google-logging-utils (~> 0.1)
      jwt (>= 1.4, < 3.0)
      multi_json (~> 1.11)
      os (>= 0.9, < 2.0)
      signet (>= 0.16, < 2.a)
    grpc (1.71.0)
      google-protobuf (>= 3.25, < 5.0)
      googleapis-common-protos-types (~> 1.0)
-    grpc-google-iam-v1 (1.10.0)
+    grpc-google-iam-v1 (1.11.0)
      google-protobuf (>= 3.18, < 5.a)
-      googleapis-common-protos (~> 1.4)
+      googleapis-common-protos (~> 1.7.0)
Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    addressable (2.8.7)
      public_suffix (>= 2.0.2, < 7.0)
    base64 (0.2.0)
    bigdecimal (3.1.9)
    faraday (2.13.1)
      faraday-net_http (>= 2.0, < 3.5)
      json
      logger
    faraday-net_http (3.4.0)
      net-http (>= 0.5.0)
    faraday-retry (2.3.1)
      faraday (~> 2.0)
    gapic-common (1.0.0)
      faraday (>= 1.9, < 3.a)
      faraday-retry (>= 1.0, < 3.a)
      google-cloud-env (~> 2.2)
      google-logging-utils (~> 0.1)
      google-protobuf (>= 3.25, < 5.a)
      googleapis-common-protos (~> 1.6)
      googleapis-common-protos-types (~> 1.15)
      googleauth (~> 1.12)
      grpc (~> 1.66)
    google-cloud-artifact_registry-v1 (0.11.0)
      gapic-common (>= 0.20.0, < 2.a)
      google-cloud-errors (~> 1.0)
      google-cloud-location (>= 0.4, < 2.a)
      grpc-google-iam-v1 (~> 1.1)
    google-cloud-env (2.3.0)
      base64 (~> 0.2)
      faraday (>= 1.0, < 3.a)
    google-cloud-errors (1.5.0)
    google-cloud-location (1.0.0)
      gapic-common (>= 0.25.0, < 2.a)
      google-cloud-errors (~> 1.0)
    google-logging-utils (0.2.0)
    google-protobuf (4.30.2)
      bigdecimal
      rake (>= 13)
    googleapis-common-protos (1.7.0)
      google-protobuf (>= 3.18, < 5.a)
      googleapis-common-protos-types (~> 1.7)
      grpc (~> 1.41)
    googleapis-common-protos-types (1.20.0)
      google-protobuf (>= 3.18, < 5.a)
    googleauth (1.14.0)
      faraday (>= 1.0, < 3.a)
      google-cloud-env (~> 2.2)
      google-logging-utils (~> 0.1)
      jwt (>= 1.4, < 3.0)
      multi_json (~> 1.11)
      os (>= 0.9, < 2.0)
      signet (>= 0.16, < 2.a)
    grpc (1.71.0)
      google-protobuf (>= 3.25, < 5.0)
      googleapis-common-protos-types (~> 1.0)
    grpc-google-iam-v1 (1.11.0)
      google-protobuf (>= 3.18, < 5.a)
      googleapis-common-protos (~> 1.7.0)
      grpc (~> 1.41)
    json (2.11.3)
    jwt (2.10.1)
      base64
    logger (1.7.0)
    multi_json (1.15.0)
    net-http (0.6.0)
      uri
    os (1.1.4)
    public_suffix (6.0.2)
    rake (13.2.1)
    signet (0.20.0)
      addressable (~> 2.8)
      faraday (>= 0.17.5, < 3.a)
      jwt (>= 1.5, < 3.0)
      multi_json (~> 1.10)
    uri (1.0.3)

PLATFORMS
  ruby

DEPENDENCIES
  google-cloud-artifact_registry-v1 (~> 0.11.0)

BUNDLED WITH
   2.5.22
Gemfile.new.lock
GEM
  remote: https://rubygems.org/
  specs:
    addressable (2.8.7)
      public_suffix (>= 2.0.2, < 7.0)
    base64 (0.2.0)
    bigdecimal (3.1.9)
    faraday (2.13.1)
      faraday-net_http (>= 2.0, < 3.5)
      json
      logger
    faraday-net_http (3.4.0)
      net-http (>= 0.5.0)
    faraday-retry (2.3.1)
      faraday (~> 2.0)
    gapic-common (1.0.0)
      faraday (>= 1.9, < 3.a)
      faraday-retry (>= 1.0, < 3.a)
      google-cloud-env (~> 2.2)
      google-logging-utils (~> 0.1)
      google-protobuf (>= 3.25, < 5.a)
      googleapis-common-protos (~> 1.6)
      googleapis-common-protos-types (~> 1.15)
      googleauth (~> 1.12)
      grpc (~> 1.66)
    google-cloud-artifact_registry-v1 (0.11.0)
      gapic-common (>= 0.20.0, < 2.a)
      google-cloud-errors (~> 1.0)
      google-cloud-location (>= 0.4, < 2.a)
      grpc-google-iam-v1 (~> 1.1)
    google-cloud-env (2.3.0)
      base64 (~> 0.2)
      faraday (>= 1.0, < 3.a)
    google-cloud-errors (1.5.0)
    google-cloud-location (1.0.0)
      gapic-common (>= 0.25.0, < 2.a)
      google-cloud-errors (~> 1.0)
    google-logging-utils (0.2.0)
    google-protobuf (4.30.2)
      bigdecimal
      rake (>= 13)
    googleapis-common-protos (1.8.0)
      google-protobuf (>= 3.18, < 5.a)
      googleapis-common-protos-types (~> 1.20)
      grpc (~> 1.41)
    googleapis-common-protos-types (1.20.0)
      google-protobuf (>= 3.18, < 5.a)
    googleauth (1.14.0)
      faraday (>= 1.0, < 3.a)
      google-cloud-env (~> 2.2)
      google-logging-utils (~> 0.1)
      jwt (>= 1.4, < 3.0)
      multi_json (~> 1.11)
      os (>= 0.9, < 2.0)
      signet (>= 0.16, < 2.a)
    grpc (1.71.0)
      google-protobuf (>= 3.25, < 5.0)
      googleapis-common-protos-types (~> 1.0)
    grpc-google-iam-v1 (1.10.0)
      google-protobuf (>= 3.18, < 5.a)
      googleapis-common-protos (~> 1.4)
      grpc (~> 1.41)
    json (2.11.3)
    jwt (2.10.1)
      base64
    logger (1.7.0)
    multi_json (1.15.0)
    net-http (0.6.0)
      uri
    os (1.1.4)
    public_suffix (6.0.2)
    rake (13.2.1)
    signet (0.20.0)
      addressable (~> 2.8)
      faraday (>= 0.17.5, < 3.a)
      jwt (>= 1.5, < 3.0)
      multi_json (~> 1.10)
    uri (1.0.3)

PLATFORMS
  ruby

DEPENDENCIES
  google-cloud-artifact_registry-v1 (~> 0.11.0)

BUNDLED WITH
   2.5.22

Investigation

In the case that the dependencies include grpc-google-iam-v1 @ 1.8.0, 1.10.0 is selected. However, Ruby bundler selects 1.11.0 with that Gemfile.

The reason why version 1.10.0 is selected when version 1.8.0 is added is probably that PubGrub doesn't simply choose the latest version, but considers the 'flexibility' of the entire dependency graph. The dependency constraint provided by 1.10.0 (googleapis-common-protos > 1.4) is broader than the constraint of 1.11.0 (> 1.7.0), which means it potentially has higher compatibility with other packages.

Test code
>
    #[test]
    fn bundler_like_resolution() {
        struct BundlerOfflineDependencyProvider {
            dependency_provider: OfflineDependencyProvider<String, RichReq>,
        }

        impl BundlerOfflineDependencyProvider {
            fn add_dependencies(
                &mut self,
                package: String,
                version: RubyVersion,
                dependencies: Vec<(String, RichReq)>,
            ) {
                self.dependency_provider
                    .add_dependencies(package, version, dependencies);
            }
        }

        impl DependencyProvider for BundlerOfflineDependencyProvider {
            type P = String;
            type V = <RichReq as VersionSet>::V;
            type VS = RichReq;
            type M = String;

            type Err = Infallible;

            #[inline]
            fn choose_version(
                &self,
                package: &Self::P,
                range: &Self::VS,
            ) -> Result<Option<Self::V>, Infallible> {
                let mut versions = self
                    .dependency_provider
                    .versions(package)
                    .map(|v| v.filter(|v| range.contains(v)).collect::<Vec<_>>())
                    .unwrap_or_default();
                versions.sort_by(|a, b| b.cmp(a));
                if let Some(v) = versions.first() {
                    if package == "grpc-google-iam-v1" {
                        println!(
                            "package: {}, choose_version: {}, versions: {:?}",
                            package, v, versions
                        );
                    }
                    Ok(Some((*v).clone()))
                } else {
                    Ok(None)
                }
                // Ok(
                //     .and_then(|versions| {
                //         versions.keys().rev().find(|v| range.contains(v)).cloned()
                //     }))
            }

            type Priority = (u32, Reverse<usize>);

            #[inline]
            fn prioritize(
                &self,
                package: &Self::P,
                range: &Self::VS,
                package_statistics: &PackageResolutionStatistics,
            ) -> Self::Priority {
                self.dependency_provider
                    .prioritize(package, range, package_statistics)
            }

            #[inline]
            fn get_dependencies(
                &self,
                package: &Self::P,
                version: &Self::V,
            ) -> Result<Dependencies<Self::P, Self::VS, Self::M>, Infallible> {
                self.dependency_provider.get_dependencies(package, version)
            }
        }

        let mut p = BundlerOfflineDependencyProvider {
            dependency_provider: OfflineDependencyProvider::new(),
        };

        /* ------ grpc-google-iam-v1 ------ */
        // 1.10.0
        p.add_dependencies(
            "google-cloud-artifact_registry-v1".into(),
            RubyVersion::parse("0.11.0"),
            vec![
                ("grpc-google-iam-v1".into(), parse_req("~> 1.1", ",").0),
                ("gapic-common".into(), parse_req(">= 0.20.0, < 2.a", ",").0),
            ],
        );

        p.add_dependencies(
            "gapic-common".into(),
            RubyVersion::parse("1.0.0"),
            vec![
                (
                    "googleapis-common-protos-types".into(),
                    parse_req("~> 1.15", ",").0,
                ),
                (
                    "googleapis-common-protos".into(),
                    parse_req("~> 1.6", ",").0,
                ),
            ],
        );

        // 1.11.0

        p.add_dependencies(
            "grpc-google-iam-v1".into(),
            RubyVersion::parse("1.10.0"),
            vec![
                ("google-protobuf".into(), parse_req(">= 3.18, < 5.a", ",").0),
                (
                    "googleapis-common-protos".into(),
                    parse_req("~> 1.4", ",").0,
                ),
                ("grpc".into(), parse_req("~> 1.41", ",").0),
            ],
        );

        p.add_dependencies(
            "grpc-google-iam-v1".into(),
            RubyVersion::parse("1.8.0"),
            vec![
                ("google-protobuf".into(), parse_req(">= 3.18, < 5.a", ",").0),
                (
                    "googleapis-common-protos".into(),
                    parse_req("~> 1.4", ",").0,
                ),
                ("grpc".into(), parse_req("~> 1.41", ",").0),
            ],
        );

        p.add_dependencies(
            "grpc-google-iam-v1".into(),
            RubyVersion::parse("1.11.0"),
            vec![
                ("google-protobuf".into(), parse_req(">= 3.18, < 5.a", ",").0),
                (
                    "googleapis-common-protos".into(),
                    parse_req("~> 1.7.0", ",").0,
                ),
                ("grpc".into(), parse_req("~> 1.41", ",").0),
            ],
        );

        /* ------ googleapis-common-protos ------ */
        p.add_dependencies(
            "googleapis-common-protos".into(),
            RubyVersion::parse("1.7.0"),
            vec![
                ("google-protobuf".into(), parse_req(">= 3.18, < 5.a", ",").0),
                (
                    "googleapis-common-protos-types".into(),
                    parse_req("~> 1.7", ",").0,
                ),
                ("grpc".into(), parse_req("~> 1.41", ",").0),
            ],
        );
        p.add_dependencies(
            "googleapis-common-protos".into(),
            RubyVersion::parse("1.8.0"),
            vec![
                ("google-protobuf".into(), parse_req(">= 3.18, < 5.a", ",").0),
                (
                    "googleapis-common-protos-types".into(),
                    parse_req("~> 1.20", ",").0,
                ),
                ("grpc".into(), parse_req("~> 1.41", ",").0),
            ],
        );

        p.add_dependencies(
            "googleapis-common-protos-types".into(),
            RubyVersion::parse("1.20.0"),
            vec![],
        );
        p.add_dependencies(
            "google-protobuf".into(),
            RubyVersion::parse("4.30.2"),
            vec![],
        );
        p.add_dependencies("grpc".into(), RubyVersion::parse("1.71.0"), vec![]);

        /* ------ root ------ */
        p.add_dependencies(
            "root".into(),
            RubyVersion::parse("0.0.0"),
            vec![(
                "google-cloud-artifact_registry-v1".into(),
                parse_req("~> 0.11.0", ",").0,
            )],
        );

        let sol = resolve(&p, "root".into(), RubyVersion::parse("0.0.0")).unwrap();

        assert_eq!(
            sol.get("grpc-google-iam-v1"),
            Some(&RubyVersion::parse("1.11.0"))
        );
        assert_eq!(
            sol.get("googleapis-common-protos"),
            Some(&RubyVersion::parse("1.7.0"))
        );
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions