Xcode fails to export Ad hoc distribution

Has Xcode failed to export an Ad Hoc distribution file or upload to AppstoreConnect? Read on for a possible fix.

Xcode uses internal processes to do a lot of its work. Some of those tools can be influenced by environment variables that may be set up by your terminal shell.

Normally when Xcode is launched from the Finder, properties you set in your terminal shell don’t matter. But it’s different if you’ve learned to use the command line program open to launch Xcode. When you do that, the Xcode process inherits the terminal environment. Including virtual environment settings such as virtualenv, pyenv, or a version manager such as rvm. It’s that last one that can cause this inexplicable error:

Xcode mail fail exporting an .IPA file for Ad Hoc Provisioning with a message “An error was encountered:” and “The data couldn’t be read because it isn’t in the correct format.”

If you click Show Logs you might find:

2020-09-29 02:38:10 +0000 /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require': incompatible library version - /Users/paddlefish/.rvm/gems/ruby-2.6.3/gems/date-3.0.0/lib/date_core.bundle (LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:inrequire'
from /Users/paddlefish/.rvm/gems/ruby-2.6.3/gems/date-3.0.0/lib/date.rb:4:in <top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:inrequire'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' from /Users/paddlefish/.rvm/gems/ruby-2.6.3/gems/CFPropertyList-3.0.2/lib/cfpropertylist/rbCFPropertyList.rb:4:in'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:inrequire'
from /Users/paddlefish/.rvm/gems/ruby-2.6.3/gems/CFPropertyList-3.0.2/lib/cfpropertylist.rb:3:in <top (required)>' from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:130:inrequire'
from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:130:in `rescue in require'

The fix suggested here is clever, but didn’t actually work for me. But it got me wondering — why would Xcode invoke my .bashrc or .zshrc file anyhow? It shouldn’t be creating a shell process at all to run its commands. That got me thinking maybe the Xcode process itself was tainted with a bad environment. Then I remembered, I often use open to start Xcode, e.g. from a source code directory with an ios directory containing an Xcode workspace:

$ open ./ios/myproject.xcworkspace

I open to be easier than clicking around in the Finder. Especially when my current working directory is already there.

But be forewarned — if you see Xcode starting to generate bizarre errors, it’s because of the Ruby Version Manager selecting a version of Ruby that doesn’t have the necessary Gems.

The fix couldn’t be easier. Quit Xcode. Then relaunch it — using the Dock, the Finder, or Apple Menu recent applications. Just not the shell command, open.

comm to compare files with the same name in the same directory (another bash command-line interface [cli] trick)

Suppose you have two related projects with a similar file/folder structure. You want to compare the files by the same name in the two projects. You can use some magic of pipes to build a list of filenames that are the same (and in the same relative directories) in the two projects like this:

(find src -name '*.ts'| sort) | comm -12 - <(cd ../other_project && find src -name '*.ts' | sort)

It’s simple to then feed that into vimdiff or whatever is your favorite command-line diff tool using a for expression

for x in `(find src -name '*.ts'| sort) | comm -12 - <(cd ../other_project && find src -name '*.ts' | sort)`; do vim -d $x ../other_project/$x; done

Replace ../other_project with the path to the other directory to compare.

TIL: git show <commit>:path/file.txt

Have you ever asked yourself, “How do I show a file at a particular commit or revision in its entirety?” “How do I print out a file not a diff in git?” “Show me a git file at a commit on stdout!” Here’s how you do it.

I knew about git show <commit> which shows a diff of all the files changed in a commit. You can even scope it with git show <commit> path/file.txt to show the diff for a particular file. Today I learned if you use a : (colon) instead of a (space) between the commit id and the file path git will instead show you the file in its entirety at that revision.

$ cd temp/
$ mkdir git_show_example
$ cd git_show_example/
$ git init
Initialized empty Git repository in .../temp/git_show_example/.git/
$ commit --allow-empty -m 'Initial commit'
[master (root-commit) 2f2f99d] Initial commit
$ echo 'Hello, World' > file.txt
$ git add file.txt
$ git commit -m 'Hello world'
[master 4bc4156] Hello world
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt
$ echo 'Goodbye' > file.txt
$ git commit -a -m 'Goodbye'
[master 8af3b90] Goodbye
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git show 4bc4156:file.txt
Hello, World