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
1 change: 1 addition & 0 deletions app.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dependencies:
eu.maveniverse.maven.mima:context: "2.4.33"
eu.maveniverse.maven.mima.runtime:standalone-static: "2.4.33"
org.apache.maven.indexer:search-backend-smo: "7.1.6"
info.picocli:picocli: "4.7.7"
org.yaml:snakeyaml: "2.4"
org.jline:jline-console-ui: "3.30.5"
Expand Down
48 changes: 48 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<maven.compiler.target>11</maven.compiler.target>
<mainClass>org.codejive.jpm.Main</mainClass>
<version.mima>2.4.34</version.mima>
<version.search-backend>7.1.6</version.search-backend>
<version.picocli>4.7.7</version.picocli>
<version.snakeyaml>2.4</version.snakeyaml>
<version.jline>3.30.5</version.jline>
Expand All @@ -55,6 +56,11 @@
<artifactId>standalone-static</artifactId>
<version>${version.mima}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.indexer</groupId>
<artifactId>search-backend-smo</artifactId>
<version>${version.search-backend}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
Expand Down Expand Up @@ -126,11 +132,21 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down Expand Up @@ -210,6 +226,38 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-test-source</id>
<phase>process-resources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/it/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<phase>integration-test</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down
161 changes: 161 additions & 0 deletions src/it/java/org/codejive/jpm/MainIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package org.codejive.jpm;

import static org.assertj.core.api.Assertions.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import picocli.CommandLine;

/** Integration tests for the Main class, focusing on the new 'do' command and aliases. */
class MainIT {

@TempDir Path tempDir;

private String originalDir;

@BeforeEach
void setUp() {
originalDir = System.getProperty("user.dir");
System.setProperty("user.dir", tempDir.toString());
System.setProperty("picocli.ansi", "false");
}

@AfterEach
void tearDown() {
System.setProperty("user.dir", originalDir);
}

/**
* Helper method to capture stdout/stderr for tests that need to check command output. Only use
* this for tests that check jpm's own output, not for tests that execute system commands.
*/
private TestOutputCapture captureOutput() {
PrintStream originalOut = System.out;
PrintStream originalErr = System.err;
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
ByteArrayOutputStream errContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));

return new TestOutputCapture(originalOut, originalErr, outContent, errContent);
}

/** Helper class to manage output capture and restoration */
private static class TestOutputCapture implements AutoCloseable {
private final PrintStream originalOut;
private final PrintStream originalErr;
private final ByteArrayOutputStream outContent;
private final ByteArrayOutputStream errContent;

TestOutputCapture(
PrintStream originalOut,
PrintStream originalErr,
ByteArrayOutputStream outContent,
ByteArrayOutputStream errContent) {
this.originalOut = originalOut;
this.originalErr = originalErr;
this.outContent = outContent;
this.errContent = errContent;
}

String getOut() {
return outContent.toString();
}

String getErr() {
return errContent.toString();
}

@Override
public void close() {
System.setOut(originalOut);
System.setErr(originalErr);
}
}

@Test
void testDoAliasWithArgs() throws IOException {
createAppYmlWithRepositories();
try (TestOutputCapture capture = captureOutput()) {
CommandLine cmd = Main.getCommandLine();
int exitCode = cmd.execute("build", "--foo", "bar");

assertThat(exitCode).isEqualTo(0);
String output = capture.getOut();
// The run action should execute and include the classpath in the output
assertThat(output).contains("javac", "jfiglet", "--foo bar");
}
}

@Test
void testCopyCommandWithRepositoryOptions() throws IOException {
// Test copy command with --repo options
CommandLine cmd = Main.getCommandLine();
int exitCode =
cmd.execute(
"copy",
"--repo",
"central=https://repo1.maven.org/maven2",
"--repo",
"https://jcenter.bintray.com",
"com.google.guava:guava:31.1-jre");

// The command should execute successfully (even if dependency resolution might fail)
assertThat(exitCode >= 0).isTrue();
}

@Test
void testInstallCommandWithRepositoryOptions() throws IOException {
CommandLine cmd = Main.getCommandLine();
int exitCode =
cmd.execute(
"install",
"--repo",
"central=https://repo1.maven.org/maven2",
"com.google.guava:guava:31.1-jre");

// The command should execute successfully (even if dependency resolution might fail)
assertThat(exitCode >= 0).isTrue();
}

@Test
void testPathCommandWithRepositoryOptionsAndAppYml() throws IOException {
// Create app.yml with repositories
createAppYmlWithRepositories();

try (TestOutputCapture capture = captureOutput()) {
CommandLine cmd = Main.getCommandLine();
int exitCode =
cmd.execute(
"path",
"--repo",
"jcenter=https://jcenter.bintray.com",
"com.google.guava:guava:31.1-jre");

// The command should execute (even if dependency resolution might fail)
assertThat(exitCode >= 0).isTrue();
}
}

private void createAppYmlWithRepositories() throws IOException {
String yamlContent =
"dependencies:\n"
+ " com.github.lalyos:jfiglet: \"0.0.9\"\n"
+ "\n"
+ "repositories:\n"
+ " central: \"https://repo1.maven.org/maven2\"\n"
+ " custom: \"https://my.custom.repo/maven2\"\n"
+ "\n"
+ "actions:\n"
+ " build: \"echo javac -cp {{deps}} *.java\"\n"
+ " test: \"echo java -cp {{deps}} TestRunner\"\n";
Files.writeString(tempDir.resolve("app.yml"), yamlContent);
}
}
54 changes: 54 additions & 0 deletions src/it/java/org/codejive/jpm/search/SearchIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.codejive.jpm.search;

import static org.assertj.core.api.Assertions.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.codejive.jpm.search.Search;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.FieldSource;

public class SearchIT {
@ParameterizedTest
@EnumSource(Search.Backends.class)
void testSearchSingleTerm(Search.Backends backend) throws IOException {
Search s = Search.getBackend(backend);
Search.SearchResult res = s.findArtifacts("httpclient", 10);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
res = s.findNextArtifacts(res);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
}

@ParameterizedTest
@EnumSource(Search.Backends.class)
void testSearchDoubleTerm(Search.Backends backend) throws IOException {
Search s = Search.getBackend(backend);
Search.SearchResult res = s.findArtifacts("apache:httpclient", 10);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
res = s.findNextArtifacts(res);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
}

@ParameterizedTest
@EnumSource(Search.Backends.class)
void testSearchTripleTerm(Search.Backends backend) throws IOException {
Search s = Search.getBackend(backend);
Search.SearchResult res = s.findArtifacts("org.apache.httpcomponents:httpclient:", 10);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
assertThat(res.artifacts).allMatch(a -> "org.apache.httpcomponents".equals(a.getGroupId()));
assertThat(res.artifacts).allMatch(a -> "httpclient".equals(a.getArtifactId()));
res = s.findNextArtifacts(res);
assertThat(res.count).isGreaterThan(1);
assertThat(res.artifacts).isNotEmpty();
assertThat(res.artifacts).allMatch(a -> "org.apache.httpcomponents".equals(a.getGroupId()));
assertThat(res.artifacts).allMatch(a -> "httpclient".equals(a.getArtifactId()));
}
}
19 changes: 17 additions & 2 deletions src/main/java/org/codejive/jpm/Jpm.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.*;
import java.util.stream.Collectors;
import org.codejive.jpm.config.AppInfo;
import org.codejive.jpm.search.Search;
import org.codejive.jpm.util.*;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.resolution.DependencyResolutionException;
Expand Down Expand Up @@ -120,12 +121,26 @@ public SyncResult copy(String[] artifactNames, Map<String, String> repos, boolea
* @throws IOException If an error occurred during the search.
*/
public String[] search(String artifactPattern, int count) throws IOException {
return search(artifactPattern, count, null);
}

/**
* Searches for artifacts matching the given pattern.
*
* @param artifactPattern The pattern to search for.
* @param count The maximum number of results to return.
* @return An array of artifact names matching the given pattern.
* @throws IOException If an error occurred during the search.
*/
public String[] search(String artifactPattern, int count, Search.Backends backend)
throws IOException {
List<Artifact> artifacts = new ArrayList<>();
int max = count <= 0 || count > 200 ? 200 : count;
SearchResult result = SearchUtils.findArtifacts(artifactPattern, max);
Search s = Search.getBackend(backend);
Search.SearchResult result = s.findArtifacts(artifactPattern, max);
while (result != null) {
artifacts.addAll(result.artifacts);
result = count <= 0 ? SearchUtils.findNextArtifacts(result) : null;
result = count <= 0 ? s.findNextArtifacts(result) : null;
}
return artifacts.stream().map(Jpm::artifactGav).toArray(String[]::new);
}
Expand Down
Loading
Loading