Homebrew / homebrew-core

🍻 Default formulae for the missing package manager for macOS (or Linux)
https://brew.sh
BSD 2-Clause "Simplified" License
13.53k stars 12.28k forks source link

`mas` won't build if ~/Library/Developer doesn't already exist #4892

Closed chdiza closed 7 years ago

chdiza commented 7 years ago

I think this might be a flaw in the HB sandbox code rather than in mas, but...

Trying to install mas from source fails if my ~/Library/Developer doesn't already exist (or if any subdirs thereof that are needed, such as Xcode, don't exist). I get the following:

==> xcodebuild -project mas-cli.xcodeproj -scheme mas-cli -configuration Release SYMROOT=build
Build settings from command line:
    SYMROOT = build

2016-09-16 09:37:12.892 xcodebuild[25081:82129]  DVTAssertions: Warning in /Library/Caches/com.apple.xbs/Sources/IDEXcode3ProjectSupport/IDEXcode3ProjectSupport-10150/Xcode3Core/LegacyProjects/Frameworks/DevToolsCore/DevToolsCore/BuildSystem/DependencyGraph/XCDependencyGraph.mm:688
Details:  unable to write dependency graph: You don’t have permission to save the file “mas.build” in the folder “Release”.
Object:   <XCDependencyGraph>
Method:   +loadOrCreateInBuildDirectory:withTargetBuildContext:withBasePath:
Thread:   <NSThread: 0x7fd034638910>{number = 5, name = (null)}
Please file a bug at http://bugreport.apple.com with this warning message and any useful information you can provide.
Build Preparation
Couldn't create module cache folder '/Users/chdiza/Library/Developer/Xcode/DerivedData/ModuleCache': Unable to create directory: /Users/chdiza/Library/Developer/Xcode/DerivedData/ModuleCache (Operation not permitted)
Couldn't update module cache session file '/Users/chdiza/Library/Developer/Xcode/DerivedData/ModuleCache/Session.modulevalidation': The folder “Session.modulevalidation” doesn’t exist.

2016-09-16 09:37:12.905 xcodebuild[25081:82088] Error saving log: Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory" UserInfo={NSFilePath=/Users/chdiza/Library/Developer/Xcode/DerivedData/mas-cli-fyildokjfwqbraetoucjcpbtmbhy/Logs/Build/AFF864A9-CA85-4BD1-BD08-FC5F4EF521A5.xcactivitylog, NSLocalizedDescription=No such file or directory} | User info: {
    NSFilePath = "/Users/chdiza/Library/Developer/Xcode/DerivedData/mas-cli-fyildokjfwqbraetoucjcpbtmbhy/Logs/Build/AFF864A9-CA85-4BD1-BD08-FC5F4EF521A5.xcactivitylog";
    NSLocalizedDescription = "No such file or directory";
}
** BUILD FAILED **

==> Sandbox log
Sep 16 09:37:12 sandboxd[140]: xcodebuild(25081) deny file-write-create /Users/chdiza/Library/Developer
Sep 16 09:37:12 sandboxd[140]: xcodebuild(25081) deny file-write-create /Users/chdiza/Library/Developer
Sep 16 09:37:12 sandboxd[140]: xcodebuild(25081) deny file-write-create /Users/chdiza/Library/Developer
Sep 16 09:37:13 sandboxd[140]: xcodebuild(25081) deny file-write-create /Users/chdiza/Library/Developer

If after a failure I manually create the dir that's being complained about, the next brew attempt will succeed.

I've never seen anything like this before. I can build other apps, outside HB, that write to ~/Library/Developer with zero problems.

chdiza commented 7 years ago
HOMEBREW_VERSION: 0.9.9
ORIGIN: https://github.com/Homebrew/brew
HEAD: 53713593d677cb916402742940d14bfc7e60a5a4
Last commit: 4 hours ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 22a2eeeff1294a9c3dddfc91f1768c653726e501
Core tap last commit: 18 minutes ago
HOMEBREW_PREFIX: /usr/local
HOMEBREW_REPOSITORY: /usr/local/hb
HOMEBREW_CELLAR: /usr/local/Cellar
HOMEBREW_BOTTLE_DOMAIN: https://homebrew.bintray.com
CPU: quad-core 64-bit ivybridge
Homebrew Ruby: 2.0.0-p648
Clang: 7.3 build 703
Git: 2.10.0 => /usr/local/bin/git
Perl: /usr/bin/perl
Python: /usr/bin/python
Ruby: /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
Java: N/A
OS X: 10.11.6-x86_64
Xcode: 7.3.1
CLT: 7.3.1.0.1.1461711523
X11: 2.7.9 => /opt/X11
ilovezfs commented 7 years ago

as a pragmatic workaround --no-sandbox

zmwangx commented 7 years ago

The problem is allow_write_sandbox in sandbox.rb:

  # Xcode projects expect access to certain cache/archive dirs.
  def allow_write_xcode
    allow_write_path "/Users/#{ENV["USER"]}/Library/Developer/Xcode/DerivedData/"
  end

It grants writing access to that path, but apparently you can't create parent directories. A workaround is to create the directory and its parents outright to prevent problems like this.

CC @xu-cheng @DomT4.

chdiza commented 7 years ago

How did this make it pass CI? Seems like it ought to have bombed out.

DomT4 commented 7 years ago

The CI isn't "clean". That path would have been created before the sandbox was implemented, and not scrubbed since, allowing it to create further things below that.

zmwangx commented 7 years ago

@DomT4 Thoughts about mkdir_p the path in allow_write_xcode, and similar changes for other whitelisted paths maybe?