From c3158d8126e6773c0fee11b54ca86bd464e69ae9 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sun, 28 Jun 2020 09:42:02 +0800 Subject: [PATCH] Fixed #397 -- If Xcode command line tools are active, warn the user. --- changes/397.bugfix.rst | 1 + src/briefcase/integrations/xcode.py | 27 ++++++++++---- .../xcode/test_ensure_xcode_is_installed.py | 37 ++++++++++++++++++- 3 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 changes/397.bugfix.rst diff --git a/changes/397.bugfix.rst b/changes/397.bugfix.rst new file mode 100644 index 000000000..ae513cae6 --- /dev/null +++ b/changes/397.bugfix.rst @@ -0,0 +1 @@ +iOS builds will now warn if the Xcode command line tools are the active. diff --git a/src/briefcase/integrations/xcode.py b/src/briefcase/integrations/xcode.py index 11feebed3..7c123dc93 100644 --- a/src/briefcase/integrations/xcode.py +++ b/src/briefcase/integrations/xcode.py @@ -148,6 +148,7 @@ def ensure_xcode_is_installed( try: output = command.subprocess.check_output( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True ) @@ -198,16 +199,28 @@ def ensure_xcode_is_installed( ************************************************************************* """) - except subprocess.CalledProcessError: - raise BriefcaseCommandError(""" -Xcode is not installed. + except subprocess.CalledProcessError as e: + if " is a command line tools instance" in e.output: + raise BriefcaseCommandError(""" +Xcode is installed, but the active developer directory is a +command line tools instance. To make XCode the active developer +directory, run: -You should be shown a dialog prompting you to install Xcode and the -command line tools. Select "Get Xcode" to install Xcode from the app store. + $ sudo xcode-select -switch /Applications/Xcode.app -You can install Xcode from the macOS App Store. +and then re-run Briefcase. +""") + else: + raise BriefcaseCommandError(""" +The Xcode install appears to exist, but Briefcase was unable to +determine the current Xcode version. Running: -Re-run Briefcase once that installation is complete. + $ xcodebuild -version + +should return the current Xcode version, but it raised an error. + +You may need to re-install Xcode. Re-run Briefcase once that +installation is complete. """) diff --git a/tests/integrations/xcode/test_ensure_xcode_is_installed.py b/tests/integrations/xcode/test_ensure_xcode_is_installed.py index ba379cf23..b4d0272c3 100644 --- a/tests/integrations/xcode/test_ensure_xcode_is_installed.py +++ b/tests/integrations/xcode/test_ensure_xcode_is_installed.py @@ -34,20 +34,49 @@ def test_not_installed(tmp_path): command.subprocess.check_output.assert_not_called() -def test_exists_but_not_installed(xcode): +def test_exists_but_command_line_tools_selected(xcode): + "If the Xcode folder exists, but cmd-line tools are selected, raise an error." + command = mock.MagicMock() + command.subprocess.check_output.side_effect = subprocess.CalledProcessError( + cmd=['xcodebuild', '-version'], + returncode=1 + ) + command.subprocess.check_output.side_effect.output = ( + "xcode-select: error: tool 'xcodebuild' requires Xcode, but " + "active developer directory '/Library/Developer/CommandLineTools' " + "is a command line tools instance\n" + ) + + with pytest.raises(BriefcaseCommandError, match=r"xcode-select -switch"): + ensure_xcode_is_installed(command, xcode_location=xcode) + + # xcode-select was invoked + command.subprocess.check_output.assert_called_once_with( + ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, + universal_newlines=True, + ) + + +def test_exists_but_corrupted(xcode): "If the Xcode folder exists, but xcodebuild breaks, raise an error." command = mock.MagicMock() command.subprocess.check_output.side_effect = subprocess.CalledProcessError( cmd=['xcodebuild', '-version'], returncode=1 ) + command.subprocess.check_output.side_effect.output = "Badness occurred." - with pytest.raises(BriefcaseCommandError): + with pytest.raises( + BriefcaseCommandError, + match=r"should return the current Xcode version" + ): ensure_xcode_is_installed(command, xcode_location=xcode) # xcode-select was invoked command.subprocess.check_output.assert_called_once_with( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True, ) @@ -63,6 +92,7 @@ def test_installed_no_minimum_version(xcode): # xcode-select was invoked command.subprocess.check_output.assert_called_once_with( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True, ) @@ -122,6 +152,7 @@ def test_installed_with_minimum_version_success(min_version, version, capsys, xc # xcode-select was invoked command.subprocess.check_output.assert_called_once_with( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True, ) @@ -160,6 +191,7 @@ def test_installed_with_minimum_version_failure(min_version, version, xcode): # xcode-select was invoked command.subprocess.check_output.assert_called_once_with( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True, ) @@ -179,6 +211,7 @@ def test_unexpected_version_output(capsys, xcode): # xcode-select was invoked command.subprocess.check_output.assert_called_once_with( ['xcodebuild', '-version'], + stderr=subprocess.STDOUT, universal_newlines=True, )