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

Allow to install any spec #1343

Merged
merged 5 commits into from
Dec 11, 2016

Conversation

vladshablinsky
Copy link
Contributor

@vladshablinsky vladshablinsky commented Oct 21, 2016

  • 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 tests with your changes locally?

This is a possible fix for install part of #1162 and possible replacement for #1296.
For now it has some complicated if statements that should probably be replaced and some feedback on how it can be achieved is appreciated.

The behaviour for install should be the following:

  • installing HEAD keg_only should be possible only if:

    • Old version installed differs from new one and optlinked
    • --force flag is passed
    • HEAD is seriously outdated or outdated with --fetch-HEAD

    OR

    • Old version installed differs from new one and not optlinked

    OR

    • This formula is not installed
  • installing keg_only should be possible only if:

    • Old version installed differs from new one and optlinked
    • --force flag is passed

    OR

    • Old version installed differs from new one and not optlinked

    OR

    • This formula is not installed
  • installing HEAD should be possible only if:

    • Old HEAD is seriously outdated or outdated with --fetch-HEAD

    OR

    • HEAD is not installed
  • installing stable or devel should be possible only if:

    • Old version installed differs from new one

Here is an example of how it looks like:

➜ vlad:Homebrew$ brew info smpeg2                                   explicit-specs ✗
smpeg2: stable 2.0.0 (bottled), HEAD
SDL MPEG Player Library
https://icculus.org/smpeg/
/usr/local/Cellar/smpeg2/2.0.0 (23 files, 613.9K)
  Poured from bottle on 2016-10-22 at 01:45:27
/usr/local/Cellar/smpeg2/HEAD-411 (23 files, 596.4K) *
  Built from source on 2016-07-27 at 18:48:29
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/smpeg2.rb
==> Dependencies
Build: autoconf ✔, automake ✔, libtool ✔, pkg-config ✔
Required: sdl2 ✔
➜ vlad:Homebrew$ brew install smpeg2 --HEAD                         explicit-specs ✗
Warning: smpeg2-HEAD-411 already installed
➜ vlad:Homebrew$ brew install smpeg2                                explicit-specs ✗
Warning: smpeg2-2.0.0 already installed, however linked version is HEAD-411.
You can use `brew switch smpeg2 2.0.0` to link this version.
➜ vlad:Homebrew$ brew install smpeg2 --HEAD --fetch-HEAD            explicit-specs ✗
Error: smpeg2-HEAD-411 already installed
To install this version, first `brew unlink smpeg2`
➜ vlad:Homebrew$ brew unlink smpeg2                                 explicit-specs ✗
Unlinking /usr/local/Cellar/smpeg2/HEAD-411... 8 symlinks removed
➜ vlad:Homebrew$ brew install smpeg2 --HEAD --fetch-HEAD            explicit-specs ✗
==> Using the sandbox
==> Cloning svn://svn.icculus.org/smpeg/trunk
Updating /Users/vlad/Library/Caches/Homebrew/smpeg2--svn-HEAD
==> ./autogen.sh
==> ./configure --prefix=/usr/local/Cellar/smpeg2/HEAD-412 --with-sdl-prefix=/usr/loc
==> make
==> make install
🍺  /usr/local/Cellar/smpeg2/HEAD-412: 24 files, 613.7K, built in 27 seconds

CC @MikeMcQuaid @ilovezfs

@ilovezfs
Copy link
Contributor

What is the command line to install stable if devel or HEAD is already installed?

@vladshablinsky
Copy link
Contributor Author

vladshablinsky commented Oct 22, 2016

What is the command line to install stable if devel or HEAD is already installed?

Just brew install.

current = f if f.installed?
current ||= f.old_installed_formulae.first
if f.keg_only? && !f.installed_prefixes.empty? && f.opt_prefix.symlink? && !ARGV.force?
# keg-only install is only possible when no ohter version is
Copy link
Member

Choose a reason for hiding this comment

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

ohter -> other

current ||= f.old_installed_formulae.first
if f.keg_only? && !f.installed_prefixes.empty? && f.opt_prefix.symlink? && !ARGV.force?
# keg-only install is only possible when no ohter version is
# optlinked, because silent install can break dependencies. Therefore
Copy link
Member

Choose a reason for hiding this comment

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

optlinked -> linked to opt. Not sure I understand what "silent install" means.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will replace "silent install" with install without any warnings.

# optlinked, because silent install can break dependencies. Therefore
# before performing other checks we need to be sure --force flag is
# passed.
opoo "#{f.full_name} is a keg-only and another version is optlinked."
Copy link
Member

Choose a reason for hiding this comment

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

optlinked ->linked to opt

puts "Use `brew install --force` if you want to install this version"
elsif (ARGV.build_head? && (version = f.latest_head_version) &&
!f.head_version_outdated?(version, fetch_head: ARGV.fetch_head?)) ||
(f.prefix.exist? && !f.prefix.children.empty?)
Copy link
Member

Choose a reason for hiding this comment

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

Split some/all of these conditionals into variables. Similarly consider doing so for the if too.

end

msg = "#{f.full_name}-#{installed_version} already installed"
if f.linked_keg.symlink? && f.linked_keg.resolved_path != f.prefix(installed_version)
Copy link
Member

Choose a reason for hiding this comment

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

f.linked_keg.resolved_path != f.prefix(installed_version) could be a helper method or just variable.

else
version.update_commit(commit)
false
end
Copy link
Member

Choose a reason for hiding this comment

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

What's this doing, out of interest?

Copy link
Contributor Author

@vladshablinsky vladshablinsky Oct 24, 2016

Choose a reason for hiding this comment

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

This tries to shrink the commit for the version if it's possible. When we pass the commit to this method, we can fetch a full-length commit and overwrite short one with full-length for the formula. If there is no multiple short commits, there is no need to keep it full-length and we update it with initial one.

commit_outdated? is called here: https://github.com/Homebrew/brew/blob/master/Library/Homebrew/formula.rb#L522

Copy link
Member

Choose a reason for hiding this comment

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

Cool, works for me.

@MikeMcQuaid
Copy link
Member

Liking where this is going, nice work @vladshablinsky!

@vladshablinsky vladshablinsky force-pushed the explicit-specs branch 3 times, most recently from 3fd1461 to 9354579 Compare November 1, 2016 01:02
@vladshablinsky
Copy link
Contributor Author

@MikeMcQuaid is it getting better? Still needs some fixes in documentation and I guess tests, but will go for it when we're fine with the behaviour and the code.

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.

A few more changes but looking good 👍

# sure --force flag is passed.
opoo "#{f.full_name} is a keg-only and another version is linked to opt."
puts "Use `brew install --force` if you want to install this version"
elsif ARGV.build_head? && new_head_installed || prefix_installed
Copy link
Member

Choose a reason for hiding this comment

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

split new_head_installed || prefix_installed into another variable because the parity is ambiguous.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually it's (ARGV.build_head? && new_head_installed) || prefix_installed here.

Copy link
Member

Choose a reason for hiding this comment

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

Heh, see! 😀


# Is formula's linked keg points to the prefix.
def prefix_linked?(v = pkg_version)
linked? && linked_keg.resolved_path == prefix(v)
Copy link
Member

Choose a reason for hiding this comment

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

return false unless linked?

end
elsif !f.any_version_installed? && old_formula = f.old_installed_formulae.first
msg = "#{old_formula.full_name}-#{old_formula.installed_version} already installed"
unless old_formula.linked? || old_formula.keg_only?
Copy link
Member

Choose a reason for hiding this comment

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

Use if here because unless || hurts my brain

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 OK. The reason I didn't change it is that unless had been here before any change was made.

Copy link
Member

Choose a reason for hiding this comment

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

Yeh, not your issue but may as well clean it up while you're refactoring the other bits 👍

end

msg = "#{f.full_name}-#{installed_version} already installed"
if f.linked? && f.linked_version != installed_version
Copy link
Member

Choose a reason for hiding this comment

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

Could make f.linked_version != installed_version another variable for clarity but feel free to ignore that.

msg = "#{current.full_name}-#{current.installed_version} already installed"
unless current.linked_keg.symlink? || current.keg_only?
msg << ", it's just not linked"
prefix_installed = (f.prefix.exist? && !f.prefix.children.empty?)
Copy link
Member

Choose a reason for hiding this comment

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

Can probably skip parentheses here.

@MikeMcQuaid
Copy link
Member

@vladshablinsky Any news here? Thanks!

@vladshablinsky
Copy link
Contributor Author

Sorry for absence during last week, left some comments and updated the code.

@MikeMcQuaid
Copy link
Member

Sorry for absence during last week, left some comments and updated the code.

@vladshablinsky No need to apologise or be Homebrewing every week. Just checking in 😁

@vladshablinsky vladshablinsky force-pushed the explicit-specs branch 2 times, most recently from ae91ccb to d52a36c Compare November 15, 2016 07:41
@vladshablinsky
Copy link
Contributor Author

It's probably set for adding tests now.

@MikeMcQuaid
Copy link
Member

@vladshablinsky Agreed, code looks good. If you could add some tests and also detail how you're testing this manually (so I can do so myself too). Thanks!

@vladshablinsky
Copy link
Contributor Author

vladshablinsky commented Nov 17, 2016

@MikeMcQuaid

Will add tests later this week.

As for manual testing -- I was patching ack in different places to see how it worked. It can be done easier, I think. I edited version and version under devel. For manual testing HEAD's I changed url so that it pointed to my local ack repo, but just renaming HEAD_<something> to HEAD_<something else> under Cellar seems to do the thing too.

@MikeMcQuaid
Copy link
Member

As for manual testing -- I was patching ack in different places to see how it worked. It can be done easier, I think. I edited version and version under devel. For manual testing HEAD's I changed url so that it pointed to my local ack repo, but just renaming HEAD_ to HEAD_ under Cellar seems to do the thing too.

Great, thanks.

@vladshablinsky vladshablinsky force-pushed the explicit-specs branch 2 times, most recently from 57ebda4 to 3c0ebb9 Compare November 27, 2016 02:33
* `Formula#linked?` returns true if formula linked
* `Formula#optlinked?` returns true if formula linked to opt
  formula installed to the Cellar
* `Formula#prefix_linked?` returns true if linked keg points to the prefix
  passed as an argument
* `Formula#linked_version` to get linked version of the formula
* installing HEAD keg_only should be possible only if:
  1.
    - Old version installed differs from new one and optlinked
    - `--force` flag is passed
    - HEAD is seriously outdated or outdated with `--fetch-HEAD`
  or 2.
    - Old version installed differs from new one and not optlinked
  or 3.
    - This formula is not installed

* installing keg_only should be possible only if:
  1.
    - Old version installed differs from new one and optlinked
    - `--force` flag is passed
  or 2.
    - Old version installed differs from new one and not optlinked
  or 3.
    - This formula is not installed

* installing HEAD should be possible only if:
  1.
    - Old HEAD is seriously outdated or outdated with `--fetch-HEAD`
  or 2.
    - HEAD is not installed

* installing stable or devel should be possible only if:
  - Old version installed differs from new one
@vladshablinsky
Copy link
Contributor Author

@MikeMcQuaid seems like it's almost ready, however El Capitan caks tests fail, what should I do?
@ilovezfs feel free to try. CC @alyssais.

@MikeMcQuaid
Copy link
Member

@vladshablinsky I reckon just a random failure. Have requeued.

end
EOS

# Ignore dependincies, because we'll try to resolve requirements in build.rb
Copy link
Member

Choose a reason for hiding this comment

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

dependincies

@vladshablinsky
Copy link
Contributor Author

vladshablinsky commented Dec 5, 2016

Will merge as soon as I am able to be around 4 hours after the merge.

@vladshablinsky vladshablinsky merged commit 45ef7ea into Homebrew:master Dec 11, 2016
@BrewTestBot BrewTestBot removed the in progress Maintainers are working on this label Dec 11, 2016
@vladshablinsky vladshablinsky deleted the explicit-specs branch December 13, 2016 15:18
@Homebrew Homebrew locked and limited conversation to collaborators May 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion Input solicited from others features New features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants