inko-lang / inko

A language for building concurrent software with confidence
http://inko-lang.org/
Mozilla Public License 2.0
874 stars 38 forks source link

Make it easy to install Inko applications #663

Open yorickpeterse opened 9 months ago

yorickpeterse commented 9 months ago

Description

Consider the imaginary Yeet framework, which wishes to introduce the yeet command. This command is used for creating new projects (yeet init), running tests in a special way (yeet test), and more. Ideally getting started with Yeet is as simple as:

inko SOMETHING
yeet init

Reusing existing package managers isn't really viable, as each platform has its own package manager with its own versioning policies, release cycles, etc. This results in an inconsistent experience: users of Arch may be able to use the AUR to easily install something, but users of Debian would have to do things differently.

To solve this, Inko should provide a way to install applications and expose these to the PATH. The purpose is not to replace platform specific package managers (e.g. you'd still want to use those for production environments), but rather to make it easy to install development related tools.

Option 1: project-specific executables

We extend inko pkg sync such that if a project's direct dependencies introduces executables (see https://github.com/inko-lang/inko/issues/625 and https://github.com/inko-lang/inko/issues/631), we compile and move those into ./dep/bin. We then need to add inko init to create a basic project layout, with an optional flag to include a package and run inko pkg sync. The result is that for our Yeet framework, we'd instruct users to run something like this:

inko init --package github.com/yeet/yeet --version 1.2.3

The benefit of this approach is that different projects can still use different versions of the Yeet executable, rather than being forced to use a single global version that may be incompatible with the project.

The downside is that now inko pkg sync or inko build needs to be aware of these executables and compile them (once). I think it makes the most sense to do this as part of inko pkg sync rather than inko build, otherwise you'd have to run inko build on an empty project just so you can get started with it, which feel a bit odd.

Another downside is that this approach isn't really suitable for easily distributing end user applications through Inko's package manager. Sure, you can set up an "apps" project somewhere and add your desired applications as a dependency, then add ./dep/bin to your PATH, but that's rather cumbersome.

Another challenge is that the executables may expect additional files to be available, such as template files to copy over. inko pkg sync only moves the src/ directory into ./dep, meaning we'd have to keep these files elsewhere.

Option 2: global applications

We introduce the inko app subcommand, supporting inko app install, inko app update, inko app remove, and inko app list. Internally the list of applications is managed using an inko.pkg somewhere. Each application is installed in ~/.local/share/inko/apps/NAME where NAME is the application name. This directory contains the git clone of the application, and the resulting executables are moved to ~/.local/share/inko/bin.

To support multiple (major) versions of an application we'd have to add a version to the application path, then provide some sort of mechanism to switch between these versions. I'm not sure what the best approach here is.

Related work

Blocked by

yorickpeterse commented 2 months ago

With https://github.com/inko-lang/inko/issues/664 merged, whatever approach (if any) we provide to install Inko applications should also support setting build variables.