Comments (11)
I think your
tap_migrations.json
inpe/old-tap
should be{ "example": "pe/new-tap/example" }
Looking at other examples I don't think so: https://github.com/brewsci/homebrew-science/blob/5d14d2fda3934c0eb8243c1cbdb9fb4621ec110b/tap_migrations.json
I tried it with pe/homebrew-old-tap@cc86591. Same error.
from brew.
While playing around, I just noticed that the same error also applies to formulae, not only to casks.
Step-by-step reproduction instructions (by running brew commands)
https://github.com/pe/homebrew-old-tap/blob/5a0e91e527c5962096e62fa277c896a1c285faef/tap_migrations.json#L3
https://github.com/pe/homebrew-new-tap/blob/d755222b381ccbea385f7884b97b9b8b9f19429e/Formula/examplef.rb#L1
~ ❯ brew install examplef --verbose --debug
Warning: Formula pe/old-tap/examplef was renamed to pe/new-tap/examplef.
Error: Formulae found in multiple taps:
* pe/new-tap/examplef
* pe/new-tap/examplef
Please use the fully-qualified name (e.g. pe/new-tap/examplef) to refer to a specific formula.
/opt/homebrew/Library/Homebrew/formulary.rb:837:in `try_new'
/opt/homebrew/Library/Homebrew/formulary.rb:1227:in `block in loader_for'
/opt/homebrew/Library/Homebrew/formulary.rb:1226:in `each'
/opt/homebrew/Library/Homebrew/formulary.rb:1226:in `loader_for'
/opt/homebrew/Library/Homebrew/formulary.rb:1008:in `factory'
/opt/homebrew/Library/Homebrew/cli/parser.rb:709:in `block in formulae'
/opt/homebrew/Library/Homebrew/cli/parser.rb:705:in `each'
/opt/homebrew/Library/Homebrew/cli/parser.rb:705:in `filter_map'
/opt/homebrew/Library/Homebrew/cli/parser.rb:705:in `formulae'
/opt/homebrew/Library/Homebrew/cli/parser.rb:363:in `parse'
/opt/homebrew/Library/Homebrew/abstract_command.rb:53:in `initialize'
/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.3.0/gems/sorbet-runtime-0.5.11385/lib/types/private/abstract/declare.rb:37:in `new'
/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.3.0/gems/sorbet-runtime-0.5.11385/lib/types/private/abstract/declare.rb:37:in `block in declare_abstract'
/opt/homebrew/Library/Homebrew/brew.rb:90:in `<main>'
The exact same code also exists here:
brew/Library/Homebrew/formulary.rb
Lines 829 to 831 in f1a7d97
from brew.
I think your tap_migrations.json
in pe/old-tap
should be
{
"example": "pe/new-tap/example"
}
from brew.
I think I found the source of the issue. The same cask is found twice. Once in the new tap and once in the old but mapped to the new tap.
If I inspect loaders
from this code:
brew/Library/Homebrew/cask/cask_loader.rb
Lines 459 to 461 in 5e6a43e
I get this:
[
#<Cask::CaskLoader::FromNameLoader:0x0000000125cac788 @token="example", @path=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>, @tap=#<Tap:0x0000000122de3898 @user="pe", @repo="new-tap", @name="pe/new-tap", @full_name="pe/homebrew-new-tap", @path=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>, @git_repo=#<GitRepository:0x0000000122e0f6f0 @pathname=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>>, @alias_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Aliases>, @alias_files=[], @alias_table={}, @formula_renames={}, @tap_migrations={}, @potential_formula_dirs=[#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Formula>, #<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/HomebrewFormula>, #<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>], @formula_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>, @formula_files=[], @formula_files_by_name={}, @cask_renames={}, @cask_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks>, @cask_files=[#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>], @cask_files_by_name={"example"=>#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>}>>,
#<Cask::CaskLoader::FromNameLoader:0x0000000125caa410 @token="example", @path=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>, @tap=#<Tap:0x0000000122de3898 @user="pe", @repo="new-tap", @name="pe/new-tap", @full_name="pe/homebrew-new-tap", @path=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>, @git_repo=#<GitRepository:0x0000000122e0f6f0 @pathname=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>>, @alias_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Aliases>, @alias_files=[], @alias_table={}, @formula_renames={}, @tap_migrations={}, @potential_formula_dirs=[#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Formula>, #<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/HomebrewFormula>, #<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>], @formula_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap>, @formula_files=[], @formula_files_by_name={}, @cask_renames={}, @cask_dir=#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks>, @cask_files=[#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>], @cask_files_by_name={"example"=>#<Pathname:/opt/homebrew/Library/Taps/pe/homebrew-new-tap/Casks/example.rb>}>>
]
The only difference is the object_id.
Changing the above code like so fixes the issue.
loaders = Tap.select { |tap| tap.installed? && !tap.core_cask_tap? }
.filter_map { |tap| super("#{tap}/#{token}", warn:) }
.select { |tap| tap.path.exist? }
.uniq{ |cask| cask.tap } # this line was added by me
But my knowledge of this codebase is none and my ruby is very limited. I can't judge if this is a good idea or not.
How to proceed? Should I just create a PR and we'll discuss there? Would you want any tests for this change? Where? Are there other places where this is also necessary?
from brew.
I can't judge if this is a good idea or not.
My Ruby-fu is limited too, but I'm pretty sure that:
- the whole point of migrations is that the formula/cask no longer exists in the old tap
- taps are processed in alpha-sorted order, so if your old tap sorts before the new one (e.g.
pe/tap1 -> pe/tap2
), your fix will pick the wrong tap
from brew.
- the whole point of migrations is that the formula/cask no longer exists in the old tap
Yes, this. You should delete the formula/cask from the old file or it won't work as expected.
from brew.
How to proceed? Should I just create a PR and we'll discuss there?
Yes, this would be best.
Would you want any tests for this change? Where?
Ideally the corresponding _spec.rb
file to the source file(s) you edit. That can wait until we've validated the approach with a draft PR, though.
from brew.
taps are processed in alpha-sorted order, so if your old tap sorts before the new one (e.g. pe/tap1 -> pe/tap2), your fix will pick the wrong tap
I don't think that the order matters because both casks are identical (except for the object_id). The cask from the old tap was already migrated to the new one, that's why they are identical.
- the whole point of migrations is that the formula/cask no longer exists in the old tap
Yes, this. You should delete the formula/cask from the old file or it won't work as expected.
I did delete it in the old tap and get this error nevertheless. See What were you trying to do (and why)?.
How to proceed? Should I just create a PR and we'll discuss there?
Yes, this would be best.
OK. Will do.
from brew.
brew/Library/Homebrew/cask/cask_loader.rb
Lines 459 to 461 in ff950e6
I suspect what's happening here is that we're getting identical cask loaders because the call to super
evaluates cask renames and migrations so it's possible that the original tap that the cask was migrated from is returning the cask loader for the new tap.
brew/Library/Homebrew/cask/cask_loader.rb
Lines 205 to 212 in ff950e6
The super
call leads to the Cask::CaskLoader::FromTapLoader.try_new
method which calls the Cask::CaskLoader.tap_cask_token_type
method. Normally it just returns the cask token, tap and type specified but if the cask has been renamed or migrated it returns the new token, tap and type. Since they are identical, just removing duplicates by path makes sense here. Tap would also work but path is a bit more specific.
Ideally, we'd figure out how to refactor this so that this doesn't happen in this sort of situation but I'm not really sure what that would look like.
from brew.
@reitermarkus Could you take a look at this if you get a chance as you did a bunch of migration work recently? Thanks ❤️
from brew.
Fixed by #17385
from brew.
Related Issues (20)
- Throttle does not work for llama.cpp HOT 2
- Support specifying replacement formulae in `deprecate!` or `disable!` calls HOT 1
- Brew appears to be broken HOT 3
- shellenv.sh: Failure when user cannot write "${HOMEBREW_PATHS_FILE}" HOT 1
- Archive and deprecate HOT 1
- Consider setting `XDG_DATA_DIRS` in `shellenv` on Linux HOT 1
- Multiple Formula giving `Error: Couldn't find manifest matching bottle checksum.` HOT 4
- pkg missing for release 4.3.21 assets HOT 4
- sha256 checksum is not enforced HOT 2
- Setup `brew determine-test-runners` for macOS 15 x86_64 HOT 11
- Avoid outputting Rosetta 2 caveats on Intel machines HOT 14
- Don't allow installing formulae from paths without HOMEBREW_DEVELOPER HOT 2
- `brew install` should display download size HOT 17
- `brew install [email protected]` failed while exec `go build` with custom system env `GOPROXY=https://goproxy.io,direct` HOT 1
- Make `brew tap-info` show commit hash for taps that don't use the JSON API (_i.e._, are cloned locally) HOT 5
- Using `actionlint` in `brew style` makes updating `actionlint` impossible HOT 4
- Piping password to brew no longer working HOT 7
- NOT support for macOS 15 HOT 3
- could you update update the hombrew versioin to suppourt macos 15 HOT 1
- postgresql@16 service can only be started by sudo HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from brew.