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

Feature/colliehub version tag #281

Merged
merged 12 commits into from
Mar 13, 2024
2 changes: 1 addition & 1 deletion src/api/CliApiFacadeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class CliApiFacadeFactory {
const detectorRunner = this.buildQuietLoggingProcessRunner();
const detector = new GitCliDetector(detectorRunner);

const processRunner = this.buildTransparentProcessRunner(detector);
const processRunner = this.buildQuietLoggingProcessRunner();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole runner setup is quite complex. But when looking close we already have a process runner with the required type. I wonder if something like


  public buildGit() {
    const detectorRunner = this.buildQuietLoggingProcessRunner();
    const detector = new GitCliDetector(detectorRunner);

    const resultHandler = new ProcessRunnerErrorResultHandler(detector);
    const quietRunner = new ResultHandlerProcessRunnerDecorator(
      new QuietProcessRunner(),
      resultHandler,
    );

    return new GitCliFacade(detectorRunner, quietRunner);
  }

works too so we need one less runner?


const resultHandler = new ProcessRunnerErrorResultHandler(detector);
const quietRunner = new ResultHandlerProcessRunnerDecorator(
Expand Down
27 changes: 23 additions & 4 deletions src/api/git/GitCliFacade.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { IProcessRunner } from "../../process/IProcessRunner.ts";
import { ProcessResult } from "../../process/ProcessRunnerResult.ts";
import { ProcessResultWithOutput } from "../../process/ProcessRunnerResult.ts";
import { QuietProcessRunner } from "../../process/QuietProcessRunner.ts";

export class GitCliFacade {
constructor(
private readonly processRunner: IProcessRunner<ProcessResult>,
private readonly processRunner: IProcessRunner<ProcessResultWithOutput>,
private readonly quietRunner: QuietProcessRunner,
) {}

Expand All @@ -20,10 +20,29 @@ export class GitCliFacade {
await this.processRunner.run(["git", "clone", repoUrl, destDir]);
}

async pull(repoDir: string) {
await this.processRunner.run(["git", "pull"], { cwd: repoDir });
async getLatestTag(repoDir: string): Promise<string> {
const result = await this.processRunner.run([
"git",
"describe",
"--tags",
"--abbrev=0",
], { cwd: repoDir });
return result.stdout.trim();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return result.stdout.trim();
return result.stdout.trim();

s: empty line before return

}

async getTags(repoDir: string): Promise<string> {
const result = await this.processRunner.run([
"git",
"tag",
], { cwd: repoDir });
return result.stdout.trim();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s: empty line before return.

}

async checkout(repoDir: string, tagValue: string) {
await this.processRunner.run(["git", "checkout", tagValue], {
cwd: repoDir,
});
}
/**
* Checks if the given dir is a .git repo dir.
* This method is using a QuietProcessRunner because we typcially don't want to output repo detection logic via
Expand Down
7 changes: 4 additions & 3 deletions src/commands/compliance/import.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GlobalCommandOptions } from "../GlobalCommandOptions.ts";
import { TopLevelCommand } from "../TopLevelCommand.ts";
import { CliApiFacadeFactory } from "../../api/CliApiFacadeFactory.ts";
import { CollieHub } from "../../model/CollieHub.ts";
import { CollieConfig } from "../../model/CollieConfig.ts";

interface ImportOptions {
clean?: boolean;
Expand All @@ -31,16 +32,16 @@ export function registerImportCmd(program: TopLevelCommand) {

const factory = new CliApiFacadeFactory(logger);
const git = factory.buildGit();

const hub = new CollieHub(git, collie);
const config = new CollieConfig(collie, logger);
const hub = new CollieHub(git, collie, logger, config);

if (opts.clean) {
logger.progress("cleaning local cache of collie hub");
await hub.cleanHubClone();
}

logger.progress("updating local cache of collie hub from " + hub.url);
const hubDir = await hub.updateHubClone();
const hubDir = await hub.cloneLatestHub();

id = id || (await promptForComplianceFrameworkId(hubDir));

Expand Down
9 changes: 7 additions & 2 deletions src/commands/config/get.command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { GlobalCommandOptions } from "../GlobalCommandOptions.ts";
import { TopLevelCommand } from "../TopLevelCommand.ts";
import { CollieConfig } from "../../model/CollieConfig.ts";
import {
CollieConfig,
CollieConfigProperties,
} from "../../model/CollieConfig.ts";
import { Logger } from "../../cli/Logger.ts";
import { CollieRepository } from "../../model/CollieRepository.ts";
import { CLI } from "../../info.ts";
Expand All @@ -18,7 +21,9 @@ export function registerGetCmd(program: TopLevelCommand) {
const repo = await CollieRepository.load();
const logger = new Logger(repo, opts);
const config = new CollieConfig(repo, logger);
const value = config.getProperty(property);
const value = config.getProperty(
property as keyof CollieConfigProperties,
);
console.log(value);
},
);
Expand Down
3 changes: 1 addition & 2 deletions src/commands/init.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ const gitignore = `# terraform/terragrunt caches
.docs

# collie caches
.collie
**.collie.json
.collie/hub
**.meta.json
`;

Expand Down
7 changes: 4 additions & 3 deletions src/commands/kit/import.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { KitModuleRepository } from "../../kit/KitModuleRepository.ts";
import { ModelValidator } from "../../model/schemas/ModelValidator.ts";
import { InteractivePrompts } from "../../cli/InteractivePrompts.ts";
import { CollieHub } from "../../model/CollieHub.ts";
import { CollieConfig } from "../../model/CollieConfig.ts";

interface ImportOptions {
clean?: boolean;
Expand All @@ -33,16 +34,16 @@ export function registerImportCmd(program: TopLevelCommand) {

const factory = new CliApiFacadeFactory(logger);
const git = factory.buildGit();

const hub = new CollieHub(git, collie);
const config = new CollieConfig(collie, logger);
const hub = new CollieHub(git, collie, logger, config);

if (opts.clean) {
logger.progress("cleaning local cache of hub modules");
await hub.cleanHubClone();
}

logger.progress("updating local cache of hub modules from " + hub.url);
const hubDir = await hub.updateHubClone();
const hubDir = await hub.cloneLatestHub();

id = id || (await promptForKitModuleId(logger, hubDir));

Expand Down
7 changes: 4 additions & 3 deletions src/model/CollieConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CollieRepository } from "./CollieRepository.ts";

export interface CollieConfigProperties {
foundation?: string;
colliehubVersion?: string;
}

export class CollieConfig {
Expand All @@ -19,8 +20,8 @@ export class CollieConfig {
private configFilePath: string;
private properties: CollieConfigProperties;

getProperty(property: string) {
const value = this.properties["foundation"];
getProperty(property: keyof CollieConfigProperties) {
const value = this.properties[property];
if (value) {
this.logger.verbose(
() => `loaded ${property}="${value}" from ${this.configFilePath}`,
Expand All @@ -30,7 +31,7 @@ export class CollieConfig {
}

async setProperty(
property: "foundation",
property: keyof CollieConfigProperties,
value: string,
) {
this.properties[property] = value;
Expand Down
31 changes: 26 additions & 5 deletions src/model/CollieHub.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import * as fs from "std/fs";
import { GitCliFacade } from "/api/git/GitCliFacade.ts";
import { CollieRepository } from "/model/CollieRepository.ts";
import { CollieConfig } from "./CollieConfig.ts";
import { Logger } from "../cli/Logger.ts";

export class CollieHub {
constructor(
private readonly git: GitCliFacade,
private readonly repo: CollieRepository,
private readonly logger: Logger,
private readonly config: CollieConfig,
) {}
private readonly hubCacheDirPath = [".collie", "hub"];

// hardcoding this is ok for now
readonly url = "https://github.com/meshcloud/collie-hub.git";
readonly url = "https://github.com/meshcloud/collie-hub.git/";

public async importKitModule(
id: string,
Expand Down Expand Up @@ -40,7 +44,7 @@ export class CollieHub {
await fs.copy(srcDir, frameworkDestDir, { overwrite: overwrite });
}

async updateHubClone() {
async cloneLatestHub() {
const hubCacheDir = this.repo.resolvePath(...this.hubCacheDirPath);

// we do keep a git clone of the repo locally because copying on the local FS is much faster than downloading and
Expand All @@ -52,12 +56,29 @@ export class CollieHub {
".git",
);
const hasAlreadyCloned = await this.git.isRepo(hubCacheGitDir);
let collieHubVersion = this.config.getProperty("colliehubVersion");

if (hasAlreadyCloned) {
await this.git.pull(hubCacheDir);
} else {
if (!hasAlreadyCloned) {
await this.git.clone(hubCacheDir, this.url);
}
if (!collieHubVersion) {
collieHubVersion = await this.git.getLatestTag(hubCacheDir);
await this.git.checkout(hubCacheDir, collieHubVersion);
this.config.setProperty("colliehubVersion", collieHubVersion!);
}
try {
const allTags = await this.git.getTags(hubCacheGitDir);
if (!allTags.includes(collieHubVersion)) {
throw new Error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d: this is strange. you throw an error here but directly catch it 3 lines later. In this case, if you dont need to stop something through multiple call-layers I suggest to just directly stop the execution in here by directly calling Deno.exit() instead of throwing an error.

`version tag does not exist, possible are: ${allTags.split("\n")}`,
);
}
} catch (error) {
this.logger.error(`${error}`);
Deno.exit(1);
}
//collie-hub version is set by the if block
await this.git.checkout(hubCacheDir, collieHubVersion!);

return hubCacheDir;
}
Expand Down
Loading