You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
5.2 KiB
211 lines
5.2 KiB
import * as semver from "semver";
|
|
import { type SemVerIncrementType, type ApiExternalsResponse } from "./types";
|
|
import { svnList, svnGetLatestTag, svnPropGet } from "./promises";
|
|
|
|
export class SolutionImplementation {
|
|
private url = "";
|
|
private baseUrl = "";
|
|
private repository = "";
|
|
private repositoryUrl = "";
|
|
private componentFolder: string | undefined = null;
|
|
private _isSolutionComponent = false;
|
|
private _isImplementation = false;
|
|
private implementationUrl = "";
|
|
private type = "";
|
|
private version: string | undefined = null;
|
|
private nextVersion: string | undefined = null;
|
|
|
|
private component = "";
|
|
|
|
constructor(url: string) {
|
|
this.parseUrl(url);
|
|
}
|
|
|
|
getBaseUrl(): string {
|
|
return this.baseUrl;
|
|
}
|
|
|
|
getUrl(): string {
|
|
return this.url;
|
|
}
|
|
|
|
getImplementationUrl(): string {
|
|
return this.implementationUrl;
|
|
}
|
|
|
|
getRepository(): string {
|
|
return this.repository;
|
|
}
|
|
|
|
getRepositoryUrl(): string {
|
|
return this.repositoryUrl;
|
|
}
|
|
|
|
getComponentFolder(): string | undefined {
|
|
return this.componentFolder;
|
|
}
|
|
|
|
isSolutionComponent(): boolean {
|
|
return this._isSolutionComponent;
|
|
}
|
|
|
|
isImplementation(): boolean {
|
|
return this._isImplementation;
|
|
}
|
|
|
|
getType(): string {
|
|
return this.type;
|
|
}
|
|
|
|
getVersion(): string | undefined {
|
|
return this.version;
|
|
}
|
|
|
|
public async getNextVersion(
|
|
semVerIncrementType: SemVerIncrementType
|
|
): Promise<string | undefined> {
|
|
await this.getLatestTag()
|
|
.then((result) => {
|
|
if (semver.valid(semver.coerce(result))) {
|
|
const sv: string = result;
|
|
this.nextVersion = semver.inc(sv, semVerIncrementType);
|
|
} else {
|
|
this.nextVersion = null;
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
// Handle error
|
|
});
|
|
return this.nextVersion;
|
|
}
|
|
|
|
public async getLatestTag(): Promise<string> {
|
|
try {
|
|
const lastTagOrBranch = await svnGetLatestTag(this.implementationUrl);
|
|
return lastTagOrBranch.name;
|
|
} catch (error) {
|
|
console.error("Error retrieving last tag or branch:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
getTypeAndVersion(): string {
|
|
if ((this.type === "tags" || this.type === "branches") && this.version) {
|
|
return `${this.type}/${this.version}`;
|
|
}
|
|
|
|
return `${this.type}`;
|
|
}
|
|
|
|
getComponent(): string {
|
|
return this.component;
|
|
}
|
|
|
|
getComponentDecoded(): string {
|
|
return decodeURIComponent(this.component);
|
|
}
|
|
|
|
getExternalsRaw(): string {
|
|
return decodeURIComponent(this.component);
|
|
}
|
|
// GetExternalsCollection(): externalsCollection {
|
|
// return decodeURIComponent(this.component);
|
|
// }
|
|
|
|
public async getExternals(): Promise<string> {
|
|
const svnOptions = { trustServerCert: true };
|
|
try {
|
|
const response: ApiExternalsResponse = await svnPropGet(
|
|
"svn:externals",
|
|
this.url,
|
|
svnOptions
|
|
);
|
|
const rawExternals: string = response.target.property._;
|
|
return rawExternals;
|
|
} catch (error) {
|
|
console.error("Error retrieving last tag or branch:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
private parseUrl(url: string): void {
|
|
this.url = url;
|
|
|
|
const regex = /^(https?:\/\/[^\/]+\/svn\/)/;
|
|
const match = regex.exec(url);
|
|
|
|
if (match && match.length > 1) {
|
|
this.baseUrl = match[1];
|
|
} else {
|
|
throw new Error("Invalid URL");
|
|
}
|
|
|
|
const segments = url.split("/");
|
|
const svnIndex = segments.indexOf("svn");
|
|
const trunkTagBranchIndex = segments.findIndex(
|
|
(segment, index) =>
|
|
index > svnIndex &&
|
|
(segment === "trunk" || segment === "tags" || segment === "branches")
|
|
);
|
|
this._isSolutionComponent = trunkTagBranchIndex - svnIndex > 2;
|
|
|
|
if (svnIndex !== -1 && svnIndex + 1 < segments.length) {
|
|
this.repository = segments[svnIndex + 1];
|
|
this.repositoryUrl = `${this.baseUrl}${this.repository}`;
|
|
|
|
if (trunkTagBranchIndex !== -1 && trunkTagBranchIndex - 1 > svnIndex) {
|
|
const nextSegment = segments[trunkTagBranchIndex - 1];
|
|
|
|
if (
|
|
nextSegment !== "trunk" &&
|
|
nextSegment !== "tags" &&
|
|
nextSegment !== "branches"
|
|
) {
|
|
if (this._isSolutionComponent) {
|
|
this.componentFolder = nextSegment;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (trunkTagBranchIndex !== -1 && trunkTagBranchIndex < segments.length) {
|
|
this.type = segments[trunkTagBranchIndex];
|
|
|
|
if (this.type === "tags" || this.type === "branches") {
|
|
if (trunkTagBranchIndex + 1 < segments.length) {
|
|
this.version = segments[trunkTagBranchIndex + 1];
|
|
if (trunkTagBranchIndex + 2 < segments.length) {
|
|
this.component = segments[trunkTagBranchIndex + 2];
|
|
}
|
|
}
|
|
} else if (trunkTagBranchIndex + 1 < segments.length) {
|
|
this.component = segments[trunkTagBranchIndex + 1];
|
|
}
|
|
}
|
|
|
|
this._isImplementation =
|
|
this.componentFolder === null && this.component === "";
|
|
this.implementationUrl = segments
|
|
.slice(0, trunkTagBranchIndex + (this.version === null ? 1 : 2))
|
|
.join("/");
|
|
|
|
if (this._isImplementation) {
|
|
const rawExternals = this.getExternals();
|
|
}
|
|
} else {
|
|
throw new Error("Invalid URL");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper function to retrieve the last tag or branch
|
|
// async function getLastTagOrBranch(url: string): Promise<string> {
|
|
// try {
|
|
// const list = await svnListPromise(url);
|
|
// const sortedList = list.sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
// const lastTagOrBranch = sortedList[0].name;
|
|
// return lastTagOrBranch;
|
|
// } catch (error) {
|
|
// throw error;
|
|
// }
|
|
// }
|