-
Notifications
You must be signed in to change notification settings - Fork 88
Feature/look in path #175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Feature/look in path #175
Changes from 1 commit
195d9af
ab078a6
a12076d
35ab870
252a88e
0a61921
d39fb31
19791dd
a734f16
fa10060
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ions.
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| /* | ||
| * Copyright 2016 Palantir Technologies, Inc. All rights reserved. | ||
| */ | ||
|
|
||
| package com.palantir.docker.compose.execution; | ||
|
|
||
| import java.io.File; | ||
| import java.nio.file.Path; | ||
| import java.nio.file.Paths; | ||
| import java.util.Map; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Stream; | ||
| import javax.annotation.Nullable; | ||
| import org.immutables.value.Value; | ||
|
|
||
| @Value.Immutable | ||
| public abstract class DockerCommandLocations { | ||
|
|
||
| private static final Pattern PATH_SPLITTER = Pattern.compile(File.pathSeparator); | ||
|
|
||
| @Value.Default | ||
| protected Map<String, String> env() { | ||
| return System.getenv(); | ||
| } | ||
|
|
||
| @Value.Derived | ||
| protected String path() { | ||
|
||
| String path = env().get("PATH"); | ||
| if (path == null) { | ||
| path = env().get("path"); | ||
| } | ||
| if (path == null) { | ||
| throw new IllegalStateException("No path environment variable found"); | ||
| } | ||
| return path; | ||
| } | ||
|
|
||
| @Value.Check | ||
| protected void pathIsNotEmpty() { | ||
| if (path().isEmpty()) { | ||
| throw new IllegalStateException("Path variable was empty"); | ||
| } | ||
| } | ||
|
|
||
| @Nullable | ||
| protected abstract String locationOverride(); | ||
|
|
||
| @Value.Default | ||
| protected Stream<String> macSearchLocations() { | ||
| return Stream.of("/usr/local/bin", "/usr/bin"); | ||
| } | ||
|
|
||
| private Stream<String> pathLocations() { | ||
| Stream<String> pathLocations = Stream.concat(PATH_SPLITTER.splitAsStream(path()), macSearchLocations()); | ||
| if (locationOverride() == null) { | ||
| return pathLocations; | ||
| } | ||
| return Stream.concat(Stream.of(locationOverride()), pathLocations); | ||
| } | ||
|
|
||
| public Stream<Path> forCommand() { | ||
|
||
| return pathLocations().map(p -> Paths.get(p)); | ||
| } | ||
|
|
||
| public static DockerCommandLocations withLocationOverride(String override) { | ||
| return ImmutableDockerCommandLocations.builder() | ||
| .locationOverride(override) | ||
| .build(); | ||
| } | ||
|
|
||
| public static ImmutableDockerCommandLocations.Builder builder() { | ||
| return ImmutableDockerCommandLocations.builder(); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,19 +15,14 @@ | |
| */ | ||
| package com.palantir.docker.compose.execution; | ||
|
|
||
| import java.io.File; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.nio.file.Paths; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Stream; | ||
| import javax.annotation.Nullable; | ||
| import org.apache.commons.lang3.SystemUtils; | ||
| import org.immutables.value.Value; | ||
|
|
||
| @Value.Immutable | ||
| public abstract class DockerCommandLocator { | ||
| private static final Pattern PATH_SPLITTER = Pattern.compile(File.pathSeparator); | ||
|
|
||
| protected abstract String command(); | ||
|
|
||
|
|
@@ -44,42 +39,18 @@ protected String executableName() { | |
| return command(); | ||
| } | ||
|
|
||
| @Value.Default | ||
| protected String path() { | ||
| String path = System.getenv("PATH"); | ||
| if (path == null) { | ||
| throw new IllegalStateException("No path environment variable found"); | ||
| } | ||
| return path; | ||
| } | ||
|
|
||
| @Value.Check | ||
| protected void pathIsNotEmpty() { | ||
| if (path().isEmpty()) { | ||
| throw new IllegalStateException("Path variable was empty"); | ||
| } | ||
| } | ||
|
|
||
| @Nullable | ||
| protected abstract String locationOverride(); | ||
|
|
||
| @Value.Default | ||
| protected Stream<String> macSearchLocations() { | ||
| return Stream.of("/usr/local/bin", "/usr/bin"); | ||
| } | ||
|
|
||
| @Value.Derived | ||
| protected Stream<String> searchLocations() { | ||
| Stream<String> pathLocations = Stream.concat(PATH_SPLITTER.splitAsStream(path()), macSearchLocations()); | ||
| if (locationOverride() == null) { | ||
| return pathLocations; | ||
| } | ||
| return Stream.concat(Stream.of(locationOverride()), pathLocations); | ||
| protected DockerCommandLocations searchLocations() { | ||
| return DockerCommandLocations.withLocationOverride(locationOverride()); | ||
| } | ||
|
|
||
| public String getLocation() { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously DOCKER_COMPOSE_LOCATION would be the path to the binary, e.g. You could remove the It might even be worth moving |
||
| return searchLocations() | ||
| .map(p -> Paths.get(p, executableName())) | ||
| .forCommand() | ||
| .map(p -> p.resolve(executableName())) | ||
| .filter(Files::exists) | ||
| .findFirst() | ||
| .map(Path::toString) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| /* | ||
| * Copyright 2016 Palantir Technologies, Inc. All rights reserved. | ||
| */ | ||
|
|
||
| package com.palantir.docker.compose.execution; | ||
|
|
||
| import static java.util.stream.Collectors.toList; | ||
| import static org.hamcrest.MatcherAssert.assertThat; | ||
| import static org.hamcrest.Matchers.contains; | ||
| import static org.hamcrest.Matchers.is; | ||
| import static org.junit.Assume.assumeTrue; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.nio.file.Path; | ||
| import java.nio.file.Paths; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.stream.Stream; | ||
| import org.junit.Before; | ||
| import org.junit.Rule; | ||
| import org.junit.Test; | ||
| import org.junit.rules.ExpectedException; | ||
| import org.junit.rules.TemporaryFolder; | ||
|
|
||
| public class DockerCommandLocationsShould { | ||
|
|
||
| @Rule public TemporaryFolder folder = new TemporaryFolder(); | ||
|
|
||
| @Rule public ExpectedException exception = ExpectedException.none(); | ||
|
|
||
| private Path firstPathFolder; | ||
| private Path secondPathFolder; | ||
|
|
||
| @Before | ||
| public void setup() throws IOException { | ||
| firstPathFolder = folder.newFolder("first").toPath(); | ||
| secondPathFolder = folder.newFolder("second").toPath(); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_contents_of_the_path_variable() { | ||
| assumeTrue("Path variable present", System.getenv("PATH") != null); | ||
|
|
||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .macSearchLocations(Stream.empty()) | ||
| .build(); | ||
| Stream<Path> foundLocations = commandLocations.forCommand(); | ||
|
|
||
| String[] pathComponents = System.getenv("PATH").split(File.pathSeparator); | ||
| List<Path> expectedPaths = Arrays.stream(pathComponents) | ||
| .map(p -> Paths.get(p)) | ||
| .collect(toList()); | ||
| assertThat(foundLocations.collect(toList()), is(expectedPaths)); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_contents_of_the_path_with_a_single_folder() { | ||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .env(Collections.singletonMap("PATH", firstPathFolder.toString())) | ||
| .macSearchLocations(Stream.empty()) | ||
| .build(); | ||
|
|
||
| assertThat(commandLocations.forCommand().collect(toList()), contains(firstPathFolder)); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_contents_of_the_path_with_two_folders() { | ||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .env(Collections.singletonMap("PATH", firstPathFolder.toString() + File.pathSeparator + secondPathFolder.toString())) | ||
| .macSearchLocations(Stream.empty()) | ||
| .build(); | ||
|
|
||
| assertThat(commandLocations.forCommand().collect(toList()), contains(firstPathFolder, secondPathFolder)); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_location_override_before_the_contents_of_the_path() { | ||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .locationOverride(firstPathFolder.toString()) | ||
| .env(Collections.singletonMap("PATH", secondPathFolder.toString())) | ||
| .macSearchLocations(Stream.empty()) | ||
| .build(); | ||
|
|
||
| assertThat(commandLocations.forCommand().collect(toList()), contains(firstPathFolder, secondPathFolder)); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_docker_for_mac_install_location_after_the_path() { | ||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .env(Collections.singletonMap("PATH", firstPathFolder.toString())) | ||
| .macSearchLocations(Stream.of(secondPathFolder.toString())) | ||
| .build(); | ||
|
|
||
| assertThat(commandLocations.forCommand().collect(toList()), contains(firstPathFolder, secondPathFolder)); | ||
| } | ||
|
|
||
| @Test public void | ||
| contain_the_contents_of_the_path_with_a_lowercase_environment_variable() { | ||
| DockerCommandLocations commandLocations = DockerCommandLocations.builder() | ||
| .env(Collections.singletonMap("path", firstPathFolder.toString())) | ||
| .macSearchLocations(Stream.empty()) | ||
| .build(); | ||
|
|
||
| assertThat(commandLocations.forCommand().collect(toList()), contains(firstPathFolder)); | ||
| } | ||
|
|
||
| @Test public void | ||
| throw_an_exception_if_no_path_variable_is_present() { | ||
| exception.expect(IllegalStateException.class); | ||
| exception.expectMessage("No path environment variable found"); | ||
|
|
||
| DockerCommandLocations.builder() | ||
| .env(Collections.emptyMap()) | ||
| .build(); | ||
| } | ||
|
|
||
| @Test public void | ||
| throw_an_exception_if_the_path_variable_is_empty() { | ||
| exception.expect(IllegalStateException.class); | ||
| exception.expectMessage("Path variable was empty"); | ||
|
|
||
| DockerCommandLocations.builder() | ||
| .env(Collections.singletonMap("PATH", "")) | ||
| .build(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,56 +18,40 @@ | |
| import static org.hamcrest.MatcherAssert.assertThat; | ||
| import static org.hamcrest.core.Is.is; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.Stream; | ||
| import org.junit.Before; | ||
| import org.junit.Rule; | ||
| import org.junit.Test; | ||
| import org.junit.rules.ExpectedException; | ||
| import org.junit.rules.TemporaryFolder; | ||
|
|
||
| public class DockerCommandLocatorShould { | ||
| private static final String command = "command"; | ||
| private static final String command = "not-a-real-command!"; | ||
| private static final String windowsCommand = command + ".exe"; | ||
|
|
||
| @Rule public TemporaryFolder folder = new TemporaryFolder(); | ||
|
|
||
| @Rule public ExpectedException exception = ExpectedException.none(); | ||
|
|
||
| private Path emptyFolder; | ||
|
|
||
| private Path firstPathFolder; | ||
| private Path secondPathFolder; | ||
|
|
||
| private String commandFileLocation; | ||
| private String windowsCommandFileLocation; | ||
|
|
||
| private String pathString; | ||
|
|
||
| @Before | ||
| public void setup() throws IOException { | ||
| emptyFolder = folder.newFolder("empty").toPath(); | ||
| firstPathFolder = folder.newFolder("first").toPath(); | ||
| secondPathFolder = folder.newFolder("second").toPath(); | ||
|
|
||
| commandFileLocation = Files.createFile(firstPathFolder.resolve(command)).toString(); | ||
| windowsCommandFileLocation = Files.createFile(firstPathFolder.resolve(windowsCommand)).toString(); | ||
| Files.createFile(secondPathFolder.resolve(command)); | ||
| Files.createFile(secondPathFolder.resolve(windowsCommand)); | ||
|
|
||
| pathString = Stream.of(emptyFolder, firstPathFolder, secondPathFolder) | ||
| .map(Path::toString) | ||
| .collect(Collectors.joining(File.pathSeparator)); | ||
| } | ||
|
|
||
| @Test public void | ||
| provide_the_first_command_location() { | ||
| DockerCommandLocator locator = DockerCommandLocator.forCommand(command) | ||
| .path(pathString) | ||
| .locationOverride(firstPathFolder.toString()) | ||
| .isWindows(false) | ||
| .build(); | ||
| assertThat(locator.getLocation(), is(commandFileLocation)); | ||
|
|
@@ -76,37 +60,16 @@ public void setup() throws IOException { | |
| @Test public void | ||
| provide_the_first_command_location_on_windows() { | ||
| DockerCommandLocator locator = DockerCommandLocator.forCommand(command) | ||
| .path(pathString) | ||
| .locationOverride(firstPathFolder.toString()) | ||
| .isWindows(true) | ||
| .build(); | ||
| assertThat(locator.getLocation(), is(windowsCommandFileLocation)); | ||
| } | ||
|
|
||
| @Test public void | ||
| provide_command_in_override_location() { | ||
| DockerCommandLocator locator = DockerCommandLocator.forCommand(command) | ||
| .path(firstPathFolder.toString()) | ||
| .locationOverride(secondPathFolder.toString()) | ||
| .isWindows(false) | ||
| .build(); | ||
| assertThat(locator.getLocation(), is(secondPathFolder.resolve(command).toString())); | ||
| } | ||
|
|
||
| @Test public void | ||
| provide_command_in_docker_for_mac_install_location() { | ||
| DockerCommandLocator locator = DockerCommandLocator.forCommand(command) | ||
| .path(emptyFolder.toString()) | ||
| .macSearchLocations(Stream.of(secondPathFolder.toString())) | ||
| .isWindows(false) | ||
| .build(); | ||
| assertThat(locator.getLocation(), is(secondPathFolder.resolve(command).toString())); | ||
| } | ||
|
|
||
| @Test public void | ||
| fail_when_no_paths_contain_command() { | ||
|
||
| DockerCommandLocator locator = DockerCommandLocator.forCommand(command) | ||
| .path(emptyFolder.toString()) | ||
| .macSearchLocations(Stream.empty()) | ||
| .locationOverride(null) | ||
| .isWindows(false) | ||
| .build(); | ||
|
|
||
|
|
@@ -115,13 +78,4 @@ public void setup() throws IOException { | |
| locator.getLocation(); | ||
| } | ||
|
|
||
| @Test public void | ||
| fail_when_no_path_variable_is_set() { | ||
| exception.expect(IllegalStateException.class); | ||
| exception.expectMessage("Path variable was empty"); | ||
|
|
||
| DockerCommandLocator.forCommand(command) | ||
| .path("") | ||
| .build(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we keeping or removing the License? It's removed here but kept in the following file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All files should have the Apache licence. I'll fix the ones that had it removed.