I recently created a tool called Grin. It's a lightweight interface to downloading releases from GitHub. Grin is nice because it lets developers create complex projects without worrying about complex installation processes for users. Instead all that's needed is a zip file of what's supposed to be installed on the user's computer. Then you make an installer that invokes Grin (through pastebin) with the proper arguments and Grin takes care of downloading, decompressing, and saving the installation to disk.
Grin-Get is a package manager based on Grin. Unlike Grin, which is meant to be lightweight and transparent to the user, Grin-Get is an interface for the user that manages the installation of packages and the interactions between them.
Github
Pastebin installer: HGAmBJiN
Usage
grin-get {install : remove} …
- grin-get install {package} This command is used to install a package. Packages are denoted by the username and repo name for the project on GitHub. e.g.
grin-get install Team-CC-Corp/Grin
By default, grin-get installs the latest version of the package, but this can be changed by specifying a version, like this:
grin-get install Team-CC-Corp/Grin/1.0.1
Grin-Get can install any Grin compatible release. No special action is needed from developers if the developer wants Grin-Get support on top of their Grin support. This is nice because it's already easy and powerful for a developer to support Grin, and this way they can support installation independently of Grin-Get. So they can keep their installation process transparent to the user if they don't want to require Grin-Get, while still supporting Grin-Get.
Grin-Get does provide some features developers might want, but these features only work through Grin-Get, not through ordinary Grin. Packages that make use of these features require installation via Grin-Get.
- grin.json
- bin The bin field can be a string delimited by colons, where each section is a path in the package where executables are found. Or the bin field can be a table with strings that represent the same things.
- dependencies The dependencies field is like the bin field, except pacakges that this package is dependent on are found instead of executables.
- lib The lib field is like the bin field, except APIs are found instead of executables.
- help The help field is like the bin field, except help files are found instead of executables.
- startup This should be a string that points to the file the package wants to run at startup. Example grin.json file:
Spoiler
- Grin-Get packages can include a grin.json file.
This should represent an object with several optional fields.
{
"bin": "programs",
"lib": "apis",
"help": "docs",
"startup": "load.lua"
}
Spoiler
- Utility Functions:
- function grin.combine(path, …) Returns the fs.combine() of a variable number of components
- function grin.assert(condition, errMsg, level) Just like assert but with a level parameter like error
- function grin.expect(t, v) Asserts that type(v) == t Grin Functions: Package names are in the format user/repo/version If version isn't supplied, it is determined to be the latest installed version.
- function grin.setGrinDir(dir) Sets the directory that grin knows as its root
- function grin.getGrinDir() Gets the root grin directory
- function grin.packageNameComponents(pkg) Returns the user, repo, version of the given full package name.
- function grin.refreshPath(shell) Puts the bin folders of all grin-get packages on the path of the given shell.
- function refreshHelpPath() Puts the help folders of all grin-get packages on the help path.
- function grin.resolvePackageRoot(pkg) Get the root directory of the given package.
- function grin.getPackagePathItems(pkg) Returns a table of all the bin folders that a package specifies.
- function getPackageHelpItems(pkg) Returns a table of all the help folders that a package specifies.
- function grin.getPackageLibItems(pkg) Returns a table of all the lib folders that a package specifies.
- function grin.resolveInPackage(pkg, path) Returns the full path of the file found at the given path in the given package's bin folder(s).
- function grin.getFromPackage(pkg, path) Returns the combination of the given package's full path and the given path.
- function grin.getPackageGrinJSON(pkg) Returns the object represented in the given package's grin.json file.
- function grin.getReleaseInfo(pkg) Returns the object represented by releases.json in the repo's directory. Will resort to GitHub if necessary.
- function grin.getReleaseInfoFromGithub(pkg) Returns the object represented by the json GitHub returns for the given repo.
- function grin.getLatestInstalledVersion(pkg) Returns the tag name of the latest installed version of the package.
- function grin.forEach(func) Calls the given function once for each installed package Passes the package name as a parameter. Does not call the function multiple times for different versions of the same package
- function grin.isPackageInstalled(pkg) Checks if the given package is installed.
- function grin.packageFromExecutable(path) Given the full path of a program, returns the package that program resides in.
- function grin.getPackageAPI(pkg, name) Finds the API for the given name in the given package. Then loads that API with os.loadAPI Returns the loaded API. Ignores .lua file extensions, which is nice for external editors.
Grin-Get is installed via a pastebin based Grin installer. Just run:
pastebin run HGAmBJiN
And Grin-Get should be installed. But you need to add something like the following to your startup file
shell.run("grin/bin/grin-startup.lua")
Because Grin-Get needs to do a couple things as the computer starts up to allow you to use your packages easily.