Cocoapods: pod install changes Podfile.lock

Created on 25 May 2019  路  10Comments  路  Source: CocoaPods/CocoaPods

Report

What did you do?

  1. Install cocoapods version 1.6.2
  2. on CI: run pod install with COCOAPODS: 1.6.1 in Podfile.lock

What did you expect to happen?

Pods are installed, CI does not make changes to versioned files.

What happened instead?

Podfile.lock now has a diff, and source tree is not clean:

-COCOAPODS: 1.6.1
+COCOAPODS: 1.6.2

CocoaPods Environment

Stack

   CocoaPods : 1.6.2
        Ruby : ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]
    RubyGems : 2.5.2.1
        Host : Unable to find an executable (No such file or directory - sw_vers)  ()
       Xcode : xcodebuild) ()
         Git : git version 2.11.0
Ruby lib dir : /usr/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ 88346adcf292500d01315b9cec9f0252443e82d6

Installation Source

Executable Path: /home/artem/.gem/ruby/2.3.0/bin/pod

Plugins

cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0

Podfile

target 'cocoapodsdemo' do
  pod 'firebase', path: 'firebase'
end

Project that demonstrates the issue

https://github.com/dotdoom/cocoapodsdemo

Most helpful comment

forcing developers and CI to use the same version of the framework makes difficult to work on multiple systems / teams at the same time.

All 10 comments

This is expected afaik

Yes its expected. Use --deployment to prevent and ensure users are on the same version or bundler.

@dnkoutso using --deployment breaks pod install:

$ pod install --deployment 
Analyzing dependencies
Fetching podspec for `firebase` from `firebase`
Verifying no changes
[!] There were changes to the lockfile in deployment mode:
PODS:
  New Lockfile:
    - FirebaseAuth (5.4.2):
      - FirebaseAuthInterop (~> 1.0)
      - FirebaseCore (~> 5.2)
      - GoogleUtilities/Environment (~> 5.2)
      - GTMSessionFetcher/Core (~> 1.1)
  Old Lockfile:
    - FirebaseAuth (5.4.2):
      - FirebaseAuthInterop (~> 1.0)
      - FirebaseCore (~> 5.2)
      - GoogleUtilities/Environment (~> 5.2)
      - GTMSessionFetcher/Core (~> 1.1)

COCOAPODS:
  New Lockfile: 1.6.2
  Old Lockfile: 1.6.1


[!] Automatically assigning platform `ios` with version `12.2` on target `cocoapodsdemo` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

$ echo $?
1

Thats the point. Force CI or others to use the version of cocoapods the podfile lock was generated with. This works as intended

@dnkoutso can you elaborate, what's the point of forcing CI to use cocoapods 1.6.1 over 1.6.2? I haven't observed this behavior in similar tools like npm and bundler, so I am not aware of such point.

The original issue was claiming (correctly) that the Podfile.lock was being changed when upgrading to a different version of CocoaPods. This is working as expected as the Podfile.lock is meant to keep track the version that it was generated with.

If you want your development team not to deal with this issue you can "force" them to use the same version of CocoaPods by using https://bundler.io/ and you can also setup --deployment for your CI job to ensure that the CI job will prevent this from being merged in a pull request.

@dnkoutso I understand that CocoaPods is trying to "force" developers and CI to use the same version of the framework.

However, I do not understand why. I have not been able to find the answer on the website, neither on this repo's Wiki. What I found is that I am encouraged to "ask Why", and that's what I am doing. This is especially controversial because, as I mentioned before, none of the existing package management systems force and upgrade (without a good reason).

Making external frameworks use bundled cocoapods is hard, even if I can make them add --deployment flag in certain conditions.

The --deploy flag is to ensure determinate builds, being on the same version of your dependency manager is a part of that

forcing developers and CI to use the same version of the framework makes difficult to work on multiple systems / teams at the same time.

I agree that tooling version consistency is as key as dependency version consistency.

We've added a script for our CI system to validate that the version of the cocoapods gem is consistent between the Podfile.lock and the Gemfile.lock used by our build script (fastlane), and throw an error if they differ.

#!/usr/bin/env ruby

require 'bundler'
require 'yaml'

IOS_DIR = ARGV[0]
PROG = File.basename($0, ".rb")

puts "#{PROG}: checking versions in dir #{IOS_DIR}"

# required by LockfileParser
Dir.chdir(IOS_DIR)

gl_version = nil
pl_version = nil

def error_and_exit(msg)
 warn <<-END_WARN
The version of cocoapods used to create the current Podfile.lock does not
seem correct.
This version must match the version of the cocoapods dependency in
Gemfile.lock, as that is the version that Fastlane will use to install the
pods. Using a different version may yield unpredictable results.
If these versions do not match, most likely it is that a developer has
updated the Podfile.lock with a different version of cocoapods than
the one in Gemfile.lock. If this is the case, plase re-create
the Podfile.lock using the right version.
Directory checked: #{IOS_DIR}
Error info:
#{msg}
END_WARN

  exit 1
end

begin
  gl = Bundler::LockfileParser.new(Bundler.read_file(File.join(IOS_DIR, "Gemfile.lock")))
  spec = gl.specs.select { |s| s.name.eql?("cocoapods") }.first
  raise "cocoapods dependency not found" unless spec
  gl_version = spec.version.to_s
rescue => e
  error_and_exit "Unable to determine version of cocoapods in Gemfile.lock: #{e.message}"
end

begin
  pl = YAML.load(File.read(File.join(IOS_DIR,'Podfile.lock')))
  pl_version = pl["COCOAPODS"]
rescue => e
  error_and_exit "Unable to determine version of cocoapods in Podfile.lock: #{e.message}"
end

unless gl_version.eql?(pl_version)
  error_and_exit "Version mismatch: Gemfile.lock: #{gl_version}, Podfile.lock: #{pl_version}"
end

puts "#{PROG}: check complete"

exit 0
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dawnnnnn picture dawnnnnn  路  3Comments

hmistry picture hmistry  路  3Comments

Mingmingmew picture Mingmingmew  路  3Comments

steffendsommer picture steffendsommer  路  3Comments

tlandsmancars picture tlandsmancars  路  3Comments