Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
11.86k stars 578 forks source link

Add support for Spoon metadata #2101

Closed cmsj closed 1 month ago

cmsj commented 5 years ago

We finally need to do something about machine-readable metadata in Spoons, because of the plan to release 1.0 and then move to 2.0.

Even though we have an informal convention to put some metadata on the Spoon object, that is no good here because code can/will already be executing when that metadata becomes available.

So, my plan is that Spoons should also have a simple JSON file with the name/author/license/version. The Spoon loader could also use this info to populate the equivalent properties of the Spoon object.

Most crucially though, is that the JSON format needs to be able to describe which versions of Hammerspoon a given Spoon works with. This could be as simple as:


{
  "supports_v2": true
}

but I wonder if it might make sense to do something like:

{
  "supports": [1, 2]
}
asmagill commented 5 years ago

IIRC, there is already support in hs.spoon to check for a docs.json file and load it into the inline help... what about just extending that?

cmsj commented 5 years ago

We could do that, although docs.json is currently treated as a transient file that is regenerated automatically from the code, so we'd need to have special comment syntax in the init.lua to contain the metadata. I don't have a strong preference right now.

cmsj commented 5 years ago

So there's one spectacular problem with this idea - once you've done require("foo") you have no idea where foo came from. We could force Spoons to only live in the config directory, but that's going to surprise anyone fiddling around with package.path. The only other solution I can think of is to require that all Spoons have at least one predictable method name, so we can use debug.getinfo() to find their path. Darn.

cmsj commented 5 years ago

Never mind, there's a pretty easy way to figure out where the Spoon lives:

package.searchpath("Caffeine", package.path)
cmsj commented 5 years ago

We now automatically inject the path of Spoons as spoon.NAME.spoonPath and also create a spoon.NAME.spoonMeta which is either an empty table, or whatever data is in a meta.json file in the Spoon's path. I haven't yet decided how to handle version support, so for now there's nothing for that yet. Currently thinking maybe a minimum_version key in the meta.json.

asmagill commented 5 years ago

This brings to mind that we need a clear cut way to compare the version of Hammerspoon against something that works correctly with the version possibly having point releases... i.e. something that properly identifies “1.1” as less than “1.1.2”, etc.

I took a crack at it a while back when trying to integrate Mjolnir with LuaRocks and you can see it at https://github.com/asmagill/hammerspoon_asm/blob/master/extras/init.lua#L227 but its been awhile and I don’t recall if I was happy with it or if it was buggy... I can take a closer look this weekend and clean it up so we can get it or something similar in now before starting the 2.0 branch.

latenitefilms commented 5 years ago

FYI - we use this in CommandPost: https://github.com/kikito/semver.lua

cmsj commented 5 years ago

@asmagill my plan for the spoons was just to have a major version number. It's mostly a way for HS 2.0 to refuse to load a Spoon that hasn't been converted over to new stuff, so I was thinking:

(also good news, Lua 5.4.0 will return a second argument from require(), giving the path it found the file at, so my hack can come out at that point)

asmagill commented 5 years ago

@cmsj, re spoons and most users, that's probably sufficient... however, I still think a good, consistent version checker might be a useful addition for the same reasons Python and Perl allow specifying minimum versions of modules they use. A prompt that I need to upgrade Hammerspoon to use such-and-such is much nicer than console messages about missing functions/methods or being unable to resolve symbols when loading the compiled portion of the module.

In this specific case I'm envisioning the developer adding code (hopefully only one or two lines) to the head of their script/spoon which checks the version number and bails or uses an alternate code path (if wanting to support multiple versions of Hammerspoon) rather than making it an automatic part of the loading process.

I won't make it a priority then, but I'll still take a look at @latenitefilms suggestion and my previous attempt and see what looks most promising.

Also not a priority and only tangentially related, but it might also be worth giving some thought to being able to add a compile time label (perhaps built from the git branch name and reference hash?) which would allow those of us building development versions to differentiate when we're running a stock version vs an "in progress" development version... something like hs.processInfo.buildTag so that with the hs.processInfo.version and the label, the specific build of Hammerspoon could be determined... it would be more useful if we had a beta track or shared our development builds for wider testing, but if it's not too difficult, I may look into adding that as well.

cmsj commented 5 years ago

@asmagill I'm definitely not opposed to carrying more info about the version/build, although I mostly think people should just run the latest version and we (and Spoon authors) shouldn't jump through hoops to help out the people who refuse to run the latest version. If people want to do that, that's up to them, but ain't nobody getting paid for this :D

cmsj commented 5 years ago

(Also I'm pretty sure I did some kind of magic in another project I was working on, to get monotonically increasing build numbers, I'll see if I can dig that up, and apply it to HS, because having the version number repeated in the build number is basically worthless)

Edit: Although I have two Macs I do builds on, which could cause issues, I suppose, so maybe a git hash would make more sense.

asmagill commented 5 years ago

I can imagine the possibility of leaving one of my machines running 10.14 for the foreseeable future, depending whether or not certain microcontroller build chains get updated to 64 bit, so the possibility of me running two out of sync versions as 10.14 slowly reaches our "3 version" cutoff becomes a possibility (granted not for awhile yet)... but I agree in principal -- we definitely shouldn't require our contributors to worry about peopler running outdated versions of Hammerspoon, but if they choose to, I think the tools to make it easier should be available, if it's not a lot of effort on our part.

cmsj commented 5 years ago

+1

cmsj commented 5 years ago

As of 5b3303ed we'll now set the build number to the current number of commits, in Release builds only, to the current number of commits on the current branch (ie master). This is a number that will only ever increase, if we all agree never to do a git push -f (which we ought to be avoiding already anyway). Happy to include dev builds too, but since it touches a file in a repo, it means more noise in commits, so probably not wanted.

cmsj commented 5 years ago

Nice things about this: