It basically works just like RPM or debian, except that the installation root
is fluid -- wherever your code project is, that is where the directory is
relative to which the files will be installed. Go ahead! package up files meant
to go under vendor
with reference to gb, or Godep/_workspace/src
, and tell
hopper to put those files there, and there they will go.
It works for any language, too. Hopper is a language-agnostic dependency management system. you tell it where to put stuff, and it puts stuff there. It is written in go and has golang in mind, but would work equally well for just about anything.
The fluidity of the package root allows us to take the brilliant concept of file-based dependency management right to your code project's front door.
-
Hopper MUST include the files to be installed in a zip file, all with paths relative to the package root.
-
The package root for hopper is determined at the start of every operation by one of the following:
- If the PWD has a file called '.hopper/dependencies.json', the PWD is taken as the package root.
- If any parent of the PWD has a file called '.hopper/dependencies.json', that directory is taken as the package root.
- If none are found, the environment variable HOPPER_PACKAGE_ROOT is checked.
- Failing all these, the entry for "package_root" in /etc/hopper/config.json is consulted, if present.
-
hopper files (as found in PWD or its parent under
.hopper
)- Dependencies: .hopper/dependencies.json
- Project-Specific configuration: .hopper/config.json (for project-specific configuration, overriding anything in /etc)
- Package installation database (PID): .hopper/packages.sqlite .
-
The package format:
- The package is simply a regular zip file, with two directories in its root:
package
anddata
. - Under
package
, a file namedpackage/manifest.json
contains the following information:- Package name under the JSON key
package/name
- Package version under the JSON key
package/version
- Package provides a list of strings under the JSON key
package/provides
- Package requires a list of strings under the JSON key
package/requires
- Package conflicts list under the JSON key
package/conflicts
- Each string in provides/requires/conflicts list is of the form
^<name>((==|>=|>|<|<=)<ver>)?$
where<name>
is of the form^[A-Za-z0-9\_]+$
and<ver>
is of the form^[^[:space:]]+$
. - Content author under JSON key
package/author
- Package maintainer under JSON key
package/packager
- Homepage under JSON key
package/url
- Summary under JSON key
package/summary
- Description under JSON key
package/description
- Release version under JSON key
package/release
, must be non-negative integer
- Package name under the JSON key
- The files under
data
are meant to be unpacked relative to the package root.
- The package is simply a regular zip file, with two directories in its root:
-
Installation:
- The PID is checked for any package of the same name installed.
- If the same name is installed, it is first marked for removal. in the data
- The package file contents are first checked to see if they will overwrite a file found in the PID.
- If it only overwrite files for packages that will be removed, this is okay.
- Otherwise, an error message is thrown and the package is not removed.
- If everything looks good, the files are unpacked to the package root and any packages being upgraded get deleted from the database.
- The database is updated to include the new version of the package and its files, etc.
-
Querying: 2. Usage:
hopper query {packages|manifest|files} [--json]
- Hopper can query its database for:
- What packages are installed and their versions
- Info (whatever was in the manifest)
- Files installed (and integrity flag)
- output may be in JSON or normal text
- Hopper can query its database for:
-
Removal:
- Usage:
hopper remove [--cascade] {<name>}
- Removes all files listed for given named package (must be actual name, not provides name)
- Removes all entries in database associated with package
- Usage:
-
Repo format:
- File called
hopper\_repo.json
like this:
- File called
{ "packages": {
"<name>": {
"<version>": "filename" (relative to URL where `hopper\_repo.json` was found)
}
}
Provides and concrete names alike find themselves in that list. It is simple. If user requests a certain package name, it is found.
Thus dependency management is solved for any and all code projects. For different languages, or layouts, simply make a hopper repo specific to that setup, as http://foo.org/go/gb/x64/
or http://foo.org/go/gb/any/
.