-
-
Notifications
You must be signed in to change notification settings - Fork 11.3k
Conversation
args.concat previous_install.used_options | ||
args.uniq! # Just in case some dupes were added | ||
|
||
args.delete_at args.index '--HEAD' if args.build_head? and not explicitly_requested? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be clearer IMO:
args.delete '--HEAD' if args.build_head? and not explicitly_requested?
Technically it removes all '--HEAD' but as you made it uniq just before it will not change a thing.
It is a bit less efficient (average is n compared to n/2 elements comparisons), but not relevant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow. How did I come up with delete_at
instead of delete
when reading the Array docs?
Thanks for pointing this out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My pleasure :)
@mxcl @MikeMcQuaid @adamv @jacknagel Thoughts on this? I've been playing around with it for a couple of weeks and it seems to fix #7724 and #5250 and should lay a foundation for future work on dependency resolution. |
Allright, I've expanded the range of filtered flags to:
I left |
Also added |
Glad this is being worked on. I have not reviewed the code yet, and would like to make some points in case they are not the case etc.
Maybe you already did these things, it looks like you were thorough, just thought I'd better mention them. So maybe: |
Currently the manifest file is written into the installation prefix ( |
Yes you are right, what you have done is better. Though the capitals seem ungainly. |
So there isn't any filtering done on the recording side, right? It basically records the entire install command line, and then the filtering is done when loading the options from the manifest? What about filtering |
Not exactly---the entire command line is not recorded. The key code is in the class method def self.for_install f, args
arg_options = args.options_only
formula_options = f.options.map { |o, _| o }
Tab.new :used_options => formula_options & arg_options,
:unused_options => formula_options - arg_options,
:timestamp => Time.now,
:tabfile => f.prefix + 'INSTALL_RECEIPT.yml'
end That pulls the options out of the command line and then extracts the option flags from the formula's So, the bottom line is that if the flag is not included in |
I'm definitely open to a different name for the receipt file. I chose all caps to make it seem important and so that it would show up near the top of |
Oh, I see what's happening now. Obviously I just need to RTFcode. |
One thing we need to decide on is what to do when there is no receipt for a formula. Currently, if This isn't very good behavior, but I did it in order to allow this code to be dropped into existing Homebrew installs without causing a ruckus. |
Can't we store the "manifest file" in the Cellar? Does it need to be anything more than a CR separated list in a dot file? Simple solutions win. Need to look at this properly later but thought I'd ask the stupid questions now. |
FWIW, I like the capitalized filename for the exact reason @Sharpie noted. |
And I think yaml will ultimately prove to be easier to deal with in the future, e.g. if we add a new field to the metadata, etc. |
One more reason to store the manifest in a file in the installation prefix rather than in another directory or some centralized database such as a file in the Cellar is that it makes it easy to add metadata to bottles---zero coding required. Also, it seems to me that a central database would require us to implement several things:
At first glance, a central database seems more complicated to me---but I'm willing to consider it. |
I do get that we get a lot from a centralised database, it just seems a little over engineered to me. Personally I always think the simplest solution for the current problem is the best and then you can further improve it if need be. I'm not convinced by the need for metadata or global locking. It feels quite non-Unixy to me. Sorry if I sound like a bit of a dick, I'm just really sensitive to complexity. I also need to RTFcode properly. |
I think we may be confusing each other here---I am not advocating a centralized database, but I thought that you were.
I'm with you on this one---I never liked the idea of storing metadata because I thought it would complicate |
Apologies, yes, we agree on the database (misread you). |
@mxcl @MikeMcQuaid @adamv @jacknagel I would like to merge some sort of metadata support this weekend if possible---it is blocking other important items like optional dependency resolution and multi-repo support. |
{ | ||
:used_options => used_options, | ||
:unused_options => unused_options, | ||
:timestamp => timestamp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just use the file timestamp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. This can be taken out.
No major objections here, posted a few minor quibbles. |
Looks good to me, and I will reiterate my support for the single YAML file vs. flat text files. I see the appeal of newline separated lists but I think if we want to be able to add new metadata (e.g. tagging kegs that were installed from other repositories via brew-tap, &c.), YAML is the way to go so that we (a) can easily support legacy installs that don't have every field and (b) don't end up with ten different metadata files in every keg. |
I don't see the disadvantage of having multiple files, personally. If we have ten suggested pieces of metadata I'd perhaps agree but for 2-3 I don't. I'm not blocking this though, if everyone disagrees, feel free to merge as-is :) |
Well, we only need to record 2-3 things now, but if we decide we want to record other things in the future, we might wish we had done it differently. And then if we want to change, we still have to support legacy installs. But I'm just repeating myself now so I'll quit harping on it. On a different note, it would be nice to get at least the options filtering merged soon. |
My feelings exactly. I know that I am planning to use the metadata files in the multi-repository code to flag installs that did not come from the master repository. I don't think flat delimited files would work for long---eventually things will get complicated enough that we will end up writing something that is much, much more complicated than just calling I would be willing to consider an alternate format such as JSON or INI if portability is an issue---but YAML is attractive because it is in the standard library and any Ruby object can be serialized to YAML. |
I find YAML unattractive because I don't use Ruby outside of Homebrew and haven't seen many parsers or much use for it outside Ruby development. Newline separated files are very easy to parse in any language and seem more Unixy to me. I don't see the need for a structured language for two types of date. Hell, you could do it on one with: Personally I'm dubious about the argument that "we might need this later". If you can suggest at least a couple more concrete things we will definitely need in the future then that's valid reasoning, otherwise it strikes me as over engineering. As said, I'm not overruling or anything here, just want to voice perhaps a different opinion. This is still good work and you guys are still pros but we'll see what @mxcl or @adamv say. |
mikemcquaid: Well, I guess the last item in the description might be a such a concrete thing: I believe it will soon be a mess if you use a custom format for more than a single information (and you know how annoying unix config files are with all different formats). The argument about libyaml not-so-widespread would be very strong if it added a dependency. But a YAML parser is included in Ruby and it seems they are numerous YAML implementations (from yaml.org). However, we might get these inconsistencies about dates between syck and psych... |
I don't find unix config files annoying, I usually find them very easy to parse from any language. How do I parse YAML from Bash? |
mikemcquaid: If it's a simple Array of String, you could just |
We could use the
This machinery can even be used without touching
Another reason to use |
As far as parsing config files goes, Given two Ruby implementations of equal complexity, I would rather take the one that offers more flexibility as any significant changes to the metadata system could be painful. However, I do appreciate the value of a format that is easily readable by other tools and would like to set up a solid system the first time around (because future changes will be painful). Perhaps we could do one of the following:
|
Yeah, though we already require git for So we could either skip the metadata recording if git isn't installed or error out and tell the user to install it first. |
Just came back to this after letting it sit for a while. I thought about using Git config files but the problem is that I don't want to write and debug these---I would rather use a library that takes care of the serialization for me. So, I switched the storage format to JSON and vendored a copy of the Pros:
Cons:
Let me know what y'all think---I can always roll back to YAML if this doesn't seem like a good idea. |
Seems pretty reasonable to me, go for it! |
Allright. Ok, last call for comments on this one---I'll pull the trigger this weekend if nothing comes up. For cereal this time. |
@@ -127,6 +129,9 @@ class FormulaInstaller | |||
data = read.read | |||
raise Marshal.load(data) unless data.nil? or data.empty? | |||
raise "Suspicious installation failure" unless $?.success? | |||
|
|||
# Write an installation recipt (a Tab) to the prefix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/recipt/receipt/
Gave it a quick test, didn't have any issues. We should probably teach |
Merged. Thanks to everyone for the comments and suggestions. |
@Sharpie urgent I get this backtrace on every install now
|
The I bet what is happening is that you have an older copy of Yajl installed that it is trying to use but failing to load. I'm away from my computer at the moment, but when I get back I will hard-wire the library to |
Thanks. |
Hmm. It actually succeeds about 10% of the time, so I'm not sure what is going on. |
Does the patch in pull request #8574 fix the issue? |
It appears so. |
Allright. Patch applied. |
This stack of changes adds metadata support and uses that metadata to preserve installation options through
brew upgrade
Summary of Core Changes
filtered_args
, is added to theFormulaInstaller
class. The installer callsfiltered_args
duringbuild
to create theARGV
that array that is used when the installer forks to compile a formula.filtered_args
address issue brew install --HEAD should not install --HEAD deps #7724 but also provides room for future manipulation of theARGV
vector that formula build with.build
method ofFormulaInstaller
now writes out aHOMEBREW_MANIFEST
file that contains:ARGV
options that triggeredoptions
from a formula.options
.This installation receipt is a simple YAML file and a new class called
Tab
is provided to manage the creation of receipts and the extraction of data from existing receipts.filtered_args
loads theTab
from previous installs (referencingLinkedKegs
) and appendsused_options
toARGV
. This addresses issue "brew upgrade" should remember install options #5250 and makes installation options persist throughbrew upgrade
I like this metadata implementation because it requires no change to the way
Formula
works. From the perspective of formula files, options are being passed throughARGV
the same as it ever was.Recording installation metadata should support other efforts to improve Homebrew options and dependencies:
depends_on
Comments and suggestions are appreciated.