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

Development: Improve git URI handling for LocalVC #8484

Merged
merged 5 commits into from
Apr 28, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,73 @@
import java.net.URISyntaxException;
import java.util.Objects;

/**
* Represents a Version Control System (VCS) repository URI with capabilities to manipulate and extract information from it.
* This class supports handling both local file references and remote repository URIs.
*/
public class VcsRepositoryUri {

/** The username associated with the VCS repository URI, if applicable. */
protected String username;

/** The URI representing either a local file path or a remote repository URL. */
protected URI uri;

/**
* Default constructor, intended for internal use only to prevent compile errors.
* This constructor is protected to discourage its use as it creates an uninitialized object.
*/
protected VcsRepositoryUri() {
// NOTE: this constructor should not be used and only exists to prevent compile errors
}

// Create the url from a uriSpecString, e.g. https://username@artemistest2gitlab.ase.in.tum.de/FTCSCAGRADING1/ftcscagrading1-username
/**
* Initializes a new instance of the {@link VcsRepositoryUri} class based on a specified URI string.
* The URI string should represent a complete URI to a VCS repository, e.g. https://username@artemistest2gitlab.ase.in.tum.de/FTCSCAGRADING1/ftcscagrading1-username
*
* @param uriSpecString The URI string to be parsed into a URI.
* @throws URISyntaxException If the provided string does not form a valid URI.
*/
public VcsRepositoryUri(String uriSpecString) throws URISyntaxException {
this.uri = new URI(uriSpecString);
}

// Create the url from a file reference, e.g. C:/Users/Admin/AppData/Local/Temp/studentOriginRepo1644180397872264950
/**
* Initializes a new instance of the {@link VcsRepositoryUri} class from a file reference, e.g. C:/Users/Admin/AppData/Local/Temp/studentOriginRepo1644180397872264950
* The file's URI is extracted and stored.
*
* @param file The file from which the URI will be created.
*/
public VcsRepositoryUri(java.io.File file) {
this.uri = file.toURI();
}

/**
* Associates a username with the current VCS repository URI and returns the instance for chaining.
*
* @param username The username to be associated with the URI.
* @return The instance of {@link VcsRepositoryUri} with the username set.
*/
public VcsRepositoryUri withUser(final String username) {
this.username = username;
return this;
}

/**
* Returns the URI associated with this VCS repository.
*
* @return The URI of the VCS repository.
*/
public URI getURI() {
return this.uri;
}

/**
* Compares this instance with another object for equality, considering both the username and the URI.
* This method also supports comparisons with subclasses of {@link VcsRepositoryUri}.
*
* @param obj The object to compare with this instance.
* @return true if the provided object is equivalent to this instance; false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand Down Expand Up @@ -62,7 +100,8 @@ public String toString() {
}

/**
* Generates the unique local folder name for a given file or remote repository URI.
* Generates a folder name from the URI to uniquely represent the repository locally.
* It takes the last path segment of file URIs and the full path for remote repository URIs, excluding any .git suffix.
* For file URIs, we take the last element of the path, which should be unique
* For URLs pointing to remote git repositories, we use the whole path
* <p>
Expand All @@ -71,7 +110,7 @@ public String toString() {
* file:C:/Users/Admin/AppData/Local/Temp/studentOriginRepo1644180397872264950 --> studentOriginRepo1644180397872264950
* file:/var/folders/vc/sk85td_s54v7w9tjq07b0_q80000gn/T/studentTeamOriginRepo420037178325056205/ --> studentTeamOriginRepo420037178325056205
*
* @return the folderName as a string.
* @return A string representing the folder name derived from the URI.
*/
public String folderNameForRepositoryUri() {
if ("file".equals(uri.getScheme())) {
Expand All @@ -91,22 +130,60 @@ public String folderNameForRepositoryUri() {
}

/**
* Retrieves the repository name without the project key and the optional practice prefix from the URI.
* Extracts and returns the repository name from the URI, removing any leading project key and optional "practice" prefix.
* This method is useful for isolating the pure repository name in contexts where the higher-level organizational
* identifiers (like project keys) are not needed.
* <p>
* The method performs the following transformations:
* <ul>
* <li>Converts the full repository URI path into its base name with the ".git" suffix removed.</li>
* <li>Strips out the leading project key followed by a dash ("-").</li>
* <li>Removes any "practice-" prefix used for practice repositories.</li>
* </ul>
* <p>
* Examples:
* http://localhost:8080/git/GREAT/great-artemis_admin.git --> artemis_admin
* http://localhost:8080/git/GREAT/great-practice-artemis_admin.git --> artemis_admin
* <ul>
* <li>http://localhost:8080/git/GREAT/great-artemis_admin.git --> artemis_admin</li>
* <li>http://localhost:8080/git/GREAT/great-practice-artemis_admin.git --> artemis_admin</li>
* </ul>
*
* @return the repository name without the project key and the optional practice prefix.
* @return The repository name without the project key and the practice prefix, in lowercase.
*/
public String repositoryNameWithoutProjectKey() {
return repositorySlug().toLowerCase().replace(projectKey().toLowerCase() + "-", "").replace("practice-", "");
}

/**
* Retrieves the last part of the URI path, typically representing the repository slug or name.
* This slug usually corresponds to the actual name of the repository in the version control system, without any path
* prefixes or the ".git" file extension. This method is often used as a helper for other methods that need to process
* or display the repository name.
* <p>
* Example:
* <ul>
* <li>From the URI "http://localhost:8080/git/GREAT/great-artemis_admin.git", it extracts "great-artemis_admin".</li>
* </ul>
*
* @return The repository slug derived from the URI's path.
*/
public String repositorySlug() {
return this.uri.getPath().substring(this.uri.getPath().lastIndexOf('/') + 1).replace(".git", "");
}

/**
* Extracts the project key from a VCS repository URI. The project key is assumed to be the second-to-last
* segment of the path in the URI, which typically identifies the organizational or project-level identifier under
* which the repository is categorized in the VCS.
* <p>
* This method is particularly useful when handling URIs where repository access is structured by project keys.
* <p>
* Example:
* <ul>
* <li>From the URI "http://localhost:8080/git/GREAT/great-artemis_admin.git", it extracts "GREAT".</li>
* </ul>
*
* @return The project key in lowercase, as found in the URI's path.
*/
private String projectKey() {
return this.uri.getPath().substring(this.uri.getPath().lastIndexOf('/', this.uri.getPath().lastIndexOf('/') - 1) + 1, this.uri.getPath().lastIndexOf('/')).toLowerCase();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ private String getGitUriAsString(VcsRepositoryUri vcsRepositoryUri) throws URISy
private URI getGitUri(VcsRepositoryUri vcsRepositoryUri) throws URISyntaxException {
if (profileService.isLocalVcsCiActive()) {
// Create less generic LocalVCRepositoryUri out of VcsRepositoryUri.
LocalVCRepositoryUri localVCRepositoryUri = new LocalVCRepositoryUri(vcsRepositoryUri.toString(), gitUrl);
LocalVCRepositoryUri localVCRepositoryUri = new LocalVCRepositoryUri(vcsRepositoryUri.toString());
String localVCBasePath = environment.getProperty("artemis.version-control.local-vcs-repo-path");
return localVCRepositoryUri.getLocalRepositoryPath(localVCBasePath).toUri();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ public LocalCIBuildResult runBuildJob(LocalCIBuildJobQueueItem buildJob, String
|| buildJob.repositoryInfo().triggeredByPushTo() == RepositoryType.AUXILIARY;

// get the local repository paths for assignment, tests, auxiliary and solution
LocalVCRepositoryUri assignmentRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().assignmentRepositoryUri(), localVCBaseUrl);
LocalVCRepositoryUri testsRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().testRepositoryUri(), localVCBaseUrl);
LocalVCRepositoryUri assignmentRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().assignmentRepositoryUri());
LocalVCRepositoryUri testsRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().testRepositoryUri());

// retrieve last commit hash from repositories
String assignmentCommitHash = buildJob.buildConfig().commitHash();
Expand Down Expand Up @@ -174,7 +174,7 @@ public LocalCIBuildResult runBuildJob(LocalCIBuildJobQueueItem buildJob, String
LocalVCRepositoryUri solutionRepoUri = null;
Path solutionRepositoryPath = null;
if (buildJob.repositoryInfo().solutionRepositoryUri() != null) {
solutionRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().solutionRepositoryUri(), localVCBaseUrl);
solutionRepoUri = new LocalVCRepositoryUri(buildJob.repositoryInfo().solutionRepositoryUri());
// In case we have the same repository for assignment and solution, we can use the same path
if (Objects.equals(solutionRepoUri.repositorySlug(), assignmentRepoUri.repositorySlug())) {
solutionRepositoryPath = assignmentRepositoryPath;
Expand All @@ -190,7 +190,7 @@ public LocalCIBuildResult runBuildJob(LocalCIBuildJobQueueItem buildJob, String

int index = 0;
for (String auxiliaryRepositoryUri : auxiliaryRepositoryUriList) {
auxiliaryRepositoriesUris[index] = new LocalVCRepositoryUri(auxiliaryRepositoryUri, localVCBaseUrl);
auxiliaryRepositoriesUris[index] = new LocalVCRepositoryUri(auxiliaryRepositoryUri);
auxiliaryRepositoriesPaths[index] = cloneRepository(auxiliaryRepositoriesUris[index], assignmentCommitHash, false, buildJob.id());
index++;
}
Expand Down
Loading
Loading