-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Enhancement request: integrated package manager #491
Comments
Right now this seems far off, though I agree that the most important bits are close. I'm very tempted by the NixOS model, and I tend to think that the only reason every HLL nowadays has its own pkg mgr is that the OS pkg mgrs are all awful in so many ways. A situation that makes me want to tackle packaging in general, but it's been done so much, so often that it seems like a recipe for failure. A very frustrating situation, this. Adding one more HLL pkg mgr to the mess is not appealing either, though it is the tradition now, and it may be unavoidable. |
@wtlangord - Elsewhere you wrote:
I've begun working on a prototype standalone package manager for jq. It's modeled closely on Julia's package system, with some influences from homebrew. In a nutshell, the main idea is to use git/github (or equivalent) so that Pkg::add("Stats") would clone the Stats repository, making the Stats module readily available via a simple "import Stats;" command without the user having to know where the remote repository or the local clone are located. To make this work nicely requires that the local clones of jq repositories have a per-user home. Julia uses $HOME/.julia/ for this purpose. The current version of Julia's package specification is version v0.3, so the package Xyzzy would actually be in the directory $HOME/.julia/v03/ and we would expect to see a subdirectory such as $HOME/.julia/v03/Xyzzy/.git My prototype has been using a similar scheme, but there are several issues which I hope you and @nicowilliams will have the time to help resolve. The first issue stems from the fact that $HOME/.jq has already been appropriated. Even though it may eventually become available for other purposes, it would be better to find an alternative name. To avoid prejudicing you, I'll refer to this directory as the "distinguished directory". The second issue stems from the goal that the user be shielded from having to know where the "distinguished directory" is located. Since this directory also houses the metadata needed to locate requested packages (like homebrew), the key to the whole thing is jq having knowledge of its location. As I understand the current architecture of jq, this would require that when presented with a simple "import" directive, jq would (in the absence of contrary directives) first look for it in the "distinguished directory". Your thoughts? |
Well, yes and no. Your package manager could have a script that should be run in the user's bashrc/zshrc/etc, that sets As far as |
Some thoughts:
|
@nicowilliams and @wtlangford - thanks for your responses. I'll first work through Nico's points:
I'll certainly keep that in mind. (See e.g. (**) below.)
My initial focus with jqpm is on "registered packages". To be registered, a tiny amount of metadata has to be stored in a (git) "metadata repository", which Julia organizes by directory as follows:
That's it. The main advantage of this scheme is that updating details for one version can't break information about any another. I'd like to keep the scheme. Is JSON overkill?
Excellent, but please note: If Xyzzy is a registered package that works with jq 1.5 then when downloaded it will go in ~/.jq/v1.5/Xyzzy and so the toplevel .jq file would be (following Julia) ~/.jq/v1.5/Xyzzy/src/Xyzzy.jq. Even if the src/ segment is dropped, jq would have to know to look for Xyzzy.jq under Xyzzy. (**) Would
So far, there's been no sighting of curl. Just git (and hg :-) |
Using git has its appeal, yes. See the other discussions as to versioning. I'm a fan of putting the major version number in the module name, minor.micro in the metadata. Ideally the metadata would be in the .jq. Yes, we'd have to parse (but not execute) it to query it, but that seems reasonable. Any syntax errors would cause failure, and hopefully the module to be re-downloaded. Alternatively we could put the metadata in a .json file. Either way is OK, but I kinda like the first not least because it'd commit us to doing constant folding for constant As for using git, would that be: a git repo per-module? A set of repos containing complete sets of modules (e.g., a standard jq library that's not builtin to jq)? A repo per-module seems like overkill, but a single repo of all jq modules would be unwieldy. So I'm leaning to a set of repos. We'll really need hierarchy. Do we want to use Java-style reverse domain name hierarchies? Lots to think about. |
@nicowilliams wrote:
Fortunately, most of the thinking has been done for us by the brilliant creators of Julia! Their package management system is mature and as I've mentioned before, I believe it is (at many levels) a perfect fit for jq. (Julia also distinguishes between modules and packages.) Regarding package/repositories/modules, the fundamental principles are: a) every package is a repository (normally a git or mercurial repository); (*) So the big question is whether it would be feasible to allow a package to have more than one root module. Maybe there are alternatives that I've not considered, but it seems to me that going down that path would introduce unnecessary complexity. As I mentioned, the simplicity I'm aiming for is that:
will do whatever is needed to make it possible for the user to "load" Foobar.jq by simply writing:
Regarding JSON -- of course we can be more JSON-oriented if we want, but since jq processes streams of JSON entities so nicely, we don't have to restrict ourselves to a one-JSON-compound-entity per file mentality. |
Of course, it'd have to be a repo per-module, but I'd want a repo of blessed modules -- think git sub-modules. I'm thinking of something like Ubuntu repos: a set of blessed modules, ..., a set of contributed modules, with a single namespace for all, but a way to refer to specific ones in case of conflict. In a jq libdir we'd have:
One could then But this seems a bit like overkill unless we expect jq to gather much momentum. I guess I should now go look at Julia's pkg manager, eh? |
Incidentally, the jq pkg mgr could just be builtin to jq, needing only git to be in |
What you call jqpm could then be just |
OK, so, that's the concept I'd go with: a set of pkg repos which are git repos listing module<->{URL(s), HEAD hashes), in a directory hierarchy (or in a single JSON file that reflects that hierarchy). Or, if we can, we should avoid hierarchy? Locally a jq libdir would have a per-pkg-repo directory and below it the hierarchy of all installed pkgs. If there's a conflict between a "contrib" and "blessed" pkg, the latter wins, but one could Dependency mgmt should be relatively simple to write in jq, but it's easy to write depth-first searches, while we should prefer a breadth-first searches. Still, that's nothing. The most important infrastructure to finish for this is the I/O stuff. Which... I should get to, no? (Re: I/O, it's in reasonable shape, but I don't like the |
Thought I'd just chip in with some info on other package managers. NPM (4k+ stars on github) is used in an Node.js environment.
NPM inspired other package managers, like Bower (10k+ stars on github). Has thousands of packages. Both NPM and Bower (pretty much) require that packages are registered with a central service, which is a drawback. Component (3k+ stars on github) uses github for namespacing (by default) in their dependencies. Oh, and all three use json for configuration (package.json, bower.json, component.json), and semver for package versioning and dependency version selection. I like and use both NPM and Bower, both because the tools are good and the eco-system healthy. Don't have as much experience with Component, but the author @visionmedia does good things. Things move really, really fast in the javascript world - I'm sure there are other alternatives today, |
Should also add that NPM uses a deep dependency tree and keeps dependencies' dependencies (and their dependencies) as private packages in their respective Bower needs all dependencies' dependencies to play nice with each other in a flat dependency tree. This is in part because Bower is made for web browsers, and that those packages historically have mutated the global |
@joelpurra remarked:
jqpm (a script being developed as a prototype for what I hope will one day be a jq package named Pkg for a module of the same name) will support both "registered" and "unregistered" packages. The packages themselves can live just about anywhere, but I envision there will be a single official registry to distinguish "registered" from "unregistered" packages. This registry itself will be a git repository (think homebrew) but will only have a tiny amount of metadata. (It wouldn't be hard to support multiple registries, but I don't really see the need at this point, assuming there is support for unregistered packages.) jqpm will by design dovetail with jq, but I'm expecting that we can do better than that. My hope is that jq will (unless otherwise instructed) be able to locate any kind of package that (a) has been installed by jqpm; and (b) has been flagged as applicable to that particular version of jq. In addition (and this has nothing directly to do with jqpm), I believe that it would be highly desirable for jq (unless otherwise instructed) to be able to locate locally installed files or modules if they have been installed in a jq-defined location, whether with or without jqpm's involvement. @wtlangford and @nicowilliams might like to comment on whether this is likely to happen. A likely directory for such locally installed files is ~/.jq/local/. As for jqpm-supported "packages - to avoid name conflicts between registered and unregistered packages, I would like to adopt the following scheme, or one very similar to it:
The reasoning behind the "v1.4" for registered (but not unregistered) packages is that the registration process should entail some kind of check or at least claim (e.g. by the package author) that a particular version of the package is compatible with a particular M.N version of jq. One question I am still asking myself is:
Comments? |
Sorry in advance for not knowing more about Julia; I don't agree with much of what I understand Julia's package manager does upon a glance (like Again, look at the One key component is semver ranges (source), which basically removes any ambiguity in selecting a compatible dependency, a compatible engine and publishing your own package version. I consider following semver to be best practice anyways, as it's well defined. Packages can be installed in the current folder's I prefer packages to be really small, single-purpose and infinitely combinable - like legos. I'd also prefer a lower-case only package naming rule as Mac OS X's HFS+ is case-preserving but case-insensitive by default. ~/tmp $ mkdir A
~/tmp $ mkdir a
mkdir: a: File exists |
I'd prefer
See npm's 'package.json' 'engine', which also allows for semver ranges for both the
I'd prefer that unregistered/unnamespaced packages aren't "system-global" or "user-global" reference-able as package dependencies, but require a more specific path (relative/absolute folder, git/hg). |
Thanks for your interest and comments. The good news is that As you may know, I spent some time trying to find a Package Manager The main reason that I gravitated away from "out of the box" solutions So that leaves us with competing specifications. In principle we Anyway, as I came to learn more about Julia's package management Let me give a small illustration of why I think Julia's choice on a
This is in contrast to what I wrote:
From what you wrote, it seems that you have rejected the idea of using Or perhaps you misunderstood a key point here - that the "v1.4" is the |
Nope - I like git/hg repositories, and like tagging them with semver-formatted "v1.2.3" tags, and like that dependencies' version ranges point to such tags. But I see a problem in using a single directory per jq-version as opposed to package-version. Git can only handle one checked out commit (be it a tag or master) at a time, so this effectively would force all jq projects running on a single machine to use the same checked out version of a shared package. That is not an "acceptable" limitation to me, at this stage of developing a package manager. (Hope I didn't misunderstand Julia here.)
No misunderstanding. A user-level Assuming jq doesn't have a new release during the night:
I know that having just the one version of a library available system-wide is common in some languages. This is why I'm pointing towards npm, where any versions can exist in parallel, and even execute concurrently. Again, since a package's dependencies are private to the package in terms of scoping (as opposed to a single package instance in memory shared across all running code in a project), problems are greatly reduced.
Yes. This is why I pointed out the |
@joelpurra wrote::
jqpm installs packages on a per-user basis, not a per-machine basis. If a single user wants to have two processes running concurrently using the same version of jq but different combinations of module-version numbers, then he or she should probably have two different accounts, just to retain his or her sanity. Better yet would be to avoid those troublesome modules until they're fixed.
jqpm's goal is to be able to work seamlessly with jq (and in particular, the "import" statement), without requiring any configuration.(*) Currently jq's import statement is very restrictive. I believe some of the complexity you have in mind would require significant changes on the jq side. Anyway, it might be helpful if you could discuss the assumptions you're making about jq and especially the "import" statement. (*) E.g.:
Of course, so long as jq cannot itself run git/hg, directly or indirectly, there will be limitations on what a jq program can do by itself. |
@joelpurra - Would you have time to write a simple (bash?) script to prototype a jq-oriented package manger that actually uses npm (or bower)? Let's call such a script jqnpm (or jqbower). The main idea would be to use the fact that jq now heeds the JQ_LIBRARY_PATH environment variable. As @wtlangford pointed out, this allows us to simulate a certain degree of integration between jq and the package manager. If you were able to do that, it would be tremendously helpful in several respects. For example, I think it would give greater insights into the pros and cons of actually using npm (or bower) in this context, and it should help pinpoint the changes (if any) that would be required on the jq side under various scenarios. Thanks! |
@wtlangford wrote:
(I'd also appreciate @nicowilliams' comments about the following.) The work on the jqpm protoytpe is coming along quite nicely (from a certain perspective), but I'd like to make sure that we're all on the same page regarding the goal that, when given "import Shazam", jq will be able to locate "Shazam.jq" very quickly and without any user-initiated configuration. There are actually two related issues here but let's review the main scenario first.
Of course we could use JQ_LIBRARY_PATH to tell jq where to look for Shazam in particular, but for numerous reasons, we don't want to go down that path. One possibility to consider would be to allow * in JQ_LIBRARY_PATH. E.g.
There are two problems with that:
Luckily, the solution is trivial:
That is, no search should be required to find an installed registered package. The other part of the question here concerns "unblessed" metadata repositories. Suppose, for example, that github/shady/jq.metadata is such a repository, and that there is a Shazam package (maybe the same one as before, maybe not) registered there too. Then jqpm will happily install the Shazam package registered at shady in ~/.jq/shady/Shazam/. Let's call the "shady" segmant of the path the "channel". Personally I don't see the need for jq to provide any special support for unblessed channels, EXCEPT that it would be nice if there were an option to specify which directory under ~/.jq it should regard as the "blessed" directory. This would be useful for testing purposes. Once one has a "--blessed NAME" option, though, the question arises as to whether one should be able to use it to specify more than one channel. Anyway, to summarize the main points:
|
I'll see if I can squeeze it in, but can't promise.
I'd rather see that the dependency has a config file (say Oh, and I forgot to mention that when you're talking about In the words of the npm creator, @isaacs: http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation
|
@joelpurra wrote:
In a sense, "Shazam.jq" is the config file. It can do whatever it likes. Of course, that is at the moment quite limited, but the work on enhanced I/O is well underway, and it seems likely that the "module" directive will also allow a JSON component. (On the last point I'd like to ask @nicowilliams and @wtlangford: has there been any discussion about how a jq program will be able to access a module's JSON component?) In any case, if there were a separate per-package jq.json file, jq would have to (a) know how to find it; and (b) know what to do with it. Both would require changes to jq beyond those that have been under discussion. Also, please note that for the time being, I would like to avoid deviations from the Julia model unless either (a) there is general agreement that it is necessary for technical reasons or for compatibility with jq 1.5; or (b) the folks at Julia plan a deviation themselves :-) Thanks! |
@joelpurra Modules would be libraries -- only defs, no top-level. Though they could define a Modules that are meant to be programs should just go in a bindir somewhere. It might be a good idea to have one pkg manager for library and program modules. Hmmm, well, there's a lot to think about here. For now I'm working on this:
where the name is an identifier (though, is it necessary? we can get it from the file path/name), and the metadata is a constant-valued jq expression. Then:
where is of similar form to module metadata and must "match" for some definition of "match". The metadata would be an object, obviously, with keys like "version" with an object value with keys like "major", "minor", and "micro" with numeric values. Though I'd also allow "version" to have a numeric value instead, in which case a) the major version is part of the module name (as I think it should be), b) the minor version is the floor of the number, and c) the micro version is the decimal portion of the number. Matching would be: name and major version (if given) must match, minor must be at least the given one, and micro must be at least the given one if minor matches exactly. There'd be a builtin which takes module names (strings) as inputs and outputs their metadata. I.e., the metadata is inside the module and jq will let you read it. Another / the same builtin would allow you to read dependency metadata. The pkg manager could (would) then use this to query modules' metadata: their version and dependency information. I'm also thinking of a meta-module named jq by which to express dependencies on jq versions. I don't understand the "no search" comment. I don't want to have to have a jq version in the search path. I don't think jq should change so drastically that this should be necessary. It will suffice to have semantic versioning for modules and a way to express dependencies on jq versions. In the jq libdir search list we'd have a directory per jq module, with the module code living in a .jq file. Putting it all together we'd have:
Arbitrary metadata would be allowed. Missing version info would be allowed too, why not. What if we need multiple versions of a module installed? What do we do about DLL Hell? A version museum might be necessary. In which case we probably do need a search by version, and we'd have a hierarchy a bit more like:
It's important to have the module name match a directory in the filesystem: so that it can be a git/whatever repo/workspace if that's desired. But I'd also allow Deep hierarchies would be allowed. It's a small change to the lexer to allow arbitrary components separated by Thoughts? |
FYI, I have |
I think it will be a short hop and a skip to do the remaining bits of core work. |
I have all of that working, save for new tests and docs. The |
See: https://github.com/nicowilliams/jq/compare/module?expand=1 @wtlangford Care to review these changes? |
On Mon, Aug 18, 2014 at 11:38 AM, Nico Williams nico@cryptonector.com wrote:
Oh, I misunderstood you. Anyways, as I explained, I want a I can make the ambiguity go away, by getting rid of the "any" location @wtlangford, thoughts? |
@nicowilliams wrote:
Just to be clear, the main issue with -L at the moment is illustrated by this test case:
So in the following, I'll assume that you want to have a single location for both "non-versioned" packages and modules. Is that assumption correct? Regarding "any" and the potential for ambiguity: First, I like your choice of the name "any". Assuming you still want a single "-L"-based mechanism for finding files and modules, then I think the following search order for finding Foo.jq given "-L PATH" would be OK:
That way, "import any::bar ..." would cause jq to go hunting in: 1a. PATH/any/bar.jq That actually seems fine to me, but to alleviate any concerns about this, it is worth point out that: (*) The use of the name "any" for a package name could be disallowed, in the sense that jq could simply skip both 2a and 3a in the special case of "import any:_". (**) The maintainers of the official metadata repository could simply ensure that (3a) would not normally exist. Pragmatically, I think that (**) should be more than enough. |
On Mon, Aug 18, 2014 at 11:22:25AM -0700, pkoppstein wrote:
The This has nothing to do with the "any" thing.
Not a "single" one, no. I want locations that aren't versioned so that
The ambiguity was the result of choosing "next" for the I'll just remove "any" then. |
Whoops, I gave the wrong example. Sorry about that. See (**) below. At the moment I'm more concerned about non-versioned local modules. On the one hand, you wrote:
But then you wrote:
To support non-versioned packages properly, jq has to be able to find them, and the idea is that jq should be able to do so without requiring any special configuration. That's why I like your idea of using the name "any", but the particular name is not as important as the principle. (**)
|
So, I'm back from a long couple of weeks. There's a lot happening here and that's quite exciting! Looks to me like we've got an issue where we aren't sure how to handle modules that don't care about the jq version they were installed under/for? Have I missed something? |
@wtlangford asked:
Welcome back! The short answer to your question is "yes". It would be difficult to recapitulate everything, but I would ask that you look at the Julia package management system (http://julia.readthedocs.org/en/latest/manual/packages/) if you haven't already done so. The jqpm prototype that I've been working on is still closely based on that. And for good reason. @nicowilliams doesn't like my use of the word "channel" in this context but an important distinction to be made is between different "channels" of package metadata. (This is not to be confused with the different "providers" of the packages themselves.) The idea is that there could be at least one "official channel" for Package metadata, as well as many "unofficial ones". It is still my hope that jq and whichever package manager is ultimately used (whether implemented in jq or not) will work together seamlessly, and with NO configuration required to use "officially sanctioned" packages (i.e. packages whose metadata is included in the "official channel"). (@nicowilliams has used the term "blessed" in this context.) p.s. See also https://sublime.wbond.net/docs/channels_and_repositories |
I did? Anyways, take a look at the commits I pushed tonight. |
@pkoppstein I should say I didn't remove "any/", I just made it the empty string. So now jq searches in these locations for each directory in the search path:
When 1.5 ships it will be:
And master after that will use:
|
@nicowilliams wrote:
Thanks for restoring the normal -L behavior. I like the "*-master" convention too. However I am troubled by (2) in the search order: (1) $dir/mod.jq First, that is a recipe for cluttering .jq. In any case, I would appreciate it if you could let me know the answer to the following question. If "snoopy" is a metadata repository that provides metadata for a package named Peanuts, and if "linus" is a metadata repo that provides metadata for a package named Blankie, then where would you recommend the two installed packages go (e.g. as a matter of best practice)? If jq were to include a package management system, what would you want it to do by default in this case? Incidentally I think that (3) above is also ill-advised. The following would be both (a) shorter and (b) more attuned to packages: (1) $dir/mod.jq # module-oriented |
@pkoppstein The non-versioned locations are not meant for package managers; they are meant for casual users., so I don't see why (2) should trouble you on that account. I will consider removing (3), though it does mean more code. Package managers have to deal with conflicts anyways. But at least that'd be one fewer stat. |
@nicowilliams wrote:
Exactly. The same logic applies to (2) too. Really. Has anyone asked for it? Also, if you drop (2) and (3) now, then after the dust settles, you'll be able to add a third location without having to worry about all the stats :-) p.s. You didn't answer my main question, which was not intended to be about conflicts, by the way. |
Yes, possibly. As to your question. I'm not sure. Consider having a different on-filesystem install location for each repo:
But then you can't mix and match easily. Consider instead having a single install location and a pkg system that knows how to mix and match, and manage conflicts:
But now the pkg manager has to be smarter, and your choice of module mix from each repo has to be global to that location. Consider instead having the repo name in the
This last gives you the most power, but at the price of making imports (at least from programs, since modules can use And now, for the non-versioned location we'd have an ambiguity problem once again, unless we required repo names to not be identifier-like. There's one more option, which is to do what Linux distros do: you can have any number of repos, but you can't really mix and match as there's a single namespace, and more-blessed repos take precedence over less-blessed repos. (Oh, yes, I probably did say something about blessed-ness earlier.) My brain hurts thinking about this. Partly because we lack requirements, and partly because I can't say that I've yet used a language that got this just right. I'm inclined to think that the only approach that works well is the single-namespace, many-repos-with-pecking-order approach. But it's true that we have a chance to do something different, and the repo import metadata approach is the only one that I think I would consider instead. You're right that we need to get this nailed down soon, before 1.5 ships, as otherwise it will be harder to fix later. You preference? |
I should add that the one nice thing about the single-namespace approach is that it's easier to find modules and docs that way. We could also play with the lexer's definition of |
Yes, me too. And I think a package should be able to define its own jq compatibility level.
Lots. I've entered the discussion preaching a node/npm style package manager. To me it seems the Julia option is far from great, and that the rest of the discussion shows that people are too used to ancient systems with only a single version of a package available at any one time and having to constantly adjust themselves (and each jq script they might run) to that. "DLL Hell", was it? I think the path will lead to people putting version information in the package names ("shazam-2") instead of in a metadata file ("shazam/jq.json") or git tags. But this is when we're talking about a single package storage instead keeping dependencies in a subfolder of the current jq script folder, which is the preferred way. We're talking a couple of kilobytes here, which would save a lot of people from headaches. So, since the discussion is moving faster than I have time to code, I'm out. I still see the option of abusing the |
I'm concerned about your comment about the discussion moving faster than you have time to code. Please come back into it when you have time. A 1.5 release is still a while away. IMO major version numbers belong in the module name. The reason is simple: a) backwards incompatible changes make the module different anyways, b) providing multiple major versions with one module is out (because the namespace within is too flat), but c) it's nice to be able to have multiple major versions installed. Minor and micro versions are supposed to be compatible, so just one version installed is a reasonable thing to expect -- except that developers aren't good enough at preventing backwards incompatible changes from sneaking in! But putting every module's version number in the filesystem path will yield something fairly unwieldy :( The jq version number in the path thing was @pkoppstein's idea and I forget how I came to be convinced it's not a bad idea, but I'm still unsure about it. I think partly the idea is that different versions of jq could coexist with each other and a pkg mgr. But yeah, I'm thinking it's more annoying than helpful. |
@joelpurra wrote:
That is supported by both julia and jqpm. @wtlangord: Please note that it is important to distinguish between modules and packages. A package need not contain any modules. A module need not be in a package. A "package" can be thought of as the contents of a single directory, or perhaps as a single git or mercurial repository. Since the package management system will no doubt itself evolve (in tandem with jq), a case could be made for having EVERYTHING related to packages being under ~/.jq/M.N. I'd be fine with that, but these and many other options seem to have been precluded by various constraints that @nicowilliams imposed. In the following, I'll use the vocabulary of "channels" to avoid confusion with "providers". A channel is repository of package metadata; a "provider" is the source of a package. You can think of distribution channels, but the package manager should be able to handle both public and private metadata repositories. One of my main goals is to ensure that jq and the package management system can handle multiple channels seamlessly, and that no jq configuration is required to handle "blessed" channels. That is so that jq can have a "standard library" that need not be distributed with jq itself. |
A POC npm style package manager script (plus jq wrapper script) doesn't sound too hard to create - it's just a matter of having/taking the time. I don't have a lot of time to spare.
Not at all. This is why semantic versioning exists and why should be a folder per each and every package version that has been installed user-/system-globally, which is dynamically referenced by a jq project's I don't think you guys are considering project-local dependencies subfolders I don't think that the What a "jq program" and what a "jq project" could be: Where things end up: How to specify a dependency's version range with a nice ruleset: So, this has taken over an hour of my day already - time which I take from finishing my master's thesis. I still have strong feelings regarding proper packager manager design, and think it's a shame to develop a brand new system based on the current direction. Since there seems to be no other way to convince you other than programming an alternative, we'll just have to wait and see if/when that happens. |
@joelpurra wrote:
I think it would be very helpful if the implications for jq itself could be clarified. That is, if the package manager is implemented separately from jq, then what requirements are there on jq in order for (a) the two to interoperate seamlessly; and (b) for "import Shazam;" on the jq side to be able to find and load a "blessed" package named Shazam that has been installed by a user (without sudo) using the package manager, without ANY jq command-line directives (i.p., no -L options), and without any configuration of jq (i.p., no setting of JQ_LIBRARY_PATH). |
p.s. - @joelpurra has emphasized the need for the package management system to be project-aware. This can be trivially accomplished within the current jqpm (Julia-based) framework simply by adding a flag, e.g. "--project FOLDER". That would, in effect, direct jq and jqpm to use FOLDER/.jq instead of ~/jq. Thus I think the current jqpm (Julia-based) approach meets what I understand to be Joel's core requirements (semantic versioning; support for multiple concurrent projects), as well as some of the preferences, e.g. use of DVCS repositories and avoiding the development of a brand new system. |
Yes, I did that before. What I think would be necessary in jq, is that import directives are scoped. This would mean that if This also means that when jq is processing |
I strongly prefer inverting the default, and require a
Not all of my core requirements. It is also leading down a dark path where there's only a single version of any package available to a user executing a jq script as everything is installed user-globally and without version-named subfolders. (Not talking about jq version at all.) This is bad. There was something else too, but lost the thought. |
@joelpurra wrote:
No!!!! You evidently missed the point about the "--project PATH" flag. There will typically be a set of installed packages under ~/.jq, but each project can have its own set of installed packages that need have no relationship at all with each other or with the standard set under ~/.jq. Suppose I have projects P and Q in ~/projects/P and ~/projects/Q. Then it would make sense to use "--project ~/projects/P" and "--project ~/projects/Q". This would mean that one set of jq-related packages and repositories would live under ~/projects/P/.jq; and another under ~/projects/Q/.jq. These would be in addition to and independent of whatever there may under ~/.jq. Each project can have its own packages, each "checked out" as appropriate for the project. For "system-wide" projects, one could specify "--project /usr/local/projects/P" or some such. This scheme would also allow you to have more than one environment per project (e.g. one jq environment per branch). |
On Thu, Aug 21, 2014 at 12:37:36AM -0700, Joel Purra wrote:
That's fine. I'll see if I can make one.
Thanks for your very clear explanation. I think jq is almost there, if
Although... with
How cool is that? I.e., foo.jq might say:
We can even make it so
And foo.jq would now have:
And, the top-level Well, except for one thing: we treat the module names just like the C
Right. Good. I would not want to have to write portable directory
Indeed.
Are you saying the use of an identifier is bad, the use of '::' is bad,
Thanks, these are useful.
We're hardly done, and we're very much open to suggestions. |
On Fri, Aug 22, 2014 at 02:04:26AM -0700, Joel Purra wrote:
jq programs have no global state anywhere. Not programs, not modules, Variables are read-only. You can only create new bindings that can
Values are also read-only. When you use the assignment operators those (I say notionally because in the common case no copy is needed, so that :) |
On Fri, Aug 22, 2014 at 02:15:27AM -0700, Joel Purra wrote:
Because of
If that seems to obscure/verbose I might add a short-hand like so:
or
|
|
You can see some of this work in progress in the |
Modern programming languages (e.g. Julia) do it; modern editors (e.g. Sublime) do it; and jq deserves to have an integrated package manager too.
Given the fantastic progress that's been recently made, it seems to me that the time is about right for hammering out some details about an integrated package manager, to help ensure the harmonious evolution of jq.
Julia's package manager seems to me to be a nearly perfect model for jq, and the draft outline specification given here closely follows http://julia.readthedocs.org/en/latest/manual/packages/
However the following is intentionally minimalist, that is, it is intended to ensure that the most important functionality will be available as soon as possible, while providing the foundations for backwards-compatible elaboration in future.
For simplicity of exposition, I'll assume in the following that:
i) the package manager's functionality is available via a jq module called Pkg;
ii) that registered packages are available as git repositories; and
iii) that anyone wishing to use the jq package management system will have access to the Internet, and will have git installed.
These assumptions are quite plausible but are not essential to the proposal. (In fact, I'm a fan of mercurial :-)
Key Concepts
Once jq has been installed, the functionality of Pkg will be available either because Pkg is part of the standard distribution, or because the following jq program will, by design, install the Pkg module:
To install another registered package, say P, as well as its dependencies (if any), it will thereafter be sufficient to run the jq program:
Packages become registered when certain metadata has been added to the jq package metadata repository.
Details
All package manager commands are found in the Pkg module:
The Requirements file
Details about the Julia requirements file can be found at http://julia.readthedocs.org/en/latest/manual/packages/#Requirementsquirement (sic)
The following scaled-back specification is intended to be suitable for a first-cut implementation:
The file is line-oriented and may contain #-style comments.
Apart from comments, each line has the format:
PACKAGENAME [ATLEAST_THIS_VERSION]
where:
The text was updated successfully, but these errors were encountered: