-
Notifications
You must be signed in to change notification settings - Fork 22
Start a design document #2
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
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
8ca7352
Start a design document
kubouch 4fe8f6b
Update DESIGN.md
kubouch 2c98488
use placeholders for parts of the design we do not have names for
amtoine 7e1819e
add backticks to "Project.toml" and add Rust's example
amtoine cb56732
refactor a bit to make the file easier to edit
amtoine ab4bb1e
Add API ideas
kubouch 32de1cd
Add notes about overlays; Misc comments
kubouch 8002bb7
add options for `nupm install`
amtoine 5ce5dd3
mark `nupm publish` as not intended
amtoine 6fcebf8
mention the self update methods
amtoine 83f759d
move the design document to `docs/design/`
amtoine 0d28c71
link to the design in the README
amtoine 8fa88e6
add a reference file about the `metadata` file
amtoine 7cecdb5
add options to `nupm search`
amtoine 345da64
add `--yes` to `install`, `uninstall` and `update`
amtoine a5b118f
add a note about short / long descriptions
amtoine ad6b0cd
apply misc review suggestions
amtoine c2da065
fix minor typos and refactor into NOTEs and links
amtoine 937ab93
add a table of content
amtoine 3bbad6a
Update README.md
kubouch 9e39e3c
Update METADATA.md
kubouch 4a6d001
Remove long description note
kubouch 7c889fe
Put back long description
kubouch File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,5 @@ | ||
| # nupm | ||
| A manager for Nushell packages. | ||
|
|
||
| ## :memo: design of `nupm` | ||
| please have a look at [the design document](docs/design/README.md) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| # Design of `nupm` :warning: Work In Progress :warning: | ||
|
|
||
| This file collects design ideas and directions. The intention is iterate on this document by PRs with discussion. | ||
|
|
||
| > **Note** | ||
| > in the following, until we settle down on precise names, we use the following placeholders: | ||
| > - `METADATA_FILE`: the file containing the metadata of a package, | ||
| > e.g. `project.nuon`, `metadata.json` or `package.nuon` | ||
| > (name inspired by Julia's `Project.toml` or Rust's `Cargo.toml`) | ||
| > - `NUPM_HOME`: the location of all the `nupm` files, overlays, scripts, libraries, ..., | ||
| > e.g. `~/.nupm/`, `$env.XDG_DATA_HOME/nupm/` or `~/.local/share/nupm/` | ||
|
|
||
| # Table of content | ||
| - [Project Structure](#project-structure-toc) | ||
| - [Separate virtual environments](#separate-virtual-environments-toc) | ||
| - [Installation, bootstraping](#installation-bootstraping-toc) | ||
| - [Dependency handling](#dependency-handling-toc) | ||
| - [Package repository](#package-repository-toc) | ||
| - [API / CLI Interface](#api--cli-interface-toc) | ||
| - [Other CLI-related points](#other-cli-related-points-toc) | ||
| - [Other](#other-toc) | ||
|
|
||
| ## Project Structure [[toc](#table-of-content)] | ||
|
|
||
| A `nupm` project is defined by `METADATA_FILE`. | ||
| This is where you define name of the project, version, dependencies, etc., and the type of the project. | ||
| > **Note** | ||
| > see [`METADATA.md`](references/METADATA.md) for a more in-depth description of | ||
| > the `METADATA_FILE` | ||
|
|
||
| There are two types of Nushell projects (named `spam` for the example): | ||
| 1. Simple script | ||
| ``` | ||
| spam | ||
| ├── METADATA_FILE | ||
| └── test.nu | ||
| ``` | ||
| * meant as a runnable script, equivalent of Rust's binary project | ||
| * could use the `.nush` extension if we agree to support it | ||
| * installed under `NUPM_HOME/bin/` | ||
|
|
||
| 2. Module | ||
| ``` | ||
| spam | ||
| ├── METADATA_FILE | ||
| └── spam | ||
| └── mod.nu | ||
| ``` | ||
| * meant as a library to be `use`d or `overlay use`d, equivalent of Rust's library project | ||
| * installed under `NUPM_HOME/modules/` | ||
|
|
||
| You can also install non-Nushell packages as well using a "custom" project type where you specify a `build.nu` installation script | ||
| (e.g., you can install Nushell itself with it). | ||
| Plugins should also be supported, preferably not requiring fully custom `build.nu`. | ||
| More "helper" types of projects could be made, e.g., installing from GitHub, etc. We could allow users to add new project types via "templates". | ||
|
|
||
| ## Separate virtual environments [[toc](#table-of-content)] | ||
|
|
||
| > Inspiration: Python, [conda](https://docs.conda.io/en/latest), `cargo` | ||
|
|
||
| There are two different concepts how to handle virtual environments: | ||
| * Global virtual environments, Python-style. We have a working prototype at [`kubouch/nuun`] using overlays. | ||
| * Installing a package will install it to the environment | ||
| * Possible to switch between them, they are completely isolated from each other | ||
| * Per-project virtual environment, `cargo`-style | ||
| * A project has its own universe (like Rust projects, for example) | ||
|
|
||
| Related to that is a lock file: It is intended to describe exactly the dependencies for a package so that it can be reproduced somewhere else. | ||
|
|
||
| The overlays could be used to achieve all three goals at the same time. When installing a dependency for a package | ||
| * `nupm` adds entry to a **lock file** (this should be the only file you need to 100% replicate the environment) | ||
| * A .nu file (module) is auto-generated from the lock file and contains export statements like `export module NUPM_HOME/cache/packages/spam-v16.4.0-124ptnpbf/spam`. Calling `overlay use` on the file will activate your virtual environment, now you have a per-project environment | ||
| * This file can be installed into a global location that's in your `NU_LIB_DIRS` (e.g., `NUPM_HOME/overlays`) -- now you have a global Python-like virtual environment | ||
| * Each overlay under `NUPM_HOME/overlays` will mimic the main NUPM_HOME structure, e.g., for an overlay `spam` there will be `NUPM_HOME/overlays/spam/bin`, `NUPM_HOME/overlays/spam/modules` (`NUPM_HOME/overlays/spam/overlays`? It might not be the best idea to have it recursive) | ||
|
|
||
| Each package would basically have its own overlay. This overlay file (it's just a module) could be used to also handle dependencies. If your project depends on `foo` and `bar` which both depend on `spam` but different versions, they could both import the different verions privately in their own overlay files and in your project's overlay file would be just `export use path/to/foo` and `export use path/to/bar`. This should prevent name clashing of `spam`. The only problem that needs to be figured out is how to tell `foo` to be aware of its overlay. | ||
|
|
||
| ## Installation, bootstraping [[toc](#table-of-content)] | ||
|
|
||
| Requires these actions from the user (this should be kept as minimal as possible): | ||
| * Add `NUPM_HOME/bin` to PATH (install location for binary projects) | ||
| * Add `NUPM_HOME/modules` to NU_LIB_DIRS | ||
| * Add `NUPM_HOME/overlays` to NU_LIB_DIRS | ||
| * Make the `nupm` command available somehow (e.g., `use` inside `config.nu`) | ||
|
|
||
| > :warning: **WIP** | ||
| > The disadvantage of this is that the default install location is not an overlay. We could make `nupm` itself an overlay that adds itself as a command, so that you can activate/deactivate it. We might need a few attempts to get to the right solution. | ||
|
|
||
| There are several approaches: | ||
| * bootstrap using shell script sourced from web (like `rustup`) | ||
| * embedded inside Nushell's binary | ||
| * The advantage of this is that it does not require user's config. The `PATH` and `NU_LIB_DIRS` could be pre-configured in Nushell | ||
| * (in the future maybe) as a compiled binary (using something like [`jntrnr/nu_app`]) | ||
| * This would allow us to reverse the installation steps: Instead of Nushell installing `nupm`, we could let user only install `nupm` which would in turn install Nushell | ||
|
|
||
| ## Dependency handling [[toc](#table-of-content)] | ||
|
|
||
| In compiled programming languages, there are two kinds of dependencies: static and dynamic. Static are included statically and compiled when compiling the project, | ||
| dynamic are pre-compiled libraries linked to the project. | ||
|
|
||
| > **Note** | ||
| > Nushell is [similar to compiled languages][Nushell compiled] rather than typical dynamic languages like Python, so these concepts are relevant for Nushell. | ||
|
|
||
| Static dependencies: | ||
| * :thumbsup:: reproducible, does not rely on system files at runtime (no more missing `random.so.2`), higher performance (allows joint optimization of dependencies and project itself) | ||
| * :thumbsdown:: increased compile time, binary size, can easily end up with multiple versions of the same library (hello Nushell dependencies) | ||
|
|
||
| Dynamic dependencies are the opposite basically. | ||
|
|
||
| Nushell currently supports only static dependencies, but we might be able to add the "linking" feature at some point which could unlock new interesting patterns regarding package management, like testing. | ||
|
|
||
| ## Package repository [[toc](#table-of-content)] | ||
|
|
||
| Packages need to be stored somewhere. There should be one central "official" location (see https://github.com/NixOS/nixpkgs for inspiration). GitHub repository seems like a good starting point. | ||
|
|
||
| Additionally, user should be able to add 3rd party repositories as well as install local and other packages (e.g., from the web, just pointing at URL), | ||
| as long as it has `METADATA_FILE` telling `nupm` what to do. | ||
|
|
||
| ## API / CLI Interface [[toc](#table-of-content)] | ||
|
|
||
| Nushell's module design conflates CLI interface with API -- they are the same. Not all of the below are of the same priority. | ||
|
|
||
| > **Note** | ||
| > commands like `list`, `install`, `search`, `uninstall`, `update`, ..., i.e. should | ||
| > - print short descriptions by default | ||
| > - print long descriptions with `--long-description (-l)` | ||
|
|
||
| - `nupm new [--script] [--module]` | ||
| - create a new local package with template files ([`kubouch/nuun`]) | ||
| - `nupm list` | ||
| - list currently installed packages and if they're out of date | ||
| - `nupm install` | ||
| - install package into the currently active overlay (can override which overlay to install to) | ||
| - `--reinstall (-r)`: reinstall package if installed | ||
| - `--update (-u)`: update local packages if outdated | ||
| - Both `-u` & `-r` flags might be specified, but updating has higher priority than reinstalling | ||
| - `--yes (-y)`: do not ask for user confirmation, e.g. to use `nupm install` in scripts | ||
| - `nupm add` | ||
| - add a dependency to the current project | ||
| - it is different from `nupm install`: this one adds the dependency to the `METADATA_FILE`, `nupm install` does not | ||
| - `nupm uninstall` | ||
| - uninstall a package from a currently active overlay (can override which overlay to install to) | ||
| - `--yes (-y)`: do not ask for user confirmation, e.g. to use `nupm uninstall` in scripts | ||
| - `nupm update` | ||
| - update all packages in a currently active overlay (can specify package and/or overlay name) | ||
| - can be used to self-update: `nupm update nupm`, `nupm update --self` or `nupm update --all` (the last one would update every package installed by `nupm`, including `nupm` itself) | ||
| - `--yes (-y)`: do not ask for user confirmation, e.g. to use `nupm update` in scripts | ||
| - `nupm search` | ||
| - search package repository (only supported ones by default) | ||
| - `--unsupported (-u)`: would also list packages that are not supported in the user's system, e.g. due to OS incompatibilities | ||
|
|
||
| - `nupm check` | ||
| - parse the project to search for errors but do not run it | ||
| - `nupm test` | ||
| - run unit and integration tests of local package | ||
| - `nupm bench` | ||
| - run benchmarks | ||
| - `nupm doc` | ||
| - generate documentation | ||
| - `nupm publish` | ||
| - publish package to a repository | ||
| - **NOT SUPPORTED FOR NOW**: the repository will be a *GitHub* repo with packages submitted by PRs to start with | ||
|
|
||
| The following are for Python-style global overlays, we might need to re-think this for local package overlays: | ||
| - `nupm overlay new` | ||
| - create a new global overlay (Python's virtual environment style) | ||
| - `--local` flag could generate an overlay locally from the currently opened project | ||
| - `nupm overlay remove` | ||
| - deletes the overlay | ||
| - `nupm overlay list` | ||
| - list all overlays | ||
| - `nupm overlay list <overlay-name>` lists all packages installed within the overlay | ||
| - `nupm overlay export` | ||
| - dump all the installed package names, versions, etc. to a file | ||
| - `nupm overlay import` | ||
| - create overlay from exported file | ||
|
|
||
| ### Other CLI-related notes [[toc](#table-of-content)] | ||
|
|
||
| * We could later think about being able to extend `nupm`, like `cargo` has plugins. | ||
| * Mutable actions (like install) have by default Y/n prompt, but can be overriden with `--yes` | ||
| * By default, new projects are cross-platform: | ||
| * Windows | ||
| * MacOS | ||
| * Linux | ||
| * Android (if someone is willing to maintain it, we're not testing Nushell on Android, at least for now) | ||
|
|
||
| ## Other [[toc](#table-of-content)] | ||
|
|
||
| * activations (not bringing all package's content but only parts of it) | ||
| * doc generation | ||
| * test running | ||
| * benchmark running | ||
| * configuration (do not add until we really need something to be configurable, keep it minimal, case study of a project with minimal configuration: [`psf/black`]) | ||
|
|
||
| [Nushell compiled]: https://www.nushell.sh/book/thinking_in_nu.html#think-of-nushell-as-a-compiled-language | ||
|
|
||
| [`kubouch/nuun`]: https://github.com/kubouch/nuun | ||
| [`jntrnr/nu_app`]: https://github.com/jntrnr/nu_app | ||
| [`psf/black`]: https://github.com/psf/black | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # `nupm`'s package metadata reference | ||
|
|
||
| ## Required attributes | ||
| - `name`: Package name | ||
| - `nu-version`: Supported Nushell version. Just like `dependencies` might be either exact version or some matcher like "greater than 1.70" | ||
| - `version`: Version of the package. Semantic versioning is advised to enable users to have more generic requirements | ||
| - `type`: Tells `nupm` how to install the package | ||
|
|
||
| ## Required attributes for publishing | ||
| - `author`: Name of the developer/organization/etc. | ||
| - `short-description`: Short info about the package, displayed by default | ||
| - `supported-os`: Operating systems supported by the package, the most broad possibility: `{"arch": ["*"], "family": ["*"], "name": ["*"]}`. Matched by `$nu.os-info` | ||
|
amtoine marked this conversation as resolved.
|
||
| - `url`: Package website/GitHub repository. Basically a place where one can find some additional info about the package | ||
|
|
||
| ## Optional attribtues | ||
| - `dependencies`: Packages needed by the package — versions have to be specified. e.g. `[nupm/0.7.0]`. Semantic versioning is also supported: `[nupm/~0.7]` | ||
| - `installer`: Name of a script (relative to the package scope) that will install the package instead (or in addition to) of default `nupm` logic | ||
| - `keywords`: List of keywords used by `nupm search` in addition to `name` | ||
|
|
||
| ## Automatically generated, outside of the user-created metadata file | ||
| - `files`: List of records of files being part of the package. Records reference: | ||
| - `checksum`: SHA256 sum of the file | ||
| - `name`: File path (relative to the package scope) | ||
| - `raw-url`: `GET`table link to the file | ||
| - `supported-os`: Exactly like in the top-level metadata | ||
|
amtoine marked this conversation as resolved.
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.