Skip to content
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

Add custom repository support for selective repositories #41177

Merged
Show file tree
Hide file tree
Changes from 13 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
8 changes: 8 additions & 0 deletions cli/ballerina-cli/spotbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
-->

<FindBugsFilter>
<Match>
<Class name="io.ballerina.cli.cmd.PullCommand"/>
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
</Match>
<Match>
<Class name="io.ballerina.cli.cmd.PullCommand"/>
<Bug pattern="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE"/>
</Match>
<Match>
<Class name="io.ballerina.cli.cmd.BuildCommand"/>
<Bug pattern="URF_UNREAD_FIELD"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,41 @@

package io.ballerina.cli.cmd;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.ballerina.cli.BLauncherCmd;
import io.ballerina.projects.ProjectException;
import io.ballerina.projects.SemanticVersion;
import io.ballerina.projects.Settings;
import io.ballerina.projects.internal.model.Proxy;
import io.ballerina.projects.internal.model.Repository;
import io.ballerina.projects.util.ProjectConstants;
import io.ballerina.projects.util.ProjectUtils;
import org.ballerinalang.central.client.CentralAPIClient;
import org.ballerinalang.central.client.CentralClientConstants;
import org.ballerinalang.central.client.exceptions.CentralClientException;
import org.ballerinalang.central.client.exceptions.PackageAlreadyExistsException;
import org.ballerinalang.maven.bala.client.MavenResolverClient;
import org.ballerinalang.maven.bala.client.MavenResolverClientException;
import org.ballerinalang.toml.exceptions.SettingsTomlException;
import org.wso2.ballerinalang.compiler.util.Names;
import org.wso2.ballerinalang.util.RepoUtils;
import picocli.CommandLine;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;

import static io.ballerina.cli.cmd.Constants.PULL_COMMAND;
import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException;
import static io.ballerina.projects.util.ProjectConstants.BALA_EXTENSION;
import static io.ballerina.projects.util.ProjectConstants.PLATFORM;
import static io.ballerina.projects.util.ProjectUtils.getAccessTokenOfCLI;
import static io.ballerina.projects.util.ProjectUtils.initializeProxy;
import static io.ballerina.projects.util.ProjectUtils.validateOrgName;
Expand Down Expand Up @@ -71,6 +84,9 @@
@CommandLine.Option(names = "--debug", hidden = true)
private String debugPort;

@CommandLine.Option(names = "--repository")
private String repositoryName;

public PullCommand() {
this.errStream = System.err;
this.exitWhenFinish = true;
Expand Down Expand Up @@ -163,6 +179,87 @@
}
}

Settings settings;
try {
settings = RepoUtils.readSettings();
} catch (SettingsTomlException e) {
settings = Settings.from();

Check warning on line 186 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java#L185-L186

Added lines #L185 - L186 were not covered by tests
}

Repository targetRepository = null;
if (repositoryName != null) {
for (Repository repository : settings.getRepositories()) {
if (repository.id().equals(repositoryName)) {
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
targetRepository = repository;
break;
}
}
}

if (targetRepository == null && repositoryName != null) {
String errMsg = "unsupported repository '" + repositoryName + "' found. Only " +
"repositories mentioned in the Settings.toml are supported.";
CommandUtil.printError(this.errStream, errMsg, null, false);
CommandUtil.exitError(this.exitWhenFinish);
return;
}

if (targetRepository != null) {
MavenResolverClient mavenResolverClient = new MavenResolverClient();
if (!"".equals(targetRepository.username()) && !"".equals(targetRepository.password())) {
mavenResolverClient.addRepository(targetRepository.id(), targetRepository.url(),
targetRepository.username(), targetRepository.password());

Check warning on line 211 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java#L210-L211

Added lines #L210 - L211 were not covered by tests
} else {
mavenResolverClient.addRepository(targetRepository.id(), targetRepository.url());
}
Proxy proxy = settings.getProxy();
mavenResolverClient.setProxy(proxy.host(), proxy.port(), proxy.username(), proxy.password());

Path mavenBalaCachePath = RepoUtils.createAndGetHomeReposPath()
.resolve(ProjectConstants.REPOSITORIES_DIR)
.resolve(targetRepository.id())
.resolve(ProjectConstants.BALA_DIR_NAME);

try {
mavenResolverClient.pullPackage(orgName, packageName, version,
String.valueOf(mavenBalaCachePath.toAbsolutePath()));
Path balaDownloadPath = mavenBalaCachePath.resolve(orgName).resolve(packageName).resolve(version)
.resolve(packageName + "-" + version + BALA_EXTENSION);
Path balaHashPath = mavenBalaCachePath.resolve(orgName).resolve(packageName).resolve(version)
.resolve(packageName + "-" + version + BALA_EXTENSION + ".sha1");
Path temporaryExtractionPath = mavenBalaCachePath.resolve(orgName).resolve(packageName)
.resolve(version).resolve(PLATFORM);
ProjectUtils.extractBala(balaDownloadPath, temporaryExtractionPath);
Path packageJsonPath = temporaryExtractionPath.resolve("package.json");
BufferedReader bufferedReader = Files.newBufferedReader(packageJsonPath, StandardCharsets.UTF_8);
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
JsonObject resultObj = new Gson().fromJson(bufferedReader, JsonObject.class);
String platform = resultObj.get(PLATFORM).getAsString();
Path actualBalaPath = mavenBalaCachePath.resolve(orgName).resolve(packageName)
.resolve(version).resolve(platform);
temporaryExtractionPath.toFile().renameTo(actualBalaPath.toFile());

Files.delete(balaDownloadPath);
Files.delete(balaHashPath);
Files.delete(balaDownloadPath.getParent().resolve("_remote.repositories"));
if (Files.exists(temporaryExtractionPath)) {
Files.walk(temporaryExtractionPath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);

Check warning on line 248 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java#L245-L248

Added lines #L245 - L248 were not covered by tests
}

} catch (MavenResolverClientException e) {
errStream.println("unexpected error occurred while pulling package:" + e.getMessage());
CommandUtil.exitError(this.exitWhenFinish);
} catch (IOException e) {
throw createLauncherException(
"unexpected error occurred while creating package repository in bala cache: " + e.getMessage());

Check warning on line 256 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java#L251-L256

Added lines #L251 - L256 were not covered by tests
}
PrintStream out = System.out;
out.println("Successfully pulled the package from the custom repository.");
return;
}

Path packagePathInBalaCache = ProjectUtils.createAndGetHomeReposPath()
.resolve(ProjectConstants.REPOSITORIES_DIR).resolve(ProjectConstants.CENTRAL_REPOSITORY_CACHE_NAME)
.resolve(ProjectConstants.BALA_DIR_NAME)
Expand All @@ -180,14 +277,6 @@
for (int i = 0; i < SUPPORTED_PLATFORMS.length; i++) {
String supportedPlatform = SUPPORTED_PLATFORMS[i];
try {
Settings settings;
try {
settings = RepoUtils.readSettings();
// Ignore Settings.toml diagnostics in the pull command
} catch (SettingsTomlException e) {
// Ignore 'Settings.toml' parsing errors and return empty Settings object
settings = Settings.from();
}
CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(),
initializeProxy(settings.getProxy()), settings.getProxy().username(),
settings.getProxy().password(), getAccessTokenOfCLI(settings));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@
import io.ballerina.projects.Settings;
import io.ballerina.projects.bala.BalaProject;
import io.ballerina.projects.directory.BuildProject;
import io.ballerina.projects.internal.model.Proxy;
import io.ballerina.projects.internal.model.Repository;
import io.ballerina.projects.repos.TempDirCompilationCache;
import io.ballerina.projects.util.ProjectConstants;
import io.ballerina.projects.util.ProjectUtils;
import org.ballerinalang.central.client.CentralAPIClient;
import org.ballerinalang.central.client.CentralClientConstants;
import org.ballerinalang.central.client.exceptions.CentralClientException;
import org.ballerinalang.central.client.exceptions.NoPackageException;
import org.ballerinalang.maven.bala.client.MavenResolverClient;
import org.ballerinalang.maven.bala.client.MavenResolverClientException;
import org.ballerinalang.toml.exceptions.SettingsTomlException;
import org.wso2.ballerinalang.util.RepoUtils;
import picocli.CommandLine;
Expand All @@ -48,6 +52,7 @@
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
Expand All @@ -61,6 +66,7 @@
import static io.ballerina.projects.util.ProjectUtils.getAccessTokenOfCLI;
import static io.ballerina.projects.util.ProjectUtils.initializeProxy;
import static io.ballerina.runtime.api.constants.RuntimeConstants.SYSTEM_PROP_BAL_DEBUG;
import static java.nio.file.Files.createDirectories;
import static org.wso2.ballerinalang.programfile.ProgramFileConstants.SUPPORTED_PLATFORMS;

/**
Expand Down Expand Up @@ -145,19 +151,33 @@
System.setProperty(CentralClientConstants.ENABLE_OUTPUT_STREAM, "true");

try {
Settings settings = RepoUtils.readSettings();

Check warning on line 154 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L154

Added line #L154 was not covered by tests

// If the repository flag is specified, validate and push to the provided repo
if (repositoryName != null) {
if (!repositoryName.equals(ProjectConstants.LOCAL_REPOSITORY_NAME)) {
boolean isCustomRepository = false;
Repository targetRepository = null;

Check warning on line 159 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L158-L159

Added lines #L158 - L159 were not covered by tests
for (Repository repository : settings.getRepositories()) {
if (repository.id().equals(repositoryName)) {
isCustomRepository = true;
targetRepository = repository;
break;

Check warning on line 164 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L162-L164

Added lines #L162 - L164 were not covered by tests
}
}

if (!repositoryName.equals(ProjectConstants.LOCAL_REPOSITORY_NAME) && !isCustomRepository) {
String errMsg = "unsupported repository '" + repositoryName + "' found. Only '"
+ ProjectConstants.LOCAL_REPOSITORY_NAME + "' repository is supported.";
+ ProjectConstants.LOCAL_REPOSITORY_NAME +
"' repository and repositories mentioned in the Settings.toml are supported.";
CommandUtil.printError(this.errStream, errMsg, null, false);
CommandUtil.exitError(this.exitWhenFinish);
return;
}

if (balaPath == null) {
if (balaPath == null && repositoryName.equals(ProjectConstants.LOCAL_REPOSITORY_NAME)) {
pushPackage(project);
} else {
return;

Check warning on line 179 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L179

Added line #L179 was not covered by tests
} else if (repositoryName.equals(ProjectConstants.LOCAL_REPOSITORY_NAME)) {
if (!balaPath.toFile().exists()) {
throw new ProjectException("path provided for the bala file does not exist: " + balaPath + ".");
}
Expand All @@ -166,9 +186,41 @@
}
validatePackageMdAndBalToml(balaPath);
pushBalaToCustomRepo(balaPath);
return;

Check warning on line 189 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L189

Added line #L189 was not covered by tests
}

MavenResolverClient mvnClient = new MavenResolverClient();

Check warning on line 192 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L192

Added line #L192 was not covered by tests
if (!"".equals(targetRepository.username()) && !"".equals(targetRepository.password())) {
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
mvnClient.addRepository(targetRepository.id(), targetRepository.url(), targetRepository.username(),
targetRepository.password());

Check warning on line 195 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L194-L195

Added lines #L194 - L195 were not covered by tests
} else {
mvnClient.addRepository(targetRepository.id(), targetRepository.url());

Check warning on line 197 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L197

Added line #L197 was not covered by tests
}
Proxy proxy = settings.getProxy();
mvnClient.setProxy(proxy.host(), proxy.port(), proxy.username(), proxy.password());

Check warning on line 200 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L199-L200

Added lines #L199 - L200 were not covered by tests

Path customRepoLocalCache = RepoUtils.createAndGetHomeReposPath()
.resolve(ProjectConstants.REPOSITORIES_DIR)
.resolve(targetRepository.id())
.resolve(ProjectConstants.BALA_DIR_NAME)
.resolve("temp");

Check warning on line 206 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L202-L206

Added lines #L202 - L206 were not covered by tests


if (balaPath == null && isCustomRepository) {
pushPackage(project, mvnClient, customRepoLocalCache);

Check warning on line 210 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L210

Added line #L210 was not covered by tests
} else if (isCustomRepository) {
if (!balaPath.toFile().exists()) {
throw new ProjectException("path provided for the bala file does not exist: " + balaPath + ".");

Check warning on line 213 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L213

Added line #L213 was not covered by tests
}
if (!FileUtils.getExtension(balaPath).equals("bala")) {
throw new ProjectException("file provided is not a bala file: " + balaPath + ".");

Check warning on line 216 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L216

Added line #L216 was not covered by tests
}
validatePackageMdAndBalToml(balaPath);
pushBalaToCustomRepo(balaPath, mvnClient, customRepoLocalCache);

Check warning on line 219 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L218-L219

Added lines #L218 - L219 were not covered by tests
}


} else {
Settings settings = RepoUtils.readSettings();
if (settings.diagnostics().hasErrors()) {
CommandUtil.printError(this.errStream, settings.getErrorMessage(), null, false);
CommandUtil.exitError(this.exitWhenFinish);
Expand Down Expand Up @@ -226,6 +278,11 @@
pushBalaToCustomRepo(balaFilePath);
}

private void pushPackage(BuildProject project, MavenResolverClient client, Path customRepoPath) {
Path balaFilePath = validateBalaFile(project, this.balaPath);
pushBalaToCustomRepo(balaFilePath, client, customRepoPath);
}

Check warning on line 284 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L282-L284

Added lines #L282 - L284 were not covered by tests

private void pushPackage(BuildProject project, CentralAPIClient client)
throws CentralClientException {
Path balaFilePath = validateBala(project, client, this.balaPath);
Expand Down Expand Up @@ -402,6 +459,45 @@
}
}

private void pushBalaToCustomRepo(Path balaPath, MavenResolverClient client, Path customRepoPath) {
try {
createDirectories(customRepoPath);
} catch (IOException e) {
throw new ProjectException(e.getMessage());
}
Path balaFileName = balaPath.getFileName();

Check warning on line 468 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L464-L468

Added lines #L464 - L468 were not covered by tests
if (null != balaFileName) {
ProjectEnvironmentBuilder defaultBuilder = ProjectEnvironmentBuilder.getDefaultBuilder();
defaultBuilder.addCompilationCacheFactory(TempDirCompilationCache::from);
BalaProject balaProject = BalaProject.loadProject(defaultBuilder, balaPath);

Check warning on line 472 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L470-L472

Added lines #L470 - L472 were not covered by tests

String org = balaProject.currentPackage().manifest().org().toString();
String name = balaProject.currentPackage().manifest().name().toString();
String version = balaProject.currentPackage().manifest().version().toString();

Check warning on line 476 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L474-L476

Added lines #L474 - L476 were not covered by tests

try {
client.pushPackage(balaPath, org, name, version, customRepoPath);

Check warning on line 479 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L479

Added line #L479 was not covered by tests
if (Files.exists(customRepoPath)) {
Files.walk(customRepoPath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);

Check warning on line 484 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L481-L484

Added lines #L481 - L484 were not covered by tests
}
} catch (MavenResolverClientException | IOException e) {
throw new ProjectException(e.getMessage());
}

Check warning on line 488 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L486-L488

Added lines #L486 - L488 were not covered by tests

Path relativePathToBalaFile;
if (this.balaPath != null) {
relativePathToBalaFile = balaPath;

Check warning on line 492 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L492

Added line #L492 was not covered by tests
} else {
relativePathToBalaFile = userDir.relativize(balaPath);

Check warning on line 494 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L494

Added line #L494 was not covered by tests
}
outStream.println("Successfully pushed " + relativePathToBalaFile

Check warning on line 496 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L496

Added line #L496 was not covered by tests
+ " to '" + repositoryName + "' repository.");
}
}

Check warning on line 499 in cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java

View check run for this annotation

Codecov / codecov/patch

cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java#L499

Added line #L499 was not covered by tests

/**
* Check if package already available in the remote.
*
Expand Down
Loading
Loading