8000 add support for buildNimPackage by lnk3 · Pull Request #862 · nix-community/nix-init · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- Add support for `buildNpmPackage`
- Add support for `buildNimPackage`

## v0.3.6 - 2026-05-15

Expand Down
1 change: 1 addition & 0 deletions README.md
8000
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Options:
- `buildPythonApplication` and `buildPythonPackage`
- `buildGoModule`
- `buildNpmPackage`
- `buildNimPackage`

### Supported fetchers

Expand Down
1 change: 1 addition & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub struct Opts {
pub enum BuilderFunction {
BuildGoModule,
BuildNpmPackage,
BuildNimPackage,
BuildPythonApplication,
BuildPythonPackage,
BuildRustPackage,
Expand Down
11 changes: 9 additions & 2 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod drv;
pub mod go;
pub mod nim;
pub mod npm;
pub mod python;
pub mod rust;
Expand All @@ -26,8 +27,8 @@ use tracing::warn;
use crate::{
cli::CargoVendor,
codegen::{
drv::MkDerivation, go::BuildGoModule, npm::BuildNpmPackage, python::BuildPythonPackage,
rust::BuildRustPackage,
drv::MkDerivation, go::BuildGoModule, nim::BuildNimPackage, npm::BuildNpmPackage,
python::BuildPythonPackage, rust::BuildRustPackage,
},
frontend::FrontendDispatch,
inputs::{AllInputs, write_all_lambda_inputs, write_inputs, write_lambda_input},
Expand All @@ -44,6 +45,7 @@ use crate::{
#[display("{0}")]
pub enum BuilderDispatch {
BuildGoModule(BuildGoModule),
BuildNimPackage(BuildNimPackage),
BuildNpmPackage(BuildNpmPackage),
BuildPythonPackage(BuildPythonPackage),
BuildRustPackage(BuildRustPackage),
Expand Down Expand Up @@ -80,6 +82,7 @@ pub struct SourceLayout {
pub has_cmake: bool,
pub has_go: bool,
pub has_meson: bool,
pub has_nim: bool,
pub has_npm: bool,
pub has_npm_lock: bool,
pub has_python: bool,
Expand Down Expand Up @@ -474,6 +477,10 @@ impl SourceLayout {
has_cmake: src_dir.join("CMakeLists.txt").is_file(),
has_go: src_dir.join("go.mod").is_file(),
has_meson: src_dir.join("meson.build").is_file(),
has_nim: std::fs::read_dir(src_dir).is_ok_and(|dir| {
dir.filter_map(Result::ok)
.any(|entry| entry.path().extension().is_some_and(|ext| ext == "nimble"))
}),
has_npm: src_dir.join("package.json").is_file(),
has_npm_lock: src_dir.join("package-lock.json").is_file()
|| src_dir.join("npm-shrinkwrap.json").is_file(),
Expand Down
59 changes: 59 additions & 0 deletions src/codegen/nim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::{
fmt::Write as _,
path::{Path, PathBuf},
};

use anyhow::Result;
use parse_display::Display;

use crate::codegen::{Builder, Codegen};

#[derive(Clone, Copy, Display)]
#[display("buildNimPackage")]
pub struct BuildNimPackage;

impl Builder for BuildNimPackage {
fn function(&self) -> &'static str {
"buildNimPackage"
}

fn explicit_strict_deps(&self) -> bool {
true
}

async fn after_src(&self, cg: &mut Codegen<'_>) -> Result<String> {
let mut out = String::new();

let lock_path = get_lock_path(cg.out_dir);

writeln!(
out,
" # Generate lockfile with: nix run -f . nim_lk ./result | jq --sort-keys > {lock_path}"
)?;
writeln!(out, " lockFile = ./lock.json;\n")?;

if let Some(file) = find_nimble_file(cg.src_dir) {
writeln!(out, " nimbleFile = \"{file}\";\n")?;
}

writeln!(out, " nimFlags = [ ];\n")?;

Ok(out)
}
}

fn get_lock_path(out_dir: Option<&Path>) -> String {
out_dir
.map(|d| d.join("lock.json"))
.unwrap_or_else(|| PathBuf::from("lock.json"))
.display()
.to_string()
}
Comment on lines +45 to +51
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use nix-init in a nixpkgs checkout it precomputed the out_dir to something like pkgs/by-name/xx/xxxxxxxx/, so I wanted to use it to help the maintainer generate the lockfile in the correct place.

The comment will result in a simple command the nix-init user can just copy and run


fn find_nimble_file(src_dir: &Path) -> Option<String> {
std::fs::read_dir(src_dir)
.ok()?
.filter_map(Result::ok)
.find(|entry| entry.path().extension().is_some_and(|ext| ext == "nimble"))
.map(|entry| entry.file_name().to_string_lossy().into_owned())
}
Comment on lines +53 to +59
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to find detect the nimble file since it doesn't have a predefined name like config.nimble

There is a nimbleFile parameter for the nixpkgs builder function which is not mandatory but nice to have and trivial to precompute for the maintainer.

9 changes: 8 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ use crate::{
cmd::{NIX, NURL},
codegen::{
BuilderDispatch, Codegen, SourceLayout, drv::MkDerivation, go::BuildGoModule,
npm::BuildNpmPackage, python::BuildPythonPackage, rust::BuildRustPackage,
nim::BuildNimPackage, npm::BuildNpmPackage, python::BuildPythonPackage,
rust::BuildRustPackage,
},
fetcher::{Fetcher, FetcherDispatch, PackageInfo, PypiFormat, Revisions, Version},
frontend::{Frontend, headless, readline},
Expand Down Expand Up @@ -385,6 +386,7 @@ async fn run() -> Result<()> {
let builder = match (opts.builder, opts.cargo_vendor) {
(Some(builder), rust @ Some(vendor)) if layout.has_cargo => match builder {
BuilderFunction::BuildGoModule => BuildGoModule.into(),
BuilderFunction::BuildNimPackage => BuildNimPackage.into(),
BuilderFunction::BuildNpmPackage => BuildNpmPackage.into(),
BuilderFunction::BuildPythonApplication => BuildPythonPackage::new(true, rust).into(),
BuilderFunction::BuildPythonPackage => BuildPythonPackage::new(false, rust).into(),
Expand All @@ -396,6 +398,7 @@ async fn run() -> Result<()> {
let rust = layout.has_cargo.then_some(CargoVendor::FetchCargoVendor);
match builder {
BuilderFunction::BuildGoModule => BuildGoModule.into(),
BuilderFunction::BuildNimPackage => BuildNimPackage.into(),
BuilderFunction::BuildNpmPackage => BuildNpmPackage.into(),
BuilderFunction::BuildPythonApplication => {
BuildPythonPackage::new(true, rust).into()
Expand All @@ -414,6 +417,10 @@ async fn run() -> Result<()> {
builders.push(BuildGoModule.into());
}

if layout.has_nim {
builders.push(BuildNimPackage.into());
}

if layout.has_cargo {
let cargo_deps_options: &[_] = match rust {
Some(vendor) => &[vendor],
Expand Down
38 changes: 38 additions & 0 deletions tests/cmd/nim.out/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
lib,
buildNimPackage,
fetchFromGitHub,
nix-update-script,
}:

buildNimPackage (finalAttrs: {
pname = "choosenim";
version = "0.8.16";
__structuredAttrs = true;
strictDeps = true;

src = fetchFromGitHub {
owner = "nim-lang";
repo = "choosenim";
tag = "v${finalAttrs.version}";
hash = "sha256-Sa1T7uZDIZHsakyI7QeJEWrHW7rSarFDniY9FaTBL7Q=";
};

# Generate lockfile with: nix run -f . nim_lk ./result | jq --sort-keys > ./lock.json
lockFile = ./lock.json;

nimbleFile = "choosenim.nimble";

nimFlags = [ ];

passthru.updateScript = nix-update-script { };

meta = {
description = "Official tool for easily installing and managing multiple versions of the Nim programming language";
homepage = "https://github.com/nim-lang/choosenim";
changelog = "https://github.com/nim-lang/choosenim/blob/${finalAttrs.src.rev}/changelog.markdown";
license = lib.licenses.bsd3;
maintainers = with lib.maintainers; [ alice ];
mainProgram = "choosenim";
};
})
5 changes: 5 additions & 0 deletions tests/cmd/nim.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
args = [
"--headless",
"--url=https://github.com/nim-lang/choosenim",
"--rev=v0.8.16",
]
0