Skip to content

Commit

Permalink
Add "which" method to Processes and ProcessHelper (#956)
Browse files Browse the repository at this point in the history
Closes #945
  • Loading branch information
sleberknight authored Apr 24, 2023
1 parent 17edd11 commit d628ea1
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/main/java/org/kiwiproject/base/process/ProcessHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,15 @@ private Process launchPgrepWithParentPidFlag(long parentProcessId, ProcessHelper
return processHelper.launch("pgrep", "-P", String.valueOf(parentProcessId));
}

/**
* Locate a program in the user's path.
*
* @param program the program to locate
* @return an Optional containing the full path to the program, or an empty Optional if not found
* @implNote If there is more than program found, only the first one is returned
* @see Processes#which(String)
*/
public Optional<String> which(String program) {
return Processes.which(program);
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/kiwiproject/base/process/Processes.java
Original file line number Diff line number Diff line change
Expand Up @@ -676,4 +676,17 @@ private static void validateKilledBeforeTimeout(long processId, boolean killedBe
format("Process %s was not killed before 1 second timeout expired", processId));
}
}

/**
* Locate a program in the user's path.
*
* @param program the program to locate
* @return an Optional containing the full path to the program, or an empty Optional if not found
* @implNote If there is more than program found, only the first one is returned
*/
public static Optional<String> which(String program) {
var whichProc = launch("which", program);
var stdOut = readLinesFromInputStreamOf(whichProc);
return stdOut.stream().findFirst();
}
}
20 changes: 20 additions & 0 deletions src/test/java/org/kiwiproject/base/process/ProcessHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

Expand Down Expand Up @@ -542,4 +543,23 @@ public int read() throws IOException {
throw new IOException(message);
}
}

@Nested
class Which {

/**
* @implNote This test assumes {@link Processes#which(String)} works. This is a trade-off to make this
* test much simpler than having to replicate its logic in this test.
*/
@Test
void shouldFindProgramThatExists() {
var lsPath = Processes.which("ls").orElseThrow();
assertThat(processes.which("ls")).contains(lsPath);
}

@Test
void shouldReturnEmptyOptional_WhenProgramDoesNotExistInPath() {
assertThat(processes.which("killify")).isEmpty();
}
}
}
17 changes: 17 additions & 0 deletions src/test/java/org/kiwiproject/base/process/ProcessesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,21 @@ void shouldThrowIllegalArgument_WhenPidIsNotNumeric(String pidString) {
.isThrownBy(() -> Processes.getPidOrThrow(pidString));
}
}

@Nested
class Which {

@ParameterizedTest
@ValueSource(strings = {"cp", "ls", "mv"})
void shouldFindProgramThatExists(String program) {
assertThat(Processes.which(program)).hasValueSatisfying(value -> assertThat(value).endsWith(program));
}

@ParameterizedTest
@ValueSource(strings = {"foobar", "abc-xyz", "clunkerate"})
void shouldReturnEmptyOptional_WhenProgramDoesNotExistInPath(String program) {
assertThat(Processes.which(program)).isEmpty();
}
}

}

0 comments on commit d628ea1

Please sign in to comment.