Carthage / Carthage

A simple, decentralized dependency manager for Cocoa
Other
14.94k stars 1.55k forks source link

Opting out of Carthage's shared cache? #1187

Open liscio opened 8 years ago

liscio commented 8 years ago

I run a Jenkins server that executes its work on a slave machine that is set to build 4 concurrent jobs at once. At times, I get irritating race conditions that cause build failures and block PRs unnecessarily. Carthage stops with messages like the following:

fatal: Unable to create '/Users/chris/Library/Caches/org.carthage.CarthageKit/dependencies/Argo/index.lock': File exists.

Generally I invoke Carthage using carthage bootstrap --no-use-binaries --platform ios,mac for my cross-platform products, because using binaries simply doesn't work with Swift code and fast-moving Xcode releases. I generally don't use submodules in my projects, either, which likely exacerbates this issue.

I think it would be beneficial to supply either a command-line switch, or something in the Cartfile that would specify a local folder to use for Carthage's cache. For instance, you could default to a non-shared cache location of Carthage/Cache (alongside Carthage/Checkouts and Carthage/Build), or the user could choose to specify their own folder.

That way I could keep on doing what I'm doing without worrying about automated build checks failing randomly, etc.

To some extent this is related to #458, #459 (in that we can maintain per-project "carthage droppings"), and surely a few others.

Alternatively, Carthage could maintain a more sensible locking mechanism to avoid running concurrent git processes that target the same folder, however that seems quite delicate.

mdiep commented 8 years ago

I think catching that error and retrying the command would be a good first step. I'd rather see us prevent/fix the issue than create a workaround.

But if that's not enough to be workable, then I'd support adding a way to opt-out of the shared cache.

stupergenius commented 7 years ago

I too think I would prefer configuration (and/or command line parameters) that allowed users to choose from a couple different sets of behavior:

  1. Use the shared Caches folder (default)
  2. Don't use a permanent Caches folder (other than the Carthage/Checkouts folder)
  3. Either
    1. Use a user-defined location for the Caches folder
    2. Default to Carthage/Caches

We're also starting to run into the same issue as OP: concurrent jobs failing on getting a lock to the Caches git repo. We don't really want to drop back to a single build executor... so yeah.

I don't know which approach is necessarily better re: allowing users to specify Caches folders or gracefully handling lock errors. I feel like both might be a benefit, but doing one would likely solve most of our issues.

liscio commented 7 years ago

@stupergenius For what it's worth, life got a lot better when I finally decided to stop using carthage for anything but a submodule resolver. In a nutshell, I did this:

  1. rm -rf Carthage
  2. carthage bootstrap --use-submodules --no-build
  3. (Update/create your Xcode workspace with all your dependencies' xcodeproj files added to it. See the ReactiveCocoa workspace for an example of this.)
  4. Update your build systems to just call git submodule update --init --recursive

Whenever you need to pick up new dependencies, you still use carthage update --use-submodules --no-build, specifying individual dependencies as needed.

So, what's the benefit of doing the above? For starters:

  1. Xcode's IDE builds way faster overall, and does a better job resolving headers/symbols/docs/etc.
  2. Contributing back to the upstream repos is a lot easier, and you can experiment with library changes in situ as you go.
  3. You will enjoy much faster, and hassle-free CI builds overall
  4. No worrying about using Carthage's copy-frameworks script/etc for submissions and all the weird issues that crop up during that workflow.

The downsides? I can think of a few, but these are probably the most common pain points:

  1. If you're not comfortable with git submodule and its related workflow then it could be awkward for a while. In general, don't commit anything in your parent repo if your submodules are dirty, and life will go fairly well for you.
  2. Building up a working xcworkspace can be a pain if you're not good with that sort of thing. Frankly I think it's a required skill for most developers to be able to construct & manage workspaces these days, so this is worthwhile to learn.

Anyway, hopefully this helps!

stupergenius commented 7 years ago

Thanks @liscio! I'd rather not deal with the separate set of headaches that are git submodules but thank you for the viable solution. I'll tinker with some of those strategies and see if there's anything workable for our use cases.

Does this resolve the concurrent index.lock error? Presumably because it's only keeping submodules checked out and not cloning separate repos?

liscio commented 7 years ago

@stupergenius I avoided this issue by just limiting my Jenkins remotes to run a single job at a time. It sucked big-time when I had a lot of builds that needed to get done, but it worked.

When I moved over to use submodules I could run many concurrent builds at once without incident.

YMMV, of course.

Once we get a stable Swift ABI, many of these problems will go away and we can return to building from the pre-built frameworks. But even when that happens I'll probably still maintain this workspace setup because of the ease of upstream work, and highly optimized workflow.

bwhiteley commented 6 years ago

We run into this problem as well (contention over index.lock files) when running CI builds. A configurable cache folder would be appreciated.

bitcrumb commented 6 years ago

Also running into this issue. Getting 'File exists' errors when running mutiple builds concurrently on both DerivedData as well as on Caches.

flockoffiles commented 5 years ago

I am also blocked by this issue. Is there a manner to serialize git updates?

hybridcattt commented 5 years ago

@liscio did you encounter any issues with using Carthage as submodule resolver? I'm aiming at exactly the same approach, as an upgrade from using plain submodules. I'm wondering if you had any learnings that could be useful? Thank you!

werner77 commented 5 years ago

Just solved this in our fork with this pull request: https://github.com/nsoperations/Carthage/pull/4

brandonlevasseur commented 5 years ago

@werner77 How has your guy's changes not been incorporated into Carthage yet. Carthage is practically unusable with large dependency graphs right now. It will literally eat up 800% of my iMac Pro's CPU when running. It's absurd to the point where it doesn't even make sense as a professional dependency manager.

werner77 commented 5 years ago

Unfortunately we will not try to merge back into the main project anymore, our fork has diverged too much already. You can install it directly with homebrew as well though. See the README at https://github.com/nsoperations/Carthage

brandonlevasseur commented 5 years ago

@werner77 how sad, hopefully SPM will gain capabilities for platform targets and version in the near future ;). That will avoid this hot mess.