svn cleanup and update

main
guidohollander 3 years ago
parent 64a50f560d
commit dbcc71dc92

@ -10,6 +10,9 @@
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
}, },
"runOptions": {
"runOn": "folderOpen"
},
"label": "tsc: watch - tsconfig.json" "label": "tsc: watch - tsconfig.json"
} }
] ]

@ -7,7 +7,7 @@
"license": "ISC", "license": "ISC",
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc && copyfiles -u 1 \"src/data/*.json\" dist",
"format": "prettier --write .", "format": "prettier --write .",
"prepare": "husky install", "prepare": "husky install",
"lint": "eslint ." "lint": "eslint ."

@ -0,0 +1,83 @@
[
{
"name": "MBS_ANGUILLA",
"functionalName": "MBS Anguilla",
"customer": "ANGUILLA",
"customerCode": "aia_mbs",
"path": "D:\\repo\\mbs_anguilla_21\\",
"class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MBS_ANGUILLA/trunk"
},
{
"name": "MTS_ANGUILLA",
"functionalName": "MTS Anguilla",
"customer": "ANGUILLA ",
"customerCode": "aia_mts",
"path": "D:\\repo\\mts_anguilla_21\\",
"class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_ANGUILLA/trunk"
},
{
"name": "ONLINE_ANGUILLA",
"functionalName": "Online Anguilla",
"customer": "ANGUILLA",
"customerCode": "aia_online",
"path": "D:\\repo\\online_anguilla\\",
"class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_ANGUILLA/trunk"
},
{
"name": "MTS_SKN",
"functionalName": "MTS Saint Kitts and Nevis",
"customer": "SKN",
"customerCode": "skn_mts",
"path": "D:\\repo\\mts_skn\\",
"class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_SKN/trunk"
},
{
"name": "ONLINE_SKN",
"functionalName": "Online Saint Kitts and Nevis",
"customer": "SKN",
"customerCode": "skn_online",
"path": "D:\\repo\\online_skn\\",
"class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_SKN/trunk"
},
{
"name": "BDSU_MTS",
"functionalName": "MTS Belastingdienst Suriname",
"customer": "Belastingdienst Suriname",
"customerCode": "bdsu_mts",
"path": "D:\\repo\\mts_bdsu\\",
"class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/BDSU_MTS/trunk",
"test": true
},
{
"name": "MTS_GRENADA",
"functionalName": "MTS Grenada",
"customer": "GRENADA",
"customerCode": "gd_mts",
"path": "D:\\repo\\mts_grenada\\",
"class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_GRENADA/trunk"
},
{
"name": "ONLINE_GD",
"functionalName": "Online Grenada",
"customer": "GRENADA",
"customerCode": "gd_online",
"path": "D:\\repo\\online_gd\\",
"class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_GD/trunk"
}
]

@ -7,7 +7,8 @@
"path": "D:\\repo\\mbs_anguilla_21\\", "path": "D:\\repo\\mbs_anguilla_21\\",
"class": "MxS", "class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MBS_ANGUILLA/trunk" "url": "/svn/MBS_ANGUILLA/trunk",
"selected": true
}, },
{ {
"name": "MTS_ANGUILLA", "name": "MTS_ANGUILLA",
@ -17,7 +18,8 @@
"path": "D:\\repo\\mts_anguilla_21\\", "path": "D:\\repo\\mts_anguilla_21\\",
"class": "MxS", "class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_ANGUILLA/trunk" "url": "/svn/MTS_ANGUILLA/trunk",
"selected": true
}, },
{ {
"name": "ONLINE_ANGUILLA", "name": "ONLINE_ANGUILLA",
@ -27,7 +29,8 @@
"path": "D:\\repo\\online_anguilla\\", "path": "D:\\repo\\online_anguilla\\",
"class": "ONLINE", "class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_ANGUILLA/trunk" "url": "/svn/ONLINE_ANGUILLA/trunk",
"selected": false
}, },
{ {
"name": "MTS_SKN", "name": "MTS_SKN",
@ -37,7 +40,8 @@
"path": "D:\\repo\\mts_skn\\", "path": "D:\\repo\\mts_skn\\",
"class": "MxS", "class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_SKN/trunk" "url": "/svn/MTS_SKN/trunk",
"selected": true
}, },
{ {
"name": "ONLINE_SKN", "name": "ONLINE_SKN",
@ -47,7 +51,8 @@
"path": "D:\\repo\\online_skn\\", "path": "D:\\repo\\online_skn\\",
"class": "ONLINE", "class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_SKN/trunk" "url": "/svn/ONLINE_SKN/trunk",
"selected": false
}, },
{ {
"name": "BDSU_MTS", "name": "BDSU_MTS",
@ -58,7 +63,8 @@
"class": "MxS", "class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/BDSU_MTS/trunk", "url": "/svn/BDSU_MTS/trunk",
"test": true "test": true,
"selected": false
}, },
{ {
"name": "MTS_GRENADA", "name": "MTS_GRENADA",
@ -68,7 +74,8 @@
"path": "D:\\repo\\mts_grenada\\", "path": "D:\\repo\\mts_grenada\\",
"class": "MxS", "class": "MxS",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/MTS_GRENADA/trunk" "url": "/svn/MTS_GRENADA/trunk",
"selected": true
}, },
{ {
"name": "ONLINE_GD", "name": "ONLINE_GD",
@ -78,6 +85,7 @@
"path": "D:\\repo\\online_gd\\", "path": "D:\\repo\\online_gd\\",
"class": "ONLINE", "class": "ONLINE",
"baseUrl": "https://svn.bearingpointcaribbean.com", "baseUrl": "https://svn.bearingpointcaribbean.com",
"url": "/svn/ONLINE_GD/trunk" "url": "/svn/ONLINE_GD/trunk",
"selected": false
} }
] ]

@ -0,0 +1,130 @@
import { DirType } from "./types.js";
import { ExternalComponentResource } from "./ExternalComponentResource.js";
export class AngloResource {
protected _url = "";
protected _baseUrl = "";
protected _fullUrl = "";
protected _bareComponentUrl = "";
protected _repository = "";
protected _repositoryUrl = "";
protected _componentFolder?: string;
protected _implementationUrl = "";
protected _dirType: DirType = DirType.trunk;
protected _version?: string;
protected _componentName = "";
constructor(baseUrl: string, url: string) {
this.parseUrl(baseUrl, url);
}
baseUrl(): string {
return this._baseUrl;
}
fullUrl(): string {
return this._fullUrl;
}
implementationUrl(): string {
return this._implementationUrl;
}
repositoryName(): string {
return this._repository;
}
repositoryUrl(): string {
return this._repositoryUrl;
}
dirType(): DirType {
return this._dirType;
}
dirTypeAndVersion(): string {
if (
(this._dirType === DirType.tags || this._dirType === DirType.branches) &&
this._version
) {
return `${this._dirType}/${this._version}`;
}
return `${this._dirType}`;
}
url(): string {
return this._url;
}
version(): string | undefined {
return this._version;
}
private parseUrl(baseUrl: string, url: string): void {
this._url = url;
this._baseUrl = baseUrl;
this._fullUrl = `${baseUrl}${url}`;
const regex = /^(https?:\/\/[^]+\/svn\/)/; //const regex = /^(https?:\/\/[^\/]+\/svn\/)/;
const match = regex.exec(this._fullUrl);
if (!(match && match.length > 1)) {
throw new Error("Invalid URL");
}
const segments = this._fullUrl.split("/");
const svnIndex = segments.indexOf("svn");
const trunkTagBranchIndex = segments.findIndex(
(segment, index) =>
index > svnIndex &&
(segment === "trunk" || segment === "tags" || segment === "branches")
);
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 instanceof ExternalComponentResource) {
this._componentFolder = nextSegment;
}
}
}
if (trunkTagBranchIndex !== -1 && trunkTagBranchIndex < segments.length) {
this._dirType = segments[trunkTagBranchIndex] as DirType;
if (this._dirType === "tags" || this._dirType === "branches") {
if (trunkTagBranchIndex + 1 < segments.length) {
this._version = this.normalizeVersion(
segments[trunkTagBranchIndex + 1]
);
if (trunkTagBranchIndex + 2 < segments.length) {
this._componentName = segments[trunkTagBranchIndex + 2];
}
}
} else if (trunkTagBranchIndex + 1 < segments.length) {
this._componentName = segments[trunkTagBranchIndex + 1];
}
}
this._implementationUrl = segments
.slice(0, trunkTagBranchIndex + (this._version === undefined ? 1 : 2))
.join("/");
this._bareComponentUrl = segments
.slice(0, trunkTagBranchIndex)
.join("/")
.replaceAll(baseUrl, "");
} else {
throw new Error("Invalid URL");
}
}
private normalizeVersion(version: string): string {
// when a version has more than 3 segments (which is an illegal semver), prefix the remaining segments with -, ie. 1.2.3-4
const segments = version.split(".");
if (segments.length <= 3) {
return version;
} else {
const lastSegments = segments.slice(2); // Join the last segments together
return `${segments[0]}.${segments[1]}.${lastSegments.join("-")}`;
}
}
}

@ -0,0 +1,98 @@
import * as semver from "semver";
import {
type SemVerIncrementType,
ExternalResourceUpdate,
DirType,
} from "./types.js";
import { svnTagsBranchesList } from "./svn.js";
import { ExternalComponentResource } from "./ExternalComponentResource.js";
import { ImplementationResource } from "./ImplementationResource.js";
import { AngloResource } from "./AngloResource.js";
export class AngloVersionedResource extends AngloResource {
protected _latestVersion?: ImplementationResource | ExternalComponentResource;
protected _nextVersion?: string | null;
public async hasUpdate(
dirType: DirType = DirType.tags
): Promise<ExternalResourceUpdate> {
let returnValue: ExternalResourceUpdate = {
hasUpdate: false,
toVersion: undefined,
};
if (this._version && this._dirType === dirType) {
if (!this._latestVersion) {
await this.getLatestVersion(DirType.tags);
}
const hasUpdate = semver.lt(
this._version as string,
this._latestVersion?.version() as string
);
if (hasUpdate) {
returnValue = {
hasUpdate,
toVersion: this._latestVersion as ExternalComponentResource,
};
}
}
return returnValue;
}
public async getLatestVersion(
dirType: DirType
): Promise<ImplementationResource | ExternalComponentResource> {
try {
const lastTagOrBranch = await svnTagsBranchesList(
dirType,
this._baseUrl,
this._bareComponentUrl,
true
);
const lastTagUrl = `${this._bareComponentUrl}${lastTagOrBranch}`;
if (this instanceof ExternalComponentResource) {
this._latestVersion = new ExternalComponentResource(
this._baseUrl,
lastTagUrl,
this._parentSolutionImplementation
);
} else {
this._latestVersion = new ImplementationResource(
this._baseUrl,
lastTagUrl,
undefined
);
}
return this._latestVersion;
} catch (error) {
console.error("Error retrieving last tag or branch:", error);
throw error;
}
}
public async getNextVersion(
dirType: DirType,
semVerIncrementType: SemVerIncrementType
): Promise<string | undefined> {
if (this._version || this._dirType === "trunk") {
await this.getLatestVersion(dirType)
.then((latestTagSolutionImplementation) => {
if (
semver.valid(
semver.coerce(latestTagSolutionImplementation.version())
)
) {
const sv: string | null | undefined =
latestTagSolutionImplementation.version();
if (semver.inc(sv as string, semVerIncrementType)) {
this._nextVersion = semver.inc(sv as string, semVerIncrementType);
}
} else {
this._nextVersion = undefined;
}
})
.catch((error) => {
console.log(error);
});
return this._nextVersion as string;
}
}
}

@ -0,0 +1,50 @@
import { AngloVersionedResource } from "./AngloVersionedResource.js";
import { ImplementationResource } from "./ImplementationResource.js";
import { svnUpdate } from "./svn.js";
export class ExternalComponentResource extends AngloVersionedResource {
public _parentSolutionImplementation: ImplementationResource;
constructor(
baseUrl: string,
url: string,
parentSolutionImplementation: ImplementationResource
) {
super(baseUrl, url);
this._parentSolutionImplementation = parentSolutionImplementation;
}
componentFolder(): string | undefined {
return this._componentFolder;
}
componentName(): string {
return this._componentName;
}
componentNameDecoded(): string {
return decodeURIComponent(this._componentName);
}
componentNameEncoded(): string {
return encodeURIComponent(this._componentName);
}
parentSolutionImplementation(): ImplementationResource {
return this._parentSolutionImplementation;
}
public async tag(): Promise<ExternalComponentResource> {
// todo
return new ExternalComponentResource(
this._baseUrl,
this._url,
this._parentSolutionImplementation
);
}
public async update(): Promise<void> {
if (
this._parentSolutionImplementation._implementationContext &&
this._componentName
) {
await svnUpdate(
`${this._parentSolutionImplementation._implementationContext.path}${this._componentName}`
);
}
}
}

@ -0,0 +1,82 @@
import {
ExternalComponent,
DirType,
InternalComponent,
TypeSolutionImplementation,
} from "./types.js";
import { svnList, svnPropGet } from "./svn.js";
import { ExternalComponentResource } from "./ExternalComponentResource.js";
import { AngloVersionedResource } from "./AngloVersionedResource.js";
import { InternalComponentResource } from "./InternalComponentResource.js";
export class ImplementationResource extends AngloVersionedResource {
protected _externalsCollection: ExternalComponentResource[] = [];
protected _internalsCollection: InternalComponentResource[] = [];
public _implementationContext?: TypeSolutionImplementation | undefined;
constructor(
baseUrl: string,
url: string,
implementationContext: TypeSolutionImplementation | undefined
) {
super(baseUrl, url);
this._implementationContext = implementationContext;
}
public async getExternals(): Promise<ExternalComponentResource[]> {
const propGetResult = await svnPropGet(
"svn:externals",
this._baseUrl,
this._url
);
propGetResult.forEach((externalComponent: ExternalComponent) => {
const thisExternal = new ExternalComponentResource(
this._baseUrl,
externalComponent.path,
this
);
this._externalsCollection.push(thisExternal);
});
return this._externalsCollection.filter(
(project) => !project.componentName().includes("FRONTEND")
);
}
public async getInternals(): Promise<InternalComponentResource[]> {
const svnListResult: InternalComponent[] = await svnList(
this._baseUrl,
this._url
);
svnListResult.forEach((internalComponent: InternalComponent) => {
const thisInternal = new InternalComponentResource(
this._baseUrl,
`${this._url}/${internalComponent}`,
this
);
this._internalsCollection.push(thisInternal);
});
return this._internalsCollection;
}
public async deploymentCheck(): Promise<ExternalComponentResource[]> {
if (!this._externalsCollection) {
await this.getExternals();
}
return this._externalsCollection.filter(
(externalComponentResource: ExternalComponentResource) => {
return externalComponentResource.dirType() === DirType.trunk;
}
);
}
public async tag(): Promise<ImplementationResource> {
return new ImplementationResource(
this._baseUrl,
this._url,
this._implementationContext
);
}
}

@ -0,0 +1,86 @@
import * as fs from "fs";
import { DirType, TypeSolutionImplementation } from "./types.js";
import { InternalComponentResource } from "./InternalComponentResource.js";
import { ImplementationResource } from "./ImplementationResource.js";
import { ExternalComponentResource } from "./ExternalComponentResource.js";
export class ImplementationResourceReader {
_solutionImplementationsInFile: TypeSolutionImplementation[];
_solutionImplementationCollection: ImplementationResource[] = [];
constructor() {
const json = fs.readFileSync("solutions.json", "utf-8");
this._solutionImplementationsInFile = JSON.parse(json).filter(
(solutionImplementation: TypeSolutionImplementation) => {
return solutionImplementation.selected;
}
);
}
// get solutionImplementationCollection(): Promise<SolutionImplementation[]> {
// return this._solutionImplementationCollection;
// }
public async load(
autoLoadInternals = true,
autoLoadExternals = false
): Promise<ImplementationResource[]> {
await Promise.all(
this._solutionImplementationsInFile.map(
async (solutionImplementation: TypeSolutionImplementation) => {
const thisSolutionImplementation = new ImplementationResource(
solutionImplementation.baseUrl,
solutionImplementation.url,
solutionImplementation
);
if (autoLoadExternals) {
const externals = await thisSolutionImplementation.getExternals();
// externals.forEach(
// async (externalComponentResource: ExternalComponentResource) => {
// const latestVersionExternalComponentResource =
// await externalComponentResource.getLatestVersion(
// DirType.tags
// );
// const hasUpdate = await externalComponentResource.hasUpdate(
// DirType.tags
// );
// console.log(
// `[External] ${externalComponentResource.componentName()}: current version: ${externalComponentResource.version()} - latest version: ${latestVersionExternalComponentResource.version()} - has update?: ${hasUpdate.toVersion?.version()}`
// );
// }
// );
externals.forEach(
async (externalComponentResource: ExternalComponentResource) => {
externalComponentResource.update();
}
);
}
if (autoLoadInternals) {
const internals = await thisSolutionImplementation.getInternals();
internals.forEach(
async (internalComponentResource: InternalComponentResource) => {
internalComponentResource.update();
}
);
}
this._solutionImplementationCollection.push(
thisSolutionImplementation
);
}
)
);
return this._solutionImplementationCollection;
}
public readSolutionUrl(): void {
this._solutionImplementationsInFile.forEach(
(solutionImplementation: TypeSolutionImplementation) => {
const s = new ImplementationResource(
solutionImplementation.baseUrl,
solutionImplementation.url,
solutionImplementation
);
console.log(JSON.stringify(s, null, 2));
}
);
}
}

@ -0,0 +1,34 @@
import { AngloResource } from "./AngloResource.js";
import { ImplementationResource } from "./ImplementationResource.js";
import { svnUpdate } from "./svn.js";
export class InternalComponentResource extends AngloResource {
public _parentSolutionImplementation: ImplementationResource;
constructor(
baseUrl: string,
url: string,
parentSolutionImplementation: ImplementationResource
) {
super(baseUrl, url);
this._parentSolutionImplementation = parentSolutionImplementation;
}
public async checkSpecifics(): Promise<boolean> {
// todo
return true;
}
public async update(): Promise<void> {
if (
this._parentSolutionImplementation._implementationContext &&
this._componentName
) {
await svnUpdate(
`${this._parentSolutionImplementation._implementationContext.path}${this._componentName}`
);
}
}
parentSolutionImplementation(): ImplementationResource {
return this._parentSolutionImplementation;
}
}

@ -1,259 +0,0 @@
import * as semver from "semver";
import {
type SemVerIncrementType,
ExternalComponent,
DirType,
InternalComponent,
SVNList,
} from "./types.js";
import { svnList, svnPropGet, svnTagsBranchesList } from "./svn.js";
export class SolutionImplementation {
#url = "";
#baseUrl = "";
#fullUrl = "";
#bareComponentUrl = "";
#repository = "";
#repositoryUrl = "";
#componentFolder?: string;
#isSolutionComponent = false;
#isInternal = false;
#isImplementation = false;
#implementationUrl = "";
#dirType: DirType = DirType.trunk;
#version?: string;
#nextVersion?: string | null;
#externalsCollection: SolutionImplementation[] = [];
#internalsCollection: SolutionImplementation[] = [];
#parentSolutionImplementation?: SolutionImplementation;
#componentName = "";
constructor(
baseUrl: string,
url: string,
parentSolutionImplementation?: SolutionImplementation
) {
this.parseUrl(baseUrl, url);
this.#parentSolutionImplementation = parentSolutionImplementation;
}
baseUrl(): string {
return this.#baseUrl;
}
componentFolder(): string | undefined {
return this.#componentFolder;
}
componentName(): string {
return this.#componentName;
}
componentNameDecoded(): string {
return decodeURIComponent(this.#componentName);
}
componentNameEncoded(): string {
return encodeURIComponent(this.#componentName);
}
fullUrl(): string {
return this.#fullUrl;
}
implementationUrl(): string {
return this.#implementationUrl;
}
isImplementation(): boolean {
return this.#isImplementation;
}
isInternal(): boolean {
return this.#isInternal;
}
isSolutionComponent(): boolean {
return this.#isSolutionComponent;
}
parentSolutionImplementation(): SolutionImplementation | undefined {
if (this.#parentSolutionImplementation) {
return this.#parentSolutionImplementation;
}
return undefined;
}
repositoryName(): string {
return this.#repository;
}
repositoryUrl(): string {
return this.#repositoryUrl;
}
dirType(): DirType {
return this.#dirType;
}
dirTypeAndVersion(): string {
if (
(this.#dirType === DirType.tags || this.#dirType === DirType.branches) &&
this.#version
) {
return `${this.#dirType}/${this.#version}`;
}
return `${this.#dirType}`;
}
url(): string {
return this.#url;
}
version(): string | undefined {
return this.#version;
}
public async getNextVersion(
dirType: DirType,
semVerIncrementType: SemVerIncrementType
): Promise<string | undefined> {
await this.getLatestVersion(dirType)
.then((latestTagSolutionImplementation) => {
if (
semver.valid(semver.coerce(latestTagSolutionImplementation.version()))
) {
const sv: string | null | undefined =
latestTagSolutionImplementation.version();
if (semver.inc(sv as string, semVerIncrementType)) {
this.#nextVersion = semver.inc(sv as string, semVerIncrementType);
}
} else {
this.#nextVersion = undefined;
}
})
.catch((error) => {
console.log(error);
});
return this.#nextVersion as string;
}
public async getLatestVersion(
dirType: DirType
): Promise<SolutionImplementation> {
try {
const lastTagOrBranch = await svnTagsBranchesList(
dirType,
this.#baseUrl,
this.#bareComponentUrl,
true
);
const lastTagUrl = `${this.#bareComponentUrl}${lastTagOrBranch}`;
return new SolutionImplementation(this.#baseUrl, lastTagUrl);
} catch (error) {
console.error("Error retrieving last tag or branch:", error);
throw error;
}
}
public async getExternals(): Promise<SolutionImplementation[]> {
try {
if (this.#isImplementation) {
const propGetResult = await svnPropGet(
"svn:externals",
this.#baseUrl,
this.#url
);
propGetResult.forEach((externalComponent: ExternalComponent) => {
const thisExternal = new SolutionImplementation(
this.#baseUrl,
externalComponent.path,
this
);
this.#externalsCollection.push(thisExternal);
});
}
return this.#externalsCollection;
} catch (error) {
console.error("Error retrieving externals:", error);
throw error;
}
}
public async getInternals(): Promise<SolutionImplementation[]> {
try {
if (this.#isImplementation) {
const svnListResult: InternalComponent[] = await svnList(
this.#baseUrl,
this.#url
);
svnListResult.forEach((internalComponent: InternalComponent) => {
const thisInternal = new SolutionImplementation(
this.#baseUrl,
`${this.#url}/${internalComponent}`,
this
);
this.#internalsCollection.push(thisInternal);
});
}
return this.#internalsCollection;
} catch (error) {
console.error("Error retrieving externals:", error);
throw error;
}
}
private parseUrl(baseUrl: string, url: string): void {
this.#url = url;
this.#baseUrl = baseUrl;
this.#fullUrl = `${baseUrl}${url}`;
const regex = /^(https?:\/\/[^]+\/svn\/)/; //const regex = /^(https?:\/\/[^\/]+\/svn\/)/;
const match = regex.exec(this.#fullUrl);
if (!(match && match.length > 1)) {
throw new Error("Invalid URL");
}
const segments = this.#fullUrl.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.#dirType = segments[trunkTagBranchIndex] as DirType;
if (this.#dirType === "tags" || this.#dirType === "branches") {
if (trunkTagBranchIndex + 1 < segments.length) {
this.#version = segments[trunkTagBranchIndex + 1];
if (trunkTagBranchIndex + 2 < segments.length) {
this.#componentName = segments[trunkTagBranchIndex + 2];
}
}
} else if (trunkTagBranchIndex + 1 < segments.length) {
this.#componentName = segments[trunkTagBranchIndex + 1];
}
}
this.#isImplementation =
this.#componentFolder === undefined && this.#componentName === "";
this.#implementationUrl = segments
.slice(0, trunkTagBranchIndex + (this.#version === undefined ? 1 : 2))
.join("/");
this.#bareComponentUrl = segments
.slice(0, trunkTagBranchIndex)
.join("/")
.replaceAll(baseUrl, "");
} else {
throw new Error("Invalid URL");
}
}
}

@ -1,47 +0,0 @@
import * as fs from "fs";
import { type TypeSolutionImplementation, DirType } from "./types";
import { SolutionImplementation } from "./SolutionImplementation.js";
export class SolutionImplementationReader {
#solutionImplementationsInFile: TypeSolutionImplementation[];
#_solutionImplementationCollection: SolutionImplementation[] = [];
constructor() {
const json = fs.readFileSync("solutions.json", "utf-8");
this.#solutionImplementationsInFile = JSON.parse(json);
}
// get solutionImplementationCollection(): Promise<SolutionImplementation[]> {
// return this._solutionImplementationCollection;
// }
public async load(): Promise<SolutionImplementation[]> {
await Promise.all(
this.#solutionImplementationsInFile.map(
async (solutionImplementation: TypeSolutionImplementation) => {
const thisSolutionImplementation = new SolutionImplementation(
solutionImplementation.baseUrl,
solutionImplementation.url
);
this.#_solutionImplementationCollection.push(
thisSolutionImplementation
);
await thisSolutionImplementation.getInternals();
await thisSolutionImplementation.getExternals();
}
)
);
return this.#_solutionImplementationCollection;
}
public readSolutionUrl(): void {
this.#solutionImplementationsInFile.forEach(
(solutionImplementation: TypeSolutionImplementation) => {
const s = new SolutionImplementation(
solutionImplementation.baseUrl,
solutionImplementation.url
);
console.log(JSON.stringify(s, null, 2));
}
);
}
}

@ -0,0 +1,8 @@
[
".metadata",
"TEST",
"com.bearingpoint.ird.anguilla.remoting_connector",
"console-1.0-dev.jar",
"migrations.bat",
"etc"
]

@ -1,12 +1,23 @@
import { Dir } from "fs"; import { ImplementationResourceReader } from "./ImplementationResourceReader.js";
import { SolutionImplementation } from "./SolutionImplementation.js"; import { ImplementationResource } from "./ImplementationResource.js";
import { DirType } from "./types.js"; import { ExternalComponentResource } from "./ExternalComponentResource.js";
import { SolutionImplementationReader } from "./SolutionImplementationReader.js"; import { ExternalComponent } from "./types.js";
// import { SolutionImplementationReader } from "./SolutionImplementationReader.js";
// import { svnPropGet, svnList, svnGetLatestTag, } from "./svn.js"; // import { svnPropGet, svnList, svnGetLatestTag, } from "./svn.js";
const baseUrl = "https://svn.bearingpointcaribbean.com"; // const baseUrl = 'https://svn.bearingpointcaribbean.com';
const url = "/svn/MBS_ANGUILLA/trunk"; // const url = '/svn/MBS_ANGUILLA/trunk';
async function deploymentCheck() {
const reader = new ImplementationResourceReader();
const implementationResources = await reader.load(true, true);
implementationResources.forEach(
async (implementationResource: ImplementationResource) => {
const collectionOfComponentToBeTagged: ExternalComponentResource[] =
await implementationResource.deploymentCheck();
console.log(collectionOfComponentToBeTagged);
}
);
}
// async function start() { // async function start() {
// svnList(baseUrl, url) // svnList(baseUrl, url)
@ -82,13 +93,8 @@ const url = "/svn/MBS_ANGUILLA/trunk";
// // console.log(await currentSolution.getExternals()); // // console.log(await currentSolution.getExternals());
// } // }
async function start5() {
const reader = new SolutionImplementationReader();
const output = await reader.load();
console.log(output);
}
//start(); //start();
//start2(); //start2();
//start3(); //start3();
// start4(); // start4();
start5(); deploymentCheck();

@ -1,94 +0,0 @@
import { SolutionImplementation } from "./SolutionImplementation";
import { SolutionImplementationReader } from "./SolutionImplementationReader";
// Const trunkUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGLO/Business_Licence/trunk/DSC%20Business%20license';
// const tagUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGLO/Interim_Stabilization_Levy/tags/1.0.0/DSC%20Interim%20stabilization%20levy';
// const branchUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGUILLA/branches/1.5.0/SC%20Address%20-%20Specific';
// const trunkSolutionUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGUILLA/trunk';
// const tagSolutionUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGUILLA/tags/2.1.1.1';
// const branchSolutionUrl = 'https://svn.bearingpointcaribbean.com/svn/MTS_ANGUILLA/branches/2.1.1';
async function showOutPut() {
console.log();
}
// ShowOutPut();
// Usage
const solutionImplementations = [];
const solutionImplementationReader = new SolutionImplementationReader();
// SolutionImplementations.push(solutionImplementationReader.readSolutionUrl());
// solution = new SolutionImplementation(tagUrl);
// console.log('solution.getURL():', solution.getURL());
// console.log('solution.getBaseURL():', solution.getBaseURL());
// console.log('solution.getRepository():', solution.getRepository());
// console.log('solution.getComponentFolder():', solution.getComponentFolder());
// console.log('solution.isSolutionComponent():', solution.isSolutionComponent());
// console.log('solution.isImplementation():', solution.isImplementation());
// console.log('solution.getType():', solution.getType());
// console.log('solution.getVersion():', solution.getVersion());
// console.log('solution.getTypeAndVersion():', solution.getTypeAndVersion());
// console.log('solution.getComponent():', solution.getComponent());
// console.log('solution.getComponentDecoded():', solution.getComponentDecoded());
// console.log('solution.getImplementationURL():', solution.getImplementationURL());
// console.log('--');
// solution = new SolutionImplementation(branchUrl);
// console.log('solution.getURL():', solution.getURL());
// console.log('solution.getBaseURL():', solution.getBaseURL());
// console.log('solution.getRepository():', solution.getRepository());
// console.log('solution.getComponentFolder():', solution.getComponentFolder());
// console.log('solution.isSolutionComponent():', solution.isSolutionComponent());
// console.log('solution.isImplementation():', solution.isImplementation());
// console.log('solution.getType():', solution.getType());
// console.log('solution.getVersion():', solution.getVersion());
// console.log('solution.getTypeAndVersion():', solution.getTypeAndVersion());
// console.log('solution.getComponent():', solution.getComponent());
// console.log('solution.getComponentDecoded():', solution.getComponentDecoded());
// console.log('solution.getImplementationURL():', solution.getImplementationURL());
// console.log('--');
// solution = new SolutionImplementation(trunkSolutionUrl);
// console.log('solution.getURL():', solution.getURL());
// console.log('solution.getBaseURL():', solution.getBaseURL());
// console.log('solution.getRepository():', solution.getRepository());
// console.log('solution.getComponentFolder():', solution.getComponentFolder());
// console.log('solution.isSolutionComponent():', solution.isSolutionComponent());
// console.log('solution.isImplementation():', solution.isImplementation());
// console.log('solution.getType():', solution.getType());
// console.log('solution.getVersion():', solution.getVersion());
// console.log('solution.getTypeAndVersion():', solution.getTypeAndVersion());
// console.log('solution.getComponent():', solution.getComponent());
// console.log('solution.getComponentDecoded():', solution.getComponentDecoded());
// console.log('solution.getImplementationURL():', solution.getImplementationURL());
// console.log('--');
// solution = new SolutionImplementation(tagSolutionUrl);
// console.log('solution.getURL():', solution.getURL());
// console.log('solution.getBaseURL():', solution.getBaseURL());
// console.log('solution.getRepository():', solution.getRepository());
// console.log('solution.getComponentFolder():', solution.getComponentFolder());
// console.log('solution.isSolutionComponent():', solution.isSolutionComponent());
// console.log('solution.isImplementation():', solution.isImplementation());
// console.log('solution.getType():', solution.getType());
// console.log('solution.getVersion():', solution.getVersion());
// console.log('solution.getTypeAndVersion():', solution.getTypeAndVersion());
// console.log('solution.getComponent():', solution.getComponent());
// console.log('solution.getComponentDecoded():', solution.getComponentDecoded());
// console.log('solution.getImplementationURL():', solution.getImplementationURL());
// console.log('--');
// solution = new SolutionImplementation(branchSolutionUrl);
// console.log('solution.getURL():', solution.getURL());
// console.log('solution.getBaseURL():', solution.getBaseURL());
// console.log('solution.getRepository():', solution.getRepository());
// console.log('solution.getComponentFolder():', solution.getComponentFolder());
// console.log('solution.isSolutionComponent():', solution.isSolutionComponent());
// console.log('solution.isImplementation():', solution.isImplementation());
// console.log('solution.getType():', solution.getType());
// console.log('solution.getVersion():', solution.getVersion());
// console.log('solution.getTypeAndVersion():', solution.getTypeAndVersion());
// console.log('solution.getComponent():', solution.getComponent());
// console.log('solution.getComponentDecoded():', solution.getComponentDecoded());
// console.log('solution.getImplementationURL():', solution.getImplementationURL());

@ -1,3 +1,5 @@
import exclusions from "./data/exclude.json" assert { type: "json" };
import * as fs from "fs";
import { exec } from "child_process"; import { exec } from "child_process";
import { parseString } from "xml2js"; import { parseString } from "xml2js";
import { import {
@ -21,7 +23,7 @@ function execShellCommand(cmd: string) {
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
async function svnCmd( async function svnCmdWithResponse(
cmd: string, cmd: string,
baseUrl: string, baseUrl: string,
url: string, url: string,
@ -59,23 +61,67 @@ export async function svnList(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<InternalComponent[]> { ): Promise<InternalComponent[]> {
const svnListResponse: InternalComponent[] = await svnCmd( try {
"list", const svnListResponse: InternalComponent[] = await svnCmdWithResponse(
baseUrl, "list",
url, baseUrl,
false url,
); false
);
type arrayOfSVNList = {
name: string[]; type arrayOfSVNList = {
}; name: string[];
};
const internals = svnListResponse.lists.list[0].entry.map(
({ name }: arrayOfSVNList) => `${name[0]}`
);
const excludeJson = fs.readFileSync("./dist/data/exclude.json", "utf-8");
const exclude = JSON.parse(excludeJson);
// const parsedExclusions = exclusions;
const filteredInternals = internals.filter(
(internal: string) => !exclusions.includes(internal)
);
// const internals = listResponse.lists.list[0].entry;
return filteredInternals;
} catch (error) {
console.log(error);
return [];
}
}
let internals = svnListResponse.lists.list[0].entry.map( async function svnCmdWithoutResponse(
({ name }) => `${name[0]}` cmd: string,
); localPath: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<any> {
return new Promise((resolve, reject) => {
const execCommand = `svn ${cmd} "${localPath}"`;
execShellCommand(execCommand)
.then((svnCmdResponse) => {
console.log(`Performed ${execCommand}`);
resolve(svnCmdResponse);
})
.catch((error) => {
reject(error);
});
});
}
// const internals = listResponse.lists.list[0].entry; export async function svnUpdate(localPath: string): Promise<void> {
return internals; try {
await svnCmdWithoutResponse("cleanup", localPath);
} catch (error) {
console.log(error);
}
try {
await svnCmdWithoutResponse("update", localPath);
} catch (error) {
console.log(error);
}
} }
export async function svnPropGet( export async function svnPropGet(
@ -83,7 +129,7 @@ export async function svnPropGet(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<[ExternalComponent]> { ): Promise<[ExternalComponent]> {
const propGetResponse = await svnCmd( const propGetResponse = await svnCmdWithResponse(
`propget ${property}`, `propget ${property}`,
baseUrl, baseUrl,
url, url,
@ -99,77 +145,95 @@ export async function svnTagsBranchesList(
baseUrl: string, baseUrl: string,
url: string, // expects url that has tags and branches url: string, // expects url that has tags and branches
latestOnly = false latestOnly = false
): Promise<[string]> { ): Promise<string[]> {
url = url.replace(/trunk$/, ""); try {
url = url.replace(/tags$/, ""); url = url.replace(/trunk$/, "");
url = url.replace(/branches$/, ""); url = url.replace(/tags$/, "");
url = dirType === "tags" ? url.concat("/tags") : url.concat("/branches"); url = url.replace(/branches$/, "");
const svnListResponse: SVNList = await svnCmd("list", baseUrl, url); url = dirType === "tags" ? url.concat("/tags") : url.concat("/branches");
const regex = /^[0-9.]+$/; // Regular expression for semantic version format const svnListResponse: SVNList = await svnCmdWithResponse(
type arrayOfSVNList = { "list",
name: string[]; baseUrl,
}; url
const filteredTags = svnListResponse.lists.list[0].entry.filter( );
(entry: arrayOfSVNList) => { const regex = /^[0-9.]+$/; // Regular expression for semantic version format
return regex.test(entry.name[0]); type arrayOfSVNList = {
} name: string[];
); };
let flattenedFilteredTags: string[] = filteredTags.map( if (
({ name }) => `${name[0]}` Object.prototype.hasOwnProperty.call(
); svnListResponse.lists.list[0],
"entry"
flattenedFilteredTags.sort((a, b) => { )
const partsA = a.split(".").map(Number); ) {
const partsB = b.split(".").map(Number); // filter any tag or branch version which do not comply with the format 0.0.0 / 0.0.0.0
const filteredTags = svnListResponse.lists.list[0].entry.filter(
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) { (entry: arrayOfSVNList) => {
const partA = partsA[i] || 0; return regex.test(entry.name[0]);
const partB = partsB[i] || 0; }
);
if (partA > partB) { // only leave the name in the objects, get rid of the hyrachical structure
return -1; let flattenedFilteredTags: string[] = filteredTags.map(
} else if (partA < partB) { ({ name }) => `${name[0]}`
return 1; );
flattenedFilteredTags.sort((a, b) => {
const partsA = a.split(".").map(Number);
const partsB = b.split(".").map(Number);
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
const partA = partsA[i] || 0;
const partB = partsB[i] || 0;
if (partA > partB) {
return -1;
} else if (partA < partB) {
return 1;
}
}
return 0;
});
flattenedFilteredTags.sort((a, b) => b.localeCompare(a));
flattenedFilteredTags = flattenedFilteredTags.map(
(element) => (element = `/${dirType}/${element}`)
);
if (latestOnly) {
return [flattenedFilteredTags[0]];
} else {
return flattenedFilteredTags;
} }
} }
return 0; } catch (error) {
}); console.log(`${url} does not have a ${dirType}: ${error}`);
flattenedFilteredTags.sort((a, b) => b.localeCompare(a)); return [];
flattenedFilteredTags = flattenedFilteredTags.map(
(element) => (element = `/${dirType}/${element}`)
);
if (latestOnly) {
return [flattenedFilteredTags[0]];
} else {
return flattenedFilteredTags as [string];
} }
} }
export async function svnGetLatestTag( export async function svnGetLatestTag(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<[string]> { ): Promise<string[]> {
return svnTagsBranchesList(DirType.tags, baseUrl, url, true); return svnTagsBranchesList(DirType.tags, baseUrl, url, true);
} }
export async function svnGetLatestBranch( export async function svnGetLatestBranch(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<[string]> { ): Promise<string[]> {
return svnTagsBranchesList(DirType.branches, baseUrl, url, true); return svnTagsBranchesList(DirType.branches, baseUrl, url, true);
} }
export async function svnGetTagList( export async function svnGetTagList(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<[string]> { ): Promise<string[]> {
return svnTagsBranchesList(DirType.tags, baseUrl, url, false); return svnTagsBranchesList(DirType.tags, baseUrl, url, false);
} }
export async function svnGetBranchesList( export async function svnGetBranchesList(
baseUrl: string, baseUrl: string,
url: string url: string
): Promise<[string]> { ): Promise<string[]> {
return svnTagsBranchesList(DirType.branches, baseUrl, url, false); return svnTagsBranchesList(DirType.branches, baseUrl, url, false);
} }

@ -1,3 +1,5 @@
import { ExternalComponentResource } from "./ExternalComponentResource";
export type SVNProperties = { export type SVNProperties = {
properties: { properties: {
target: { target: {
@ -51,6 +53,11 @@ export type InternalComponent = {
version: string; version: string;
}; };
export type ExternalResourceUpdate = {
hasUpdate: boolean;
toVersion?: ExternalComponentResource;
};
export type SemVerIncrementType = "minor" | "major" | "patch"; export type SemVerIncrementType = "minor" | "major" | "patch";
export enum DirType { export enum DirType {
tags = "tags", tags = "tags",
@ -67,6 +74,7 @@ export type TypeSolutionImplementation = {
class: string; class: string;
baseUrl: string; baseUrl: string;
url: string; url: string;
selected: boolean;
}; };
export type ApiExternalsResponse = { export type ApiExternalsResponse = {

@ -39,7 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */ "resolveJsonModule": true /* Enable importing .json files. */,
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

Loading…
Cancel
Save

Powered by TurnKey Linux.