Skip to content

Commit

Permalink
fix: add consistent use of path.join and refactor path names
Browse files Browse the repository at this point in the history
  • Loading branch information
kosmoz committed Mar 4, 2024
1 parent 1e3b76b commit 0cfbf0e
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 71 deletions.
7 changes: 4 additions & 3 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import oclifPrettierConfig from "@oclif/prettier-config";
import oclifPrettierConfig from '@oclif/prettier-config';

export default {
...oclifPrettierConfig,
semi: true
}
semi: true,
arrowParens: 'avoid',
};
2 changes: 1 addition & 1 deletion bin/dev.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env -S node --import tsx/esm
#!/usr/bin/env -S npx tsx

import {execute} from '@oclif/core';

Expand Down
44 changes: 24 additions & 20 deletions src/commands/index/index.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,56 @@
import {Command, Flags} from '@oclif/core';
import path from 'node:path';
import * as YAML from 'yaml';

import {getLatestManifest, getLatestVersion} from '../../manifest.js';
import {Paths, packagePaths} from '../../paths.js';
import {PackageRepoIndexItem} from '../../types/glasskube/index.js';
import {PackageIndex} from '../../types/types.js';
import {getFoldersIn, write} from '../../utils/io.js';
import {buildPath} from '../../utils/path.js';

export default class Index extends Command {
static override readonly aliases = ['update:index'];

static override readonly description = 'updates packages index';

static override readonly description = 'updates the packages index';
static override readonly examples = ['<%= config.bin %> <%= command.id %>'];

static override readonly flags = {
// flag with no value (-c, --create-version)
'dry-run': Flags.boolean({description: 'do not make any changes'}),
// flag to determine the base folder
source: Flags.string({char: 's', description: 'packages context'}),
source: Flags.string({char: 's', default: '.', description: 'packages context'}),
};

public async run(): Promise<void> {
private paths!: Paths;

protected override async init(): Promise<void> {
const {flags} = await this.parse(Index);
this.paths = packagePaths(path.join(flags.source, 'packages'));
}

const {source} = flags;
const packageFolders = await getFoldersIn(buildPath('packages', source));
public override async run(): Promise<void> {
const {flags} = await this.parse(Index);
const packageFolders = await getFoldersIn(this.paths.dirName());

const index = {
packages: await Promise.all(packageFolders.map((it) => this.createPackageIndexItem(it, source))),
} as PackageIndex;
const index: PackageIndex = {
packages: await Promise.all(packageFolders.map(it => this.createPackageIndexItem(it))),
};

if (!flags['dry-run']) {
this.log('will rewrite index');
await write(buildPath('index.yaml', source), YAML.stringify(index));
const indexPath = this.paths.indexYaml();
this.log('will rewrite index at', indexPath);
await write(indexPath, YAML.stringify(index));
this.log('index rewritten');
}
}

private async createPackageIndexItem(packageFolder: string, source?: string) {
const latestVersion = await getLatestVersion(packageFolder, source);
const packageManifest = await getLatestManifest(packageFolder, source);
private async createPackageIndexItem(packageFolder: string): Promise<PackageRepoIndexItem> {
const packagePaths = this.paths.package(packageFolder);
const latestVersion = await getLatestVersion(packagePaths);
const packageManifest = await getLatestManifest(packagePaths);
return {
name: packageFolder,
// eslint-disable-next-line perfectionist/sort-objects
iconUrl: packageManifest.iconUrl,
latestVersion: latestVersion.raw,
name: packageFolder,
shortDescription: packageManifest.shortDescription,
} as PackageRepoIndexItem;
};
}
}
43 changes: 23 additions & 20 deletions src/commands/package/index.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
import {Args, Command, Flags} from '@oclif/core';
import {Command, Flags} from '@oclif/core';
import path from 'node:path';
import {SemVer} from 'semver';

import {getArtifactPackage} from '../../datasources/artifacthub/index.js';
import {getLatestRelease} from '../../datasources/github-release/index.js';
import {createNewManifestVersion, getLatestManifest, getLatestVersion, updateHelmManifest} from '../../manifest.js';
import {Paths, packagePaths} from '../../paths.js';
import {PackageReference, PlainManifest} from '../../types/glasskube/package-manifest.js';
import {parseArtifactHubReferenceUrl, parseManifestUrl} from '../../utils/url-parser.js';

export default class Package extends Command {
static override readonly aliases = ['update:package'];

static override readonly args = {
package: Args.string({description: 'package to scout', required: true}),
};

static override readonly description = 'describe the command here';

static override readonly examples = ['<%= config.bin %> <%= command.id %>'];

static override readonly flags = {
// flag with no value (-c, --create-version)
'dry-run': Flags.boolean({description: 'do not make any changes'}),
// flag with no value (-f, --force)
force: Flags.boolean({char: 'f'}),
// flag with a value (-n, --name=VALUE)
name: Flags.string({char: 'n', description: 'name to print'}),
name: Flags.string({char: 'n', description: 'name to print', required: true}),
// flag to determine the base folder
source: Flags.string({char: 's', description: 'packages context'}),
source: Flags.string({char: 's', default: '.', description: 'packages context'}),
};

public async run(): Promise<void> {
const {args, flags} = await this.parse(Package);
private paths!: Paths;

const packageManifest = await getLatestManifest(args.package, flags.source);
protected override async init(): Promise<void> {
const {flags} = await this.parse(Package);
this.paths = packagePaths(path.join(flags.source, 'packages'));
}

const newPackageManifests = [];
public async run(): Promise<void> {
const {flags} = await this.parse(Package);
const packagePaths = this.paths.package(flags.name);
const packageManifest = await getLatestManifest(packagePaths);
const newPackageManifests: PlainManifest[] = [];

let newPackageManifestAvailable = false;
let newAppVersion = await getLatestVersion(args.package, flags.source);
let newAppVersion = await getLatestVersion(packagePaths);

for await (const plainManifest of packageManifest.manifests ?? []) {
const manifestUrl = parseManifestUrl(plainManifest.url);
Expand All @@ -56,20 +57,22 @@ export default class Package extends Command {
this.log(`new release on GitHub: ${latestRelease}`);
newPackageManifests.push({
url: manifestUrl.raw.replace(manifestUrl.semVer.raw, latestRelease.raw),
} as PlainManifest);
});
} else {
this.log('no newer manifest release found');
}
}

packageManifest.manifests = newPackageManifests;
if (newPackageManifests.length > 0) {
packageManifest.manifests = newPackageManifests;
}

if (packageManifest.helm) {
this.log(
`found Helm release of chart ${packageManifest.helm.chartName} with version ${packageManifest.helm.chartVersion}`,
);

const artifactHubUrl = this.findArtifactHubReference(packageManifest.references || []);
const artifactHubUrl = this.findArtifactHubReference(packageManifest.references ?? []);

if (artifactHubUrl) {
const artifactHub = parseArtifactHubReferenceUrl(artifactHubUrl.url);
Expand All @@ -89,12 +92,12 @@ export default class Package extends Command {

if (!flags['dry-run'] && (newPackageManifestAvailable || flags.force)) {
this.log('will create new version');
await createNewManifestVersion(packageManifest, newAppVersion, flags.source);
await createNewManifestVersion(packagePaths, packageManifest, newAppVersion);
this.log('latest version created');
}
}

private findArtifactHubReference(references: PackageReference[]): PackageReference | undefined {
return references.find((it) => it.label === 'ArtifactHub');
return references.find(it => it.label === 'ArtifactHub');
}
}
37 changes: 17 additions & 20 deletions src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,44 @@ import {SemVer} from 'semver';
import * as YAML from 'yaml';

import {getNextBuildNumber, getPackageVersions} from './package.js';
import {PackageIndexItem} from './types/glasskube/versions.js';
import {PackagePaths, PackageVersionPaths} from './paths.js';
import {ArtifactHubPackage, PackageManifest} from './types/types.js';
import {createDir, parseYaml, read, write} from './utils/io.js';

export async function createNewManifestVersion(
packagePaths: PackagePaths,
packageManifest: PackageManifest,
latestAppVersion: SemVer,
source?: string,
) {
const packageName = packageManifest.name;

const buildNumber = await getNextBuildNumber(latestAppVersion, packageName, source);
const buildNumber = await getNextBuildNumber(latestAppVersion, packagePaths);
const version = `v${latestAppVersion}+${buildNumber}`;
const latestVersionPath = `${source}packages/${packageName}/${version}`;
await writePackageManifestFile(latestVersionPath, packageManifest);
await updateVersionsFile(packageName, version, source);
await writePackageManifestFile(packagePaths.version(version), packageManifest);
await updateVersionsFile(packagePaths, version);
}

async function writePackageManifestFile(latestVersionPath: string, packageManifest: PackageManifest) {
await createDir(latestVersionPath);
async function writePackageManifestFile(paths: PackageVersionPaths, packageManifest: PackageManifest) {
await createDir(paths.dirName());
await write(
`${latestVersionPath}/package.yaml`,
paths.packageYaml(),
'# yaml-language-server: $schema=https://glasskube.dev/schemas/v1/package-manifest.json\n\n' +
YAML.stringify(packageManifest),
);
}

async function updateVersionsFile(packageName: string, version: string, source?: string) {
const packageVersions = await getPackageVersions(packageName, source);
packageVersions.versions.push({version} as PackageIndexItem);
await write(`${source}packages/${packageName}/versions.yaml`, YAML.stringify(packageVersions));
async function updateVersionsFile(paths: PackagePaths, version: string) {
const packageVersions = await getPackageVersions(paths);
packageVersions.versions.push({version});
await write(paths.versionsYaml(), YAML.stringify(packageVersions));
}

export async function getLatestVersion(name: string, source?: string) {
const packageVersions = await getPackageVersions(name, source);
export async function getLatestVersion(paths: PackagePaths) {
const packageVersions = await getPackageVersions(paths);
return new SemVer(packageVersions.latestVersion);
}

export async function getLatestManifest(name: string, source?: string) {
const latestVersion = await getLatestVersion(name, source);
const stringContent = await read(`${source}packages/${name}/${latestVersion.raw}/package.yaml`);
export async function getLatestManifest(paths: PackagePaths) {
const latestVersion = await getLatestVersion(paths);
const stringContent = await read(paths.version(latestVersion.raw).packageYaml());
return parseYaml<PackageManifest>(stringContent);
}

Expand Down
13 changes: 7 additions & 6 deletions src/package.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import {SemVer} from 'semver';

import {PackagePaths} from './paths.js';
import {PackageVersions} from './types/types.js';
import {parseYaml, read} from './utils/io.js';

export async function getPackageVersions(packageName: string, source?: string) {
const versionsContent = await read(`${source}packages/${packageName}/versions.yaml`);
export async function getPackageVersions(pkg: PackagePaths) {
const versionsContent = await read(pkg.versionsYaml());
return parseYaml<PackageVersions>(versionsContent);
}

export async function getBuildNumbers(version: SemVer, versions: PackageVersions) {
return versions.versions
.filter((it) => version.compare(it.version) === 0)
.map((it) => Number(new SemVer(it.version).build ?? 1));
.filter(it => version.compare(it.version) === 0)
.map(it => Number(new SemVer(it.version).build ?? 1));
}

export async function getNextBuildNumber(appVersion: SemVer, packageName: string, source?: string) {
const packageVersions = await getPackageVersions(packageName, source);
export async function getNextBuildNumber(appVersion: SemVer, pkg: PackagePaths) {
const packageVersions = await getPackageVersions(pkg);
return Math.max(0, ...(await getBuildNumbers(appVersion, packageVersions))) + 1;
}
28 changes: 28 additions & 0 deletions src/paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import path from 'node:path';

type StringSupplier = () => string;
type DirName = {readonly dirName: StringSupplier};
type IndexYaml = {readonly indexYaml: StringSupplier};
type VersionsYaml = {readonly versionsYaml: StringSupplier};
type ManifestYaml = {readonly packageYaml: StringSupplier};
export type PackageVersionPaths = DirName & ManifestYaml;
type WithPackageVersion = {readonly version: (version: string) => PackageVersionPaths};
export type PackagePaths = DirName & VersionsYaml & ManifestYaml & WithPackageVersion;
type WithPackage = {readonly package: (name: string) => PackagePaths};
export type Paths = DirName & IndexYaml & WithPackage;

export function packagePaths(base: string): Paths {
return {
dirName: () => base,
indexYaml: () => path.join(base, 'index.yaml'),
package: (name: string) => ({
dirName: () => path.join(base, name),
packageYaml: () => path.join(base, name, 'package.yaml'),
version: (version: string) => ({
dirName: () => path.join(base, name, version),
packageYaml: () => path.join(base, name, version, 'package.yaml'),
}),
versionsYaml: () => path.join(base, name, 'versions.yaml'),
}),
};
}
2 changes: 1 addition & 1 deletion src/utils/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export async function parseYaml<T>(yamlContent: string): Promise<T> {

export async function getFoldersIn(path: string): Promise<string[]> {
const allFiles = await fs.readdir(path, {withFileTypes: true});
return allFiles.filter((it) => it.isDirectory()).map((it) => it.name);
return allFiles.filter(it => it.isDirectory()).map(it => it.name);
}

0 comments on commit 0cfbf0e

Please sign in to comment.