nim-lang / RFCs

A repository for your Nim proposals.
136 stars 26 forks source link

Nimble for Nim v2 #524

Open mratsim opened 1 year ago

mratsim commented 1 year ago

Nim and its ecosystem have been growing significantly in the past years.

One of the roles it grew into lately has been as the engine under Python and Javascript libraries thanks to packages like nimpy, nimporter or genny.

With the advent of Nim v2, in particular the new memory management default which significantly improve interoperability with other languages (no need for GC_ref in libraries for example), Nim is becoming even more interesting as a backend even for compiled language such as C++, Go or Rust.

For example I have had discussions on how to use Constantine a high speed cryptography library from those 3 languages. In particular, static and generic (especially static enums), compile-time evaluation, the guarantee of no GC on value types, the performance and ergonomic has been instrumental to make such a library. However, I now face challenges from a totally different area of computer science: package installation.

I've identified 3 areas of the current situation that would improve growth of libraries:

  1. Support for monorepo
  2. nimble install foo should preserve the package structure, i.e. what is on the developer machine should end up on users' machines.
  3. Provide a nimble -pkg foo mytask, for example nimble -pkg constantine test so that users can run tasks of any installed package, in particular tests and benchmarks which can be used by developers for diagnostics.

Mono-repo support

For large codebases with strong versioning requirements of components, monorepos significantly reduce development friction. A single PR can update an application and all dpeendencies, instead of having to review multiple PRs.

In some cases, security or cryptographic packages, having a single dependency may even be a requirement. That requirement is motivated to prevent supply chain attacks which have grown a lot in frequency and sophistication in the past years. I indeed was asked this question "do you have any dependency besides the compiler?"

How to?

Unfortunately I'm unsure how other languages with a package manager like Rust, Go, Python, Javascript handle monorepo but I'd assume the root nimble file needs to be extended with support for:

Preserving the package structure

Currently if we want to have subpackages in a project we need to use

On installation, the src is dropped as are all folders not in src.

This is problematic:

Lastly, implicitly exposing all those subpackageX is not always desirable. Some of those subpackages might be internal dependencies that are not supposed to be used by the public.

Instead, the .nimble file should specify the path of the public packages.

Global namespaced nimble tasks

To continue on the topic on making supporting complex nim applications as streamlined as possible, I would like to be able to say to my users:

"Can you run nimble -pkg mypkg test and nimble -pkg mypkg bench"

Currently I have to ask them to clone, potentially github submodule, cd and run the nimble task.

Furthermore the cloned version might not be the installed version.

Related

Clonkk commented 1 year ago

I will add to that the ability to package artifacts for library that are built on top of shared library (bindings for example).

FedericoCeratto commented 1 year ago

Regarding to the package structure, currently there isn't a very clear distinction between what files should be installed to use a library, or also run tests, or generate documentation or unneded files (e.g. screenshots, CI conf) This is described in https://github.com/nim-lang/RFCs/issues/179 and https://github.com/nim-lang/nimble/issues/1042 and https://github.com/nim-lang/nimble/issues/506

metagn commented 1 year ago

About -pkg, there is supposedly --package but it's only documented under "nimble run".