This repository has been archived by the owner. It is now read-only.

Version output in 0.9.1+ inconsistent with older releases #13299

Closed
jtimberman opened this Issue Jul 9, 2012 · 41 comments

Comments

Projects
None yet
6 participants
@jtimberman
Contributor

jtimberman commented Jul 9, 2012

I'm sure there was a good reason for this.

However, it took a relatively simple way to inspect a package and its version from:

git 1.7.11

(making it really easy to split with awk, or any scripting language)

to this:

git: stable 1.7.11.1, HEAD

Or, if it doesn't have "specs", something like this:

mysql: stable 5.5.25a

Now I have to guess, or work around splitting off the comma and whatever might trail it. I don't know what else might be there.

To make matters worse, this was done in a 0.9 -> 0.9.1 (or, 0.9.2, the latest) release. Properly behaved package managers do not arbitrarily change the way that they present information about the package; this is not behaving properly.

What is the value add here? Why was this appended on the same line as the version? Why doesn't the output do something like:

Formula: git
Stable Version: 1.7.11.1
Devel Version: HEAD

Or similar?

@adamv

This comment has been minimized.

Show comment
Hide comment
@adamv

adamv Jul 9, 2012

Contributor

We've never been great at defining outputs for commands such that they can be parsed programmatically, and I really want to start doing that. Like how certain GIT commands have specified outputs.

We've generally treated command output as "human readable" instead of "machine readable."

So... let's start fixing that.

Contributor

adamv commented Jul 9, 2012

We've never been great at defining outputs for commands such that they can be parsed programmatically, and I really want to start doing that. Like how certain GIT commands have specified outputs.

We've generally treated command output as "human readable" instead of "machine readable."

So... let's start fixing that.

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Jul 9, 2012

Contributor

Commit where this was introduced:

94d0f23#Library/Homebrew/cmd/info.rb

Contributor

jtimberman commented Jul 9, 2012

Commit where this was introduced:

94d0f23#Library/Homebrew/cmd/info.rb

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Jul 9, 2012

Contributor

Pull request: #13300

Sample output:

% bin/brew info git
git 1.7.11.1
Formula name: git
Stable version: 1.7.11.1
Development version: HEAD

% bin/brew info wine   
wine 1.4
Formula name: wine
Stable version: 1.4
Development version: 1.5.6, HEAD
Contributor

jtimberman commented Jul 9, 2012

Pull request: #13300

Sample output:

% bin/brew info git
git 1.7.11.1
Formula name: git
Stable version: 1.7.11.1
Development version: HEAD

% bin/brew info wine   
wine 1.4
Formula name: wine
Stable version: 1.4
Development version: 1.5.6, HEAD
@jacknagel

This comment has been minimized.

Show comment
Hide comment
@jacknagel

jacknagel Jul 9, 2012

Contributor

I don't like spending four lines of output on this. As @adamv said, brew info was not designed for consumption by scripts, etc.

I think any machine readable output should be triggered by an option.

Contributor

jacknagel commented Jul 9, 2012

I don't like spending four lines of output on this. As @adamv said, brew info was not designed for consumption by scripts, etc.

I think any machine readable output should be triggered by an option.

@adamv

This comment has been minimized.

Show comment
Hide comment
@adamv

adamv Jul 10, 2012

Contributor

Thinking out loud, add --data options to commands that spits out documented JSON objects.

Contributor

adamv commented Jul 10, 2012

Thinking out loud, add --data options to commands that spits out documented JSON objects.

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Jul 10, 2012

Contributor

@adamv JSON or YAML, or an option for either, sounds good. Machine parsable "info" output would be fantastic!

@jacknagel Despite best intentions, that happens with almost any "informational" output for text/cli-based programs. All the tooling around processing text output of package management systems like APT and YUM is testament to that.

Of course, a data output is better, and definitely preferred, and an API would be fantastical too.

Contributor

jtimberman commented Jul 10, 2012

@adamv JSON or YAML, or an option for either, sounds good. Machine parsable "info" output would be fantastic!

@jacknagel Despite best intentions, that happens with almost any "informational" output for text/cli-based programs. All the tooling around processing text output of package management systems like APT and YUM is testament to that.

Of course, a data output is better, and definitely preferred, and an API would be fantastical too.

@adamv

This comment has been minimized.

Show comment
Hide comment
@adamv

adamv Jul 10, 2012

Contributor

Definitely prefer JSON over YAML for non-Ruby compatibility.

Contributor

adamv commented Jul 10, 2012

Definitely prefer JSON over YAML for non-Ruby compatibility.

@jacknagel

This comment has been minimized.

Show comment
Hide comment
@jacknagel

jacknagel Jul 10, 2012

Contributor

I can certainly understand that, and I would not be this cavalier if we were talking about e.g. brew deps or something that can be used in a shell pipeline. But brew info doesn't really fall into that category, and we've never made any sort of guarantee about the output format, so I don't feel like we need to maintain any sort of backwards compatibility here. Even your suggested format may break some scripts that are parsing more than just the first line.

So I'd say the way forward is definitely something along the lines of a JSON dump.

Contributor

jacknagel commented Jul 10, 2012

I can certainly understand that, and I would not be this cavalier if we were talking about e.g. brew deps or something that can be used in a shell pipeline. But brew info doesn't really fall into that category, and we've never made any sort of guarantee about the output format, so I don't feel like we need to maintain any sort of backwards compatibility here. Even your suggested format may break some scripts that are parsing more than just the first line.

So I'd say the way forward is definitely something along the lines of a JSON dump.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 4, 2012

Member

I agree brew info is not for machine reading.

But the new output isn't even human-readable IMO.

If you need a stable format, then you could always use a ruby instance to instantiate the Formula class you are interested in.

Or patches for info --yaml or whatever are welcome.

Member

mxcl commented Aug 4, 2012

I agree brew info is not for machine reading.

But the new output isn't even human-readable IMO.

If you need a stable format, then you could always use a ruby instance to instantiate the Formula class you are interested in.

Or patches for info --yaml or whatever are welcome.

@jacknagel

This comment has been minimized.

Show comment
Hide comment
@jacknagel

jacknagel Aug 5, 2012

Contributor

But the new output isn't even human-readable IMO.

What's better:

(a)

foo
1.2 (stable), 1.3 (devel), HEAD

(b)

foo
stable 1.2, devel 1.3, HEAD

(c)

foo
stable: 1.2, devel: 1.3, HEAD
Contributor

jacknagel commented Aug 5, 2012

But the new output isn't even human-readable IMO.

What's better:

(a)

foo
1.2 (stable), 1.3 (devel), HEAD

(b)

foo
stable 1.2, devel 1.3, HEAD

(c)

foo
stable: 1.2, devel: 1.3, HEAD
@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 5, 2012

Member

None really. First few times I parsed it I assumed I had all those installed. I have no suggestions.

Member

mxcl commented Aug 5, 2012

None really. First few times I parsed it I assumed I had all those installed. I have no suggestions.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 5, 2012

Member

I refer to this gist as an example of a standalone Ruby script that can query Formula instances: https://gist.github.com/3260053

Member

mxcl commented Aug 5, 2012

I refer to this gist as an example of a standalone Ruby script that can query Formula instances: https://gist.github.com/3260053

@jacknagel

This comment has been minimized.

Show comment
Hide comment
@jacknagel

jacknagel Aug 5, 2012

Contributor

Well I don't know how else to present that information then. Previously it said "formula version", but even then it was always the current formula version and didn't correspond to any installed version.

Contributor

jacknagel commented Aug 5, 2012

Well I don't know how else to present that information then. Previously it said "formula version", but even then it was always the current formula version and didn't correspond to any installed version.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 5, 2012

Member

Yes, previously it was less than useful. I sat down and tried to think of something yesterday, but came up with nothing.

Member

mxcl commented Aug 5, 2012

Yes, previously it was less than useful. I sat down and tried to think of something yesterday, but came up with nothing.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 16, 2012

Contributor

Took a stab at this: https://github.com/mistydemeo/homebrew/compare/json

I thought about merging more logic between the two info formats, but since 99% of the logic in info_formula is presentation-specific it didn't really seem worth breaking up.

(Better names for "linked" and children welcome, I was tired and couldn't think of anything better.)

@jtimberman As the original requester, how does this look?

Contributor

mistydemeo commented Aug 16, 2012

Took a stab at this: https://github.com/mistydemeo/homebrew/compare/json

I thought about merging more logic between the two info formats, but since 99% of the logic in info_formula is presentation-specific it didn't really seem worth breaking up.

(Better names for "linked" and children welcome, I was tired and couldn't think of anything better.)

@jtimberman As the original requester, how does this look?

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 16, 2012

Member

IMO, if there is only one, the JSON should not be in an array. Probably there should be a switch for that.

[
   {
      "specs":{
         "bottle":null,
         "stable":"1.10.2",
         "head":"HEAD",
         "devel":false
      },
      "caveats":null,
      "homepage":"http://defunkt.io/hub/",
      "conflicts":[

      ],
      "installed":[
         {
            "version":"1.10.2",
            "used_options":[

            ],
            "built_bottle":false
         }
      ],
      "name":"hub",
      "linked":{
         "keg_only":false,
         "reason":""
      },
      "dependencies":[

      ],
      "github_history":"https://github.com/mxcl/homebrew/commits/master/Library/Formula/hub.rb",
      "options":[

      ]
   }
]

Proposed changes:

  • conflicts:[] => conflicts_with:null.
  • "linked":{"keg_only":false, "reason":""} => "linked_kegs":[1.10.2], "keg-only":false
  • "options":[] should be "options":null
  • "installed":[{"version":"1.10.2","used_options":[],"built_bottle":false}] =>"installed":[{"version":"1.10.2","used_options":null,"built_bottle":false}]

What does built_bottle even mean? I went into the source for Tab and am just confused. Names matter whoever chose that :P

I'd frankly choose another name for "specs" too. I know we call it this in the code, but for me, it's a completely meaningless name. "install_options" is way clearer.

Otherwise, super. Good to see this.

Member

mxcl commented Aug 16, 2012

IMO, if there is only one, the JSON should not be in an array. Probably there should be a switch for that.

[
   {
      "specs":{
         "bottle":null,
         "stable":"1.10.2",
         "head":"HEAD",
         "devel":false
      },
      "caveats":null,
      "homepage":"http://defunkt.io/hub/",
      "conflicts":[

      ],
      "installed":[
         {
            "version":"1.10.2",
            "used_options":[

            ],
            "built_bottle":false
         }
      ],
      "name":"hub",
      "linked":{
         "keg_only":false,
         "reason":""
      },
      "dependencies":[

      ],
      "github_history":"https://github.com/mxcl/homebrew/commits/master/Library/Formula/hub.rb",
      "options":[

      ]
   }
]

Proposed changes:

  • conflicts:[] => conflicts_with:null.
  • "linked":{"keg_only":false, "reason":""} => "linked_kegs":[1.10.2], "keg-only":false
  • "options":[] should be "options":null
  • "installed":[{"version":"1.10.2","used_options":[],"built_bottle":false}] =>"installed":[{"version":"1.10.2","used_options":null,"built_bottle":false}]

What does built_bottle even mean? I went into the source for Tab and am just confused. Names matter whoever chose that :P

I'd frankly choose another name for "specs" too. I know we call it this in the code, but for me, it's a completely meaningless name. "install_options" is way clearer.

Otherwise, super. Good to see this.

@MikeMcQuaid

This comment has been minimized.

Show comment
Hide comment
@MikeMcQuaid

MikeMcQuaid Aug 16, 2012

Member

built_bottle means a bottle was built using --build-bottle :D

To be exact that means it was built with the generic CFLAGS etc. required for bottles.

Member

MikeMcQuaid commented Aug 16, 2012

built_bottle means a bottle was built using --build-bottle :D

To be exact that means it was built with the generic CFLAGS etc. required for bottles.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 16, 2012

Member

OK, I figured that was one of the options. Why is it recorded in the receipt? Surely a much better choice of attribute here would have been "is_bottle". All the other attributes refer to the state of the keg the receipt is attached to, not the past-participle of the state of the install-process.

Member

mxcl commented Aug 16, 2012

OK, I figured that was one of the options. Why is it recorded in the receipt? Surely a much better choice of attribute here would have been "is_bottle". All the other attributes refer to the state of the keg the receipt is attached to, not the past-participle of the state of the install-process.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 16, 2012

Contributor

IMO, if there is only one, the JSON should not be in an array. Probably there should be a switch for that.

Maybe it should be an option. My thinking was, since this is an interface which can return more than one item, it's better for the consumer to consistently get an array than to sometimes get an array and sometimes not.

Ditto [] vs null, cf. the Twitter API: https://raw.github.com/gist/df1100a926754e5bae6c/c55ef5e111e64ed92f354abe514a90ae42e5b93b/smaufrai.json

"linked":{"keg_only":false, "reason":""} => "linked_kegs":[1.10.2], "keg-only":false

Way better. Though perhaps it should just be linked_keg, given that we don't support linking multiple versions in parallel.

Surely a much better choice of attribute here would have been "is_bottle".

Yeah, was just going from how it's recorded in the tab. is_bottle is better for sure.

Contributor

mistydemeo commented Aug 16, 2012

IMO, if there is only one, the JSON should not be in an array. Probably there should be a switch for that.

Maybe it should be an option. My thinking was, since this is an interface which can return more than one item, it's better for the consumer to consistently get an array than to sometimes get an array and sometimes not.

Ditto [] vs null, cf. the Twitter API: https://raw.github.com/gist/df1100a926754e5bae6c/c55ef5e111e64ed92f354abe514a90ae42e5b93b/smaufrai.json

"linked":{"keg_only":false, "reason":""} => "linked_kegs":[1.10.2], "keg-only":false

Way better. Though perhaps it should just be linked_keg, given that we don't support linking multiple versions in parallel.

Surely a much better choice of attribute here would have been "is_bottle".

Yeah, was just going from how it's recorded in the tab. is_bottle is better for sure.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 16, 2012

Contributor

specs could easily be versions here instead.

Contributor

mistydemeo commented Aug 16, 2012

specs could easily be versions here instead.

@MikeMcQuaid

This comment has been minimized.

Show comment
Hide comment
@MikeMcQuaid

MikeMcQuaid Aug 16, 2012

Member

@mxcl It's not that it was installed from a bottle; it's that it can be used to create a bottle i.e. from a bottle or built with the generic CFLAGS.

Member

MikeMcQuaid commented Aug 16, 2012

@mxcl It's not that it was installed from a bottle; it's that it can be used to create a bottle i.e. from a bottle or built with the generic CFLAGS.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 16, 2012

Member

Maybe it should be an option. My thinking was, since this is an interface which can return more than one item, it's better for the consumer to consistently get an array than to sometimes get an array and sometimes not.

I usually aim for the 80% rule with API design. 80% of the time people are not requesting multiple datas, don't punish those guys by forcing them to deal with arrays.

Ditto [] vs null, cf. the Twitter API:

Having worked extensively against the Twitter API I really must say, it is not something to use as an example. However the null/[] is an opinionated topic, I think all we should insist upon is consistence. Use null for absent non-array datas though.

@mxcl It's not that it was installed from a bottle; it's that it can be used to create a bottle i.e. from a bottle or built with the generic CFLAGS.

Oh okay. Then: "built_as_bottle" makes more sense.

Yeah, was just going from how it's recorded in the tab. is_bottle is better for sure.

Indeed I saw and it is a sensible choice. But I think we should aim to return data and names that are intuitive. The less confusion, the less support tickets and emails. Also intuitive is what nice people do to their APIs.

Member

mxcl commented Aug 16, 2012

Maybe it should be an option. My thinking was, since this is an interface which can return more than one item, it's better for the consumer to consistently get an array than to sometimes get an array and sometimes not.

I usually aim for the 80% rule with API design. 80% of the time people are not requesting multiple datas, don't punish those guys by forcing them to deal with arrays.

Ditto [] vs null, cf. the Twitter API:

Having worked extensively against the Twitter API I really must say, it is not something to use as an example. However the null/[] is an opinionated topic, I think all we should insist upon is consistence. Use null for absent non-array datas though.

@mxcl It's not that it was installed from a bottle; it's that it can be used to create a bottle i.e. from a bottle or built with the generic CFLAGS.

Oh okay. Then: "built_as_bottle" makes more sense.

Yeah, was just going from how it's recorded in the tab. is_bottle is better for sure.

Indeed I saw and it is a sensible choice. But I think we should aim to return data and names that are intuitive. The less confusion, the less support tickets and emails. Also intuitive is what nice people do to their APIs.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 16, 2012

Member

My experience of working against APIs is that very rarely does anyone give much thought or test for edge cases. It is important for us to do that work and not push it onto every single consumer. To lower the WTF-count is to craft a beautiful API.

Member

mxcl commented Aug 16, 2012

My experience of working against APIs is that very rarely does anyone give much thought or test for edge cases. It is important for us to do that work and not push it onto every single consumer. To lower the WTF-count is to craft a beautiful API.

@MikeMcQuaid

This comment has been minimized.

Show comment
Hide comment
@MikeMcQuaid

MikeMcQuaid Aug 16, 2012

Member

build_as_bottle works for me. I'll move new tabs to use that but still work with the old value.

Member

MikeMcQuaid commented Aug 16, 2012

build_as_bottle works for me. I'll move new tabs to use that but still work with the old value.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 16, 2012

Member

But! build_as_bottle is not right! built_as_bottle is right! It refers to the state, not the pre-install intent.

Member

mxcl commented Aug 16, 2012

But! build_as_bottle is not right! built_as_bottle is right! It refers to the state, not the pre-install intent.

@MikeMcQuaid

This comment has been minimized.

Show comment
Hide comment
@MikeMcQuaid

MikeMcQuaid Aug 16, 2012

Member

Sorry, typo. I'm more careful with my code than GitHub comments. I meant built_as_bottle works for me.

Member

MikeMcQuaid commented Aug 16, 2012

Sorry, typo. I'm more careful with my code than GitHub comments. I meant built_as_bottle works for me.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 17, 2012

Contributor

Having worked extensively against the Twitter API I really must say, it is not something to use as an example.

Ha. Very true!

However the null/[] is an opinionated topic, I think all we should insist upon is consistence. Use null for absent non-array datas though.

Personally I prefer [] over null but I'll defer if I'm outvoted. Agreed re: consistency.

Used null over false for other values where appropriate.

(Sigh at the wonky ordering, but I guess it doesn't need to be pretty for humans. ;) )

{
  "linked_keg": "1.10.1",
  "options": [

  ],
  "homepage": "http://defunkt.io/hub/",
  "name": "hub",
  "versions": {
    "bottle": null,
    "stable": "1.10.2",
    "devel": null,
    "head": "HEAD"
  },
  "conflicts_with": [

  ],
  "github_history": "https://github.com/mxcl/homebrew/commits/master/Library/Formula/hub.rb",
  "keg_only": false,
  "installed": [
    {
      "version": "1.10.0",
      "built_as_bottle": false,
      "used_options": [

      ]
    },
    {
      "version": "1.10.1",
      "built_as_bottle": false,
      "used_options": [

      ]
    },
    {
      "version": "1.8.4",
      "built_as_bottle": false,
      "used_options": [

      ]
    }
  ],
  "caveats": null,
  "dependencies": [

  ]
}
Contributor

mistydemeo commented Aug 17, 2012

Having worked extensively against the Twitter API I really must say, it is not something to use as an example.

Ha. Very true!

However the null/[] is an opinionated topic, I think all we should insist upon is consistence. Use null for absent non-array datas though.

Personally I prefer [] over null but I'll defer if I'm outvoted. Agreed re: consistency.

Used null over false for other values where appropriate.

(Sigh at the wonky ordering, but I guess it doesn't need to be pretty for humans. ;) )

{
  "linked_keg": "1.10.1",
  "options": [

  ],
  "homepage": "http://defunkt.io/hub/",
  "name": "hub",
  "versions": {
    "bottle": null,
    "stable": "1.10.2",
    "devel": null,
    "head": "HEAD"
  },
  "conflicts_with": [

  ],
  "github_history": "https://github.com/mxcl/homebrew/commits/master/Library/Formula/hub.rb",
  "keg_only": false,
  "installed": [
    {
      "version": "1.10.0",
      "built_as_bottle": false,
      "used_options": [

      ]
    },
    {
      "version": "1.10.1",
      "built_as_bottle": false,
      "used_options": [

      ]
    },
    {
      "version": "1.8.4",
      "built_as_bottle": false,
      "used_options": [

      ]
    }
  ],
  "caveats": null,
  "dependencies": [

  ]
}
@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 17, 2012

Contributor

(Also only displays a single record rather than a one-item array when called with a single formula.)

Contributor

mistydemeo commented Aug 17, 2012

(Also only displays a single record rather than a one-item array when called with a single formula.)

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 21, 2012

Member

Looks sweet now. Push!

We should have an option for always-array IMO. It's the sort of option I would look and hope for then grumble if it isn't there and not submit a patch.

Possibly --[], though quirky.

Member

mxcl commented Aug 21, 2012

Looks sweet now. Push!

We should have an option for always-array IMO. It's the sort of option I would look and hope for then grumble if it isn't there and not submit a patch.

Possibly --[], though quirky.

@adamv

This comment has been minimized.

Show comment
Hide comment
@adamv

adamv Aug 21, 2012

Contributor

I want to read through this; quick take: always have a top-level object (instead of array) and key like {'name': {stuff}}. At least, for web APIs. I'll review this unless it gets pushed first.

Contributor

adamv commented Aug 21, 2012

I want to read through this; quick take: always have a top-level object (instead of array) and key like {'name': {stuff}}. At least, for web APIs. I'll review this unless it gets pushed first.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 21, 2012

Member

It is typical, I guess, to have a top-level {}. However I have to say, I've never understood that. It's a little tedious to always have to consume extra data layers that you don't need; and–at least for now–we are not a web-service.

As an aside: I find this output more legible than the default brew info output. Great job @mistydemeo!

Member

mxcl commented Aug 21, 2012

It is typical, I guess, to have a top-level {}. However I have to say, I've never understood that. It's a little tedious to always have to consume extra data layers that you don't need; and–at least for now–we are not a web-service.

As an aside: I find this output more legible than the default brew info output. Great job @mistydemeo!

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Aug 21, 2012

Contributor

@mistydemeo I like the output, especially that it is JSON.

@mxcl Personally I don't like --[] because of shell metacharacter expansion issues (not all shells have noglob, natch). But I can just avoid using that option :).

Is there a guide or code I should read about how I could use the info sub-command as a library rather than shelling out to get direct access to the JSON? My use case for this is in a Chef cookbook library.

Thank you all!

Contributor

jtimberman commented Aug 21, 2012

@mistydemeo I like the output, especially that it is JSON.

@mxcl Personally I don't like --[] because of shell metacharacter expansion issues (not all shells have noglob, natch). But I can just avoid using that option :).

Is there a guide or code I should read about how I could use the info sub-command as a library rather than shelling out to get direct access to the JSON? My use case for this is in a Chef cookbook library.

Thank you all!

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 21, 2012

Member

@jtimberman there is no documentation, but this will work:

HOMEBREW_LIBPATH = "#{`brew --prefix`.chomp}/Library/Homebrew"
$:.unshift(HOMEBREW_LIBPATH)
require 'global'
require 'cmd/info'
$:.delete(HOMEBREW_LIBPATH)

#then:
Homebrew.info(args)

For brew2 I'm making this far more sensible (than having to import so much and having to add a crappy path with generically named files in it to your library path.

However the info command is probably no use, so scrap requiring it and just Formula.factory(name) and query them directly for the information you need.

IMO safest bet at this point is to use the JSON output. The Formula class is not stable (we will stabilize it 1.0, maybe. More likely we will make a stable library or something that has another Formula class in it). The JSON response however is firm from the point we commit it.

Though having said this I think we should declare it non-stable and require you to pass --json=v1 in order to get this output, then deprecate that at Homebrew-1.0. This gives us flexibility. So what I'm saying is: --json=v1 will always output the form we are about to commit.

Member

mxcl commented Aug 21, 2012

@jtimberman there is no documentation, but this will work:

HOMEBREW_LIBPATH = "#{`brew --prefix`.chomp}/Library/Homebrew"
$:.unshift(HOMEBREW_LIBPATH)
require 'global'
require 'cmd/info'
$:.delete(HOMEBREW_LIBPATH)

#then:
Homebrew.info(args)

For brew2 I'm making this far more sensible (than having to import so much and having to add a crappy path with generically named files in it to your library path.

However the info command is probably no use, so scrap requiring it and just Formula.factory(name) and query them directly for the information you need.

IMO safest bet at this point is to use the JSON output. The Formula class is not stable (we will stabilize it 1.0, maybe. More likely we will make a stable library or something that has another Formula class in it). The JSON response however is firm from the point we commit it.

Though having said this I think we should declare it non-stable and require you to pass --json=v1 in order to get this output, then deprecate that at Homebrew-1.0. This gives us flexibility. So what I'm saying is: --json=v1 will always output the form we are about to commit.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 21, 2012

Contributor

@mxcl That won't work, it all goes to stdout. (Also, it doesn't take args, it checks ARGV.)

@jtimberman Once I push this patch, you can get the output as a hash this way:

HOMEBREW_LIBPATH = "#{`brew --prefix`.chomp}/Library/Homebrew"
$:.unshift(HOMEBREW_LIBPATH)
require 'global'
require 'cmd/info'
$:.delete(HOMEBREW_LIBPATH)

Homebrew.hash_formula Formula.factory(your_formula)

Still not terribly convenient I'm afraid but it's something?

Maybe I should let .hash_formula take a string argument.

@mxcl For the array argument, how about --as-array or --array, if we go with an array?

I guess I'm kind of undecided on a top-level {}, but I can see where, when retrieving info on many formulae, it would be more convenient to access by name rather than by index.

Contributor

mistydemeo commented Aug 21, 2012

@mxcl That won't work, it all goes to stdout. (Also, it doesn't take args, it checks ARGV.)

@jtimberman Once I push this patch, you can get the output as a hash this way:

HOMEBREW_LIBPATH = "#{`brew --prefix`.chomp}/Library/Homebrew"
$:.unshift(HOMEBREW_LIBPATH)
require 'global'
require 'cmd/info'
$:.delete(HOMEBREW_LIBPATH)

Homebrew.hash_formula Formula.factory(your_formula)

Still not terribly convenient I'm afraid but it's something?

Maybe I should let .hash_formula take a string argument.

@mxcl For the array argument, how about --as-array or --array, if we go with an array?

I guess I'm kind of undecided on a top-level {}, but I can see where, when retrieving info on many formulae, it would be more convenient to access by name rather than by index.

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Aug 21, 2012

Contributor

@mistydemeo Cool, that's working.

Noting this for myself because I'll refer back to this issue when I update our cookbook to use this:

require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut

brew = shell_out!("brew --prefix")
HOMEBREW_LIBPATH = File.join(brew.stdout.chomp, "Library", "Homebrew")
$:.unshift(HOMEBREW_LIBPATH)

require 'global'
require 'cmd/info'

pkg_info = Homebrew.hash_formula(Formula.factory("package_name"))
pkg_info['versions']['stable']

Thanks!

Contributor

jtimberman commented Aug 21, 2012

@mistydemeo Cool, that's working.

Noting this for myself because I'll refer back to this issue when I update our cookbook to use this:

require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut

brew = shell_out!("brew --prefix")
HOMEBREW_LIBPATH = File.join(brew.stdout.chomp, "Library", "Homebrew")
$:.unshift(HOMEBREW_LIBPATH)

require 'global'
require 'cmd/info'

pkg_info = Homebrew.hash_formula(Formula.factory("package_name"))
pkg_info['versions']['stable']

Thanks!

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Aug 21, 2012

Contributor

Of course, at this point you could also go straight to the formula object itself, unless you like getting everything as a hash:

require 'global'

pkg = Formula.factory 'package_name'
pkg.stable.version

Depends on how much information you're looking for; we do do a little preprocessing for some of the other values so it the hash may still be easier.

@mxcl Thinking it may be worthwhile for Homebrew.hash_formula foo to become Formula#to_hash.

Contributor

mistydemeo commented Aug 21, 2012

Of course, at this point you could also go straight to the formula object itself, unless you like getting everything as a hash:

require 'global'

pkg = Formula.factory 'package_name'
pkg.stable.version

Depends on how much information you're looking for; we do do a little preprocessing for some of the other values so it the hash may still be easier.

@mxcl Thinking it may be worthwhile for Homebrew.hash_formula foo to become Formula#to_hash.

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Aug 21, 2012

Contributor

@mistydemeo Oh, nice! That actually works for my use case as is (without the json patch). Though the JSON patch will be awesome too, for non-Ruby language use.

Contributor

jtimberman commented Aug 21, 2012

@mistydemeo Oh, nice! That actually works for my use case as is (without the json patch). Though the JSON patch will be awesome too, for non-Ruby language use.

@mxcl

This comment has been minimized.

Show comment
Hide comment
@mxcl

mxcl Aug 22, 2012

Member

@mxcl Thinking it may be worthwhile for Homebrew.hash_formula foo to become Formula#to_hash.

Sounds sensible to me.

Member

mxcl commented Aug 22, 2012

@mxcl Thinking it may be worthwhile for Homebrew.hash_formula foo to become Formula#to_hash.

Sounds sensible to me.

@MikeMcQuaid

This comment has been minimized.

Show comment
Hide comment
@MikeMcQuaid

MikeMcQuaid Aug 25, 2012

Member

@mxcl Using built_as_bottle in 8837423.

Member

MikeMcQuaid commented Aug 25, 2012

@mxcl Using built_as_bottle in 8837423.

@mistydemeo

This comment has been minimized.

Show comment
Hide comment
@mistydemeo

mistydemeo Sep 18, 2012

Contributor

Geeze, didn't realize I'd lost track of this this long. Merged, with --json=v1 and the hash method moved to Formula#to_hash.

Contributor

mistydemeo commented Sep 18, 2012

Geeze, didn't realize I'd lost track of this this long. Merged, with --json=v1 and the hash method moved to Formula#to_hash.

@jtimberman

This comment has been minimized.

Show comment
Hide comment
@jtimberman

jtimberman Sep 18, 2012

Contributor

Awesome, thank you! <3

Contributor

jtimberman commented Sep 18, 2012

Awesome, thank you! <3

Sharpie pushed a commit to Sharpie/homebrew that referenced this issue Sep 23, 2012

info: Add JSON output
Output JSON with the --json=v1 option. Output is in an array, and
supports one or more formulae (or all, with the --all option).

Why 'v1'? The format is unstable, presumably we'll deprecate it
someday. It should be solid by Homebrew 1.0.

Closes #13299.

snakeyroc3 pushed a commit to snakeyroc3/homebrew that referenced this issue Dec 17, 2012

info: Add JSON output
Output JSON with the --json=v1 option. Output is in an array, and
supports one or more formulae (or all, with the --all option).

Why 'v1'? The format is unstable, presumably we'll deprecate it
someday. It should be solid by Homebrew 1.0.

Closes #13299.

@Homebrew Homebrew locked and limited conversation to collaborators Feb 16, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.