Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ nix run github:eureka-cpu/ns -- <URI>#<ATTR>
Add or remove it from your user profile:

```sh
nix profile install github:eureka-cpu/ns
nix profile add github:eureka-cpu/ns
nix profile remove ns
```

Expand Down
2 changes: 1 addition & 1 deletion dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(name ns)

(version 0.4.2)
(version 0.4.3)

(generate_opam_files true)

Expand Down
6 changes: 3 additions & 3 deletions lib/cmd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ module Cmd = struct
Bos.Cmd.v "nix"
|>+ [ "develop" ] @ [ Uri.sprintf_uri_attr_opt entrypoint attribute ]
|>+ Option.value ~default:[] force_experimental_features
|>+ [ "--command"; Unix.shell ]
|>+ [ "--command"; Unix.shell () ]
;;

let legacy_nix_shell_from_entrypoint entrypoint attribute =
Bos.Cmd.v "nix-shell"
|>+ Option.value ~default:[] (Option.map (fun attr -> [ "--attr"; attr ]) attribute)
|>+ [ entrypoint ]
|>+ [ "--command"; Unix.shell ]
|>+ [ "--command"; Unix.shell () ]
;;

let nix_shell installables force_experimental_features =
Expand All @@ -40,7 +40,7 @@ module Cmd = struct
(* Need to combine/validate that the installables given are all Nixpkgs *)
Bos.Cmd.v "nix-shell"
|>+ [ "--packages" ] @ installables
|>+ [ "--command"; Unix.shell ]
|>+ [ "--command"; Unix.shell () ]
;;

let print_strategy ({ workdir; primary; fallback } : strategy) =
Expand Down
8 changes: 2 additions & 6 deletions lib/util.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ module Util = struct
Error.handle_ns_error "%s" (Error.sprintf_unix_error e path)
;;

(** Get the user's shell from the environment *)
let shell =
match Sys.getenv_opt "SHELL" with
| Some s -> s
| None -> "/bin/sh"
;;
(** Get the user's login shell *)
let shell () = (Unix.getpwuid (Unix.getuid ())).Unix.pw_shell

(** Whether a flake.nix file exists at the given directory *)
let flake_exists_at dir = Sys.file_exists (Filename.concat dir "flake.nix")
Expand Down
2 changes: 1 addition & 1 deletion ns.opam
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
version: "0.4.2"
version: "0.4.3"
synopsis: "A unified interface for nix shell."
description:
"An intuitive nix shell interface that unifies the `nix shell`, `nix develop` and `nix-shell` commands."
Expand Down
2 changes: 1 addition & 1 deletion test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
(targets test_ns) ; the Dune target name
(deps test_ns.rs) ; path relative to this dune file
(action
(run rustc --test %{deps} -o %{targets} --allow warnings)))
(run rustc --test %{deps} -o %{targets} -A warnings -l c)))
39 changes: 36 additions & 3 deletions test/test_ns.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
use std::{env, path, process, sync};
use std::{env, ffi, path, process, sync};

static DUNE_TEST_DIR: sync::OnceLock<path::PathBuf> = sync::OnceLock::new();
static ENV_SHELL: sync::OnceLock<String> = sync::OnceLock::new();

fn dune_test_dir() -> &'static path::PathBuf {
DUNE_TEST_DIR.get_or_init(|| env::current_dir().expect("failed to get test directory"))
}
fn env_shell() -> &'static String {
ENV_SHELL.get_or_init(|| env::var("SHELL").expect("failed to get shell from environment"))

/// Minimal bindings to dynamically linked libc, used for getting the shell of the logged in user.
mod libc {
unsafe extern "C" {
pub fn getuid() -> u32;
pub fn getpwuid(uid: u32) -> *mut Passwd;
}

#[repr(C)]
pub struct Passwd {
pub pw_name: *mut i8,
pub pw_passwd: *mut i8,
pub pw_uid: u32,
pub pw_gid: u32,
#[cfg(target_os = "macos")]
pub pw_change: i64,
#[cfg(target_os = "macos")]
pub pw_class: *mut i8,
pub pw_gecos: *mut i8,
pub pw_dir: *mut i8,
pub pw_shell: *mut i8,
#[cfg(target_os = "macos")]
pub pw_expire: i64,
}
}

fn env_shell() -> &'static str {
ENV_SHELL.get_or_init(|| unsafe {
let uid = libc::getuid();
let pw = libc::getpwuid(uid);
assert!(!pw.is_null());
ffi::CStr::from_ptr((*pw).pw_shell)
.to_string_lossy()
.into_owned()
})
}

fn ns() -> path::PathBuf {
Expand Down