neovim / packspec

ALPHA package dependencies spec
http://packspec.org/
Apache License 2.0
221 stars 2 forks source link

Format of `source` #8

Closed mjlbach closed 2 years ago

mjlbach commented 2 years ago

Source object should be consistent. (stolen) proposal:

lewis6991 commented 2 years ago

Example?

wbthomason commented 2 years ago

To clarify: you are not suggesting unifying all source information for dependencies and the package into a single object, but rather using the same schema for all source objects across all dependencies and the package?

mjlbach commented 2 years ago

To clarify: you are not suggesting unifying all source information for dependencies and the package into a single object, but rather using the same schema for all source objects across all dependencies and the package?

Yes, see below:

Current:

source = {
  url = "git://github.com/neovim/nvim-lspconfig.git",
}
...
dependencies = {
   neovim = {
      version = ">= 0.6.1",
      source = "git://github.com/neovim/neovim.git"
   },
   gitsigns = {
      version = "> 0.3",
      source = "git://github.com/lewis6991/gitsigns.nvim.git"
   }
}

Proposed:

source = {
  url = "git://github.com/neovim/nvim-lspconfig.git",
}
...
dependencies = {
   neovim = {
      version = ">= 0.6.1",
      source = {
        url = "git://github.com/neovim/neovim.git",
      }
   },
   gitsigns = {
      version = "> 0.3",
      source = {
        url = "git://github.com/lewis6991/gitsigns.nvim.git",
      }
   }
}
ii14 commented 2 years ago

Why source is a table, can't it just be a string everywhere?

mjlbach commented 2 years ago

So there can be additional fields. @wbthomason was interested in possibly a "tag" vs "release" vs "commit" based specifier additionally.

ii14 commented 2 years ago

Can't it be a union type, string|table?

mjlbach commented 2 years ago

It could, but given that this is supposed to only ever be used by machines (and possibly generated by a template generator) should we not prefer as simple a structure as possible?

lewis6991 commented 2 years ago

+1 for union types as that will make the common case simpler.

Canonical form will be a table.

lewis6991 commented 2 years ago

Also doesn't tag/release/commit conflict with the version?

mjlbach commented 2 years ago

I think the question was how to specify how the plugins are versioned, as in, they use tags or commits, maybe @wbthomason can clarify

wbthomason commented 2 years ago

@lewis6991 Yes, the intent of specifying tag, etc. here was to tell the plugin manager where to look, not what to look at (which is specified by the version). This could be confusing - perhaps we should have:

  1. A string | table union type for the source field
  2. A common-case assumption that plugins are versioned with tags
  3. A field type = 'tag' | 'branch' (not sure if we can specify commits as a versioning model here; I don't know how to resolve a SemVer spec to a commit. If we do want to allow commits here, then the field should instead be one of tag = true, branch = true, or commit = <hash>).
mjlbach commented 2 years ago

@wbthomason could we use commit as a way to specify the lower bound on the commit since we are checking out the git repos anyways? Might be overcomplicated

wbthomason commented 2 years ago

Yeah, we can use commit to specify version lower bounds, but the question is more how to go from a SemVer to a commit (if we're using SemVers for most version bounds), right?

mjlbach commented 2 years ago

We could allow specifying the commit range if using the commit tag for versioning. I would recommend we pressure people into semver though.

lewis6991 commented 2 years ago

Proposal

Example:

dependencies = {
   neovim = {
      version = ">= 0.6.1",
      -- tag = "0.6.1",  -- LEGAL
      -- tag = ">= 0.6.1",  -- ILLEGAL
      url = "git://github.com/neovim/neovim.git",
   },
   gitsigns = {
      branch = 'new_feature',
      url = "git://github.com/lewis6991/gitsigns.nvim.git",
   }
   impatient = {
      commit = '04f16a5' ,
      url = "git://github.com/lewis6991/impatient.nvim.git",
   }
}

Illegal example:

dependencies = {
   neovim = {
      version = ">= 0.6.1",
      branch = "v0.6.1", -- ILLEGAL as version is already specified.
      url = "git://github.com/neovim/neovim.git",
   },
}
ii14 commented 2 years ago

Just throwing an idea out there, what about merging tag, branch and commit into a single revision field? And then you could specify ranges like 04f16a5.., v0.5.0^..v0.6.1, branch_a..branch_b etc.

I don't know how easy would that be to implement, because you'd probably want it to be a subset of what git has.

lewis6991 commented 2 years ago

I don't mind merging tag, branch and commit into revision, but that should be separate from version.

mjlbach commented 2 years ago

I feel like that is going to be hard to parse, also what are the semantic of branch_a..branch_b?

Iamafnan commented 2 years ago

Hey for what thing this meta data will be used in future?

ii14 commented 2 years ago

@mjlbach I don't think parsing is the hard part necessarily. The problem is that I think the meaning can change based on the context, so some things I think can be ambiguous. And also you generally don't want to give people the ability to specify remotes, HEAD, relative dates and stuff like that. Or it could just be a naive implementation, split the string on .., resolve lhs and rhs with git, and tell people not to do stupid things.

Not 100% sure, but it looks like branch_a..branch_b means just all commits from branch_a to branch_b that are reachable from branch_b.

ii14 commented 2 years ago

@Iamafnan to get compatible versions of dependencies. For example say there is dependency A and the latest version is 1.7. Some plugin can say "I want dependency A in at least version 1.5", and some other plugin "I also want dependency A, but I need version 1.6 specifically". The plugin manager can then get the dependency in version 1.6, or warn the user if the requirements can't be met.

mjlbach commented 2 years ago

The issue title is format of source, please do not hijack issue discussions to ask general questions.

ii14 commented 2 years ago

If we want to go with revision, we could just say what subset should be supported, and let the implementations decide if they want to do it in naive way, or something more advanced. And before we decide, we can come up with some implementation and see what the problems exactly are.

mjlbach commented 2 years ago

I'm also not sure I see the need for anything but version right now, I think we can just stick with version, and not allow uesrs to specify a specific tag/branch as that will likely only introduce version conflicts.... (unless we do something like vim.dep which has a ton of technical challenges to sort out)

ii14 commented 2 years ago

I agree about tags, but I can see branches being useful. I guess right now we could just say that if you're using branches then it's probably for development, so deal with that outside of your package manager, or use some implementation defined extension

lewis6991 commented 2 years ago

So for now format is just a table with the fields url and version and version uses tags for git?

And we remove source as a field?

wbthomason commented 2 years ago

As long as we establish the convention of version using only tags, that seems reasonable to me.

mjlbach commented 2 years ago

How do we handle the case of allowing master? If there is a lower bound on version ( > 0.5) does that mean that only tagged releases are valid, or the plugin can also choose to depend directly on the latest git revision.

wbthomason commented 2 years ago

Maybe:

mjlbach commented 2 years ago

I feel like there probably should be a distinction between unbounded upper versions (preferring the latest release) and unbounded upper versions included the latest commit, but I cannot think of an elegant way to do that without just adding an additional field (like prefer_tag = true)

wbthomason commented 2 years ago

If we do add another field, I'd nominate releases_only = true | false.