Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create: Fix getting name from GitHub archives #16238

Merged
merged 1 commit into from Dec 5, 2023

Conversation

abitrolly
Copy link
Contributor

@abitrolly abitrolly commented Nov 20, 2023

brew create https://github.com/lapce/lapce/archive/v0.3.0.tar.gz currently gets the wrong name v3.0.0 from the URL. The PR fixes that.

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew typecheck with your changes locally?
  • Have you successfully run brew tests with your changes locally?

@abitrolly
Copy link
Contributor Author

I have no idea why the test fails. Its execution path with --set-name should avoid modifications that I've made. Need help with that.

Failures:

  1) brew create creates a new Formula file for a given URL
     Failure/Error: expect(formula_file).to exist
       expected #<Pathname:/tmp/homebrew-tests-20231120-3549-dtiz3r/prefix/Library/Taps/homebrew/homebrew-core/Formula/testball.rb> to exist
     # ./test/dev-cmd/create_spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./test/support/helper/spec/shared_context/integration_test.rb:49:in `block (2 levels) in <top (required)>'

Randomized with seed 62719

@abitrolly
Copy link
Contributor Author

The failure is caused by the move of fc.url to the top of the create function. I see no reasons why it should fail. Really weird.

@abitrolly
Copy link
Contributor Author

Okay, It looks like fc.url setter is way too smart

But given that FormulaCreator is only used once, it should be possible to remove URL parsing from it. Because that logic is also needed when creating casks.

$ rg FormulaCreator
Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi
4508:class Homebrew::FormulaCreator

Library/Homebrew/formula_creator.rb
11:  class FormulaCreator

Library/Homebrew/dev-cmd/create.rb
143:    fc = FormulaCreator.new(args)

@abitrolly
Copy link
Contributor Author

All right, it fails, because url= setter does too much and also sets version, and if it placed to the top, then the version is overwritten by fc.version = args.set_version line.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, nice work so far!

Okay, It looks like fc.url setter is way too smart

The opposite, actually: I'd rather than this logic moved into FormulaCreator for formulae.

Is it a problem for casks for you personally or just formulae? If it's just a formulae problem: just handle this all in FormulaCreator. If also casks: it'd be good to move the logic to something closer to FormulaCreator but for casks instead.

@abitrolly
Copy link
Contributor Author

I don't have Mac, so I don't have experience with casts. It just looks like the logic to get the name from an URL is the same for creating the cask and the formula.

@MikeMcQuaid
Copy link
Member

I don't have Mac, so I don't have experience with casts. It just looks like the logic to get the name from an URL is the same for creating the cask and the formula.

Ok, just scope it to formulae only then and put logic in FormulaCreator, thanks!

@abitrolly
Copy link
Contributor Author

I don't have Mac, so I don't have experience with casts. It just looks like the logic to get the name from an URL is the same for creating the cask and the formula.

Ok, just scope it to formulae only then and put logic in FormulaCreator, thanks!

I moved the url2name function to formula_creator.rb to keep it stateless. If it was a stateless function from the start, it wouldn't take me 9 hours to add a new rule to it. It is 9 hours given that I am already familiar with the codebase and that isn't my first attempt to fix the issue.

I also left create --cask alone, scoping the change to formulas only.

@abitrolly
Copy link
Contributor Author

I a rest. 10 hours is too much for fixing such a small issue. :D

Library/Homebrew/dev-cmd/create.rb Outdated Show resolved Hide resolved
Library/Homebrew/dev-cmd/create.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
stem.rpartition("=").last
elsif url =~ %r{github\.com/\S+/(\S+)/(archive|releases)/}
Regexp.last_match(1)
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the else not be the original behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand it right. else is the original behavior from here.

else
@name = path.basename.to_s[/(.*?)[-_.]?#{Regexp.escape(path.version.to_s)}/, 1]

@abitrolly
Copy link
Contributor Author

@MikeMcQuaid rebase was unfeasible, so I just overwrote the branch with copy-pasted content after the review. It is now ready.

Copy link
Member

@Rylan12 Rylan12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I may have missed a discussion on this (although I don't see one in the comments). Could the issue be avoided by reordering the name assignment and the fc.parse_url call?:

fc = FormulaCreator.new(...)
fc.parse_url
if args.set_name.blank? # So that this will run even if the name is detected from the URL but wasn't passed to `brew create`
  print "Formula name [#{fc.name}]: " # May need to handle `fc.name` being blank better...
  fc.name = __gets || fc.name
end

(I've not tested the above)

It feels like assigning @name to a value that comes from the URL should happen within parse_url rather than its own method to be called in basically the same place.

@abitrolly
Copy link
Contributor Author

It feels like assigning @name to a value that comes from the URL should happen within parse_url rather than its own method to be called in basically the same place.

I believe the root cause of the bug is that the code in parse_url was too magic to understand, so the rule that broke the parsing was added in the wrong place. It was also impossible to cover by tests.

It makes sense to move name_from_url call to parse_url though.

@abitrolly
Copy link
Contributor Author

@Rylan12 thanks for the suggestion. The code looks better now, with one less bug that prevented GitLab user name from being parsed.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Couple more things.

Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Comment on lines 39 to 40
name = if stem.start_with? "index.cgi"
# parsing gitweb URLs http://www.codesrc.com/gitweb/index.cgi?p=libzipper.git;a=summary
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's specifically worth checking for the domain name here or more bits e.g. gitweb?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a default Git interface https://wiki.archlinux.org/title/gitweb so checking domain name would exclude other installations.

Checking for gitweb specifically.. well, the stem variable is still needed for other rules, so the would be a bit redundant. I don't think there are many repo browser installations with exposed index.cgi which are not gitweb. In any case, if somebody reports new URL, it is easy to patch given we've got something to test against.

Library/Homebrew/formula_creator.rb Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Show resolved Hide resolved
@abitrolly
Copy link
Contributor Author

@MikeMcQuaid looks like some problem with linter. The commit Style/RedundantSelf which fixes https://github.com/Homebrew/brew/actions/runs/7091523800/job/19300839843?pr=16238#step:6:15 breaks the code.

@abitrolly
Copy link
Contributor Author

@MikeMcQuaid I had to revert the suggestion to call static method as self.name_from_url - it didn't work and subsequent linter errors were misleading - rubocop/rubocop#12512 (comment)

Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Outdated Show resolved Hide resolved
Library/Homebrew/formula_creator.rb Show resolved Hide resolved
Comment on lines 6 to 29
it "parses names from URL correctly" do
t = described_class.name_from_url("https://github.com/abitrolly/lapce/archive/v0.3.0.tar.gz")
expect(t).to eq("lapce")
t = described_class.name_from_url("http://www.codesrc.com/gitweb/index.cgi?p=libzipper.git;a=summary")
expect(t).to eq("libzipper")
t = described_class.name_from_url("https://github.com/abitrolly/lapce.git")
expect(t).to eq("lapce")
t = described_class.name_from_url("https://github.com/stella-emu/stella/releases/download/6.7/stella-6.7-src.tar.xz")
expect(t).to eq("stella")
t = described_class.name_from_url("http://digit-labs.org/files/tools/synscan/releases/synscan-5.02.tar.gz")
expect(t).to eq("synscan")
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please split this into one URL/expectation per test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean split it into five it "parses URL ..." blocks ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@abitrolly abitrolly force-pushed the create-urlparse branch 2 times, most recently from 1c8c3db to 1f39e83 Compare December 5, 2023 15:34
@abitrolly
Copy link
Contributor Author

Done. Rebased and squashed a bit.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work here @abitrolly. Thanks for all your patience, hard work and back and forth here. Hope this is your first PR of many ❤️

`brew create https://github.com/lapce/lapce/archive/v0.3.0.tar.gz` was
getting the wrong name 'v3.0.0' from the URL

Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
@MikeMcQuaid MikeMcQuaid merged commit b9dce73 into Homebrew:master Dec 5, 2023
26 checks passed
@abitrolly abitrolly deleted the create-urlparse branch December 6, 2023 00:49
@github-actions github-actions bot added the outdated PR was locked due to age label Jan 6, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants