Repository: casey/just (rust)

Issue:
Add function that returns PID of the just process
Mentioned by @page-down in #1011.

Pull request:
Add function returning PID of `just` process
Fixes #1019.

I had to split `Test::run()` into `spawn()` and `check_output` to allow inspection of `process::Child` (for its PID) before setting expected `stdout`. I'm open to any other solutions.

Patch:
diff --git a/README.md b/README.md
index b5d622de..c854c565 100644
--- a/README.md
+++ b/README.md
@@ -1323,6 +1323,23 @@ $ just
 The executable is at: /bin/just
 ```
 
+#### Just Process ID
+
+- `just_pid()` - Process ID of the `just` executable.
+
+For example:
+
+```just
+pid:
+  @echo The process ID is: {{ just_pid() }}
+```
+
+```sh
+$ just
+The process ID is: 420
+```
+
+
 #### String Manipulation
 
 - `quote(s)` - Replace all single quotes with `'\''` and prepend and append
diff --git a/src/function.rs b/src/function.rs
index c4923e59..464e64a1 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -41,6 +41,7 @@ pub(crate) fn get(name: &str) -> Option<Function> {
     "invocation_directory_native" => Nullary(invocation_directory_native),
     "join" => BinaryPlus(join),
     "just_executable" => Nullary(just_executable),
+    "just_pid" => Nullary(just_pid),
     "justfile" => Nullary(justfile),
     "justfile_directory" => Nullary(justfile_directory),
     "kebabcase" => Unary(kebabcase),
@@ -251,6 +252,10 @@ fn just_executable(_context: &FunctionContext) -> Result<String, String> {
   })
 }
 
+fn just_pid(_context: &FunctionContext) -> Result<String, String> {
+  Ok(std::process::id().to_string())
+}
+
 fn justfile(context: &FunctionContext) -> Result<String, String> {
   context
     .search


Test patch:
diff --git a/tests/functions.rs b/tests/functions.rs
index 53566158..e1da40ad 100644
--- a/tests/functions.rs
+++ b/tests/functions.rs
@@ -651,3 +651,14 @@ fn sha256_file() {
     .stdout("177b3d79aaafb53a7a4d7aaba99a82f27c73370e8cb0295571aade1e4fea1cd2")
     .run();
 }
+
+#[test]
+fn just_pid() {
+  let Output { stdout, pid, .. } = Test::new()
+    .args(["--evaluate", "x"])
+    .justfile("x := just_pid()")
+    .stdout_regex(r"\d+")
+    .run();
+
+  assert_eq!(stdout.parse::<u32>().unwrap(), pid);
+}
diff --git a/tests/invocation_directory.rs b/tests/invocation_directory.rs
index b62790e7..bbef3857 100644
--- a/tests/invocation_directory.rs
+++ b/tests/invocation_directory.rs
@@ -85,7 +85,9 @@ fn test_invocation_directory() {
 
 #[test]
 fn invocation_directory_native() {
-  let Output { stdout, tempdir } = Test::new()
+  let Output {
+    stdout, tempdir, ..
+  } = Test::new()
     .justfile("x := invocation_directory_native()")
     .args(["--evaluate", "x"])
     .stdout_regex(".*")
diff --git a/tests/test.rs b/tests/test.rs
index 4aad92b7..a615fb65 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -35,6 +35,7 @@ macro_rules! test {
 }
 
 pub(crate) struct Output {
+  pub(crate) pid: u32,
   pub(crate) stdout: String,
   pub(crate) tempdir: TempDir,
 }
@@ -210,6 +211,8 @@ impl Test {
       .spawn()
       .expect("just invocation failed");
 
+    let pid = child.id();
+
     {
       let mut stdin_handle = child.stdin.take().expect("failed to unwrap stdin handle");
 
@@ -257,8 +260,9 @@ impl Test {
     }
 
     Output {
-      tempdir: self.tempdir,
+      pid,
       stdout: output_stdout.into(),
+      tempdir: self.tempdir,
     }
   }
 }