diff --git a/src/commands/foundation/docs.command.ts b/src/commands/foundation/docs.command.ts index 214fe7c..5f6134c 100644 --- a/src/commands/foundation/docs.command.ts +++ b/src/commands/foundation/docs.command.ts @@ -1,21 +1,14 @@ -import * as fs from "std/fs"; import { CliApiFacadeFactory } from "../../api/CliApiFacadeFactory.ts"; import { Logger } from "../../cli/Logger.ts"; import { ProgressReporter } from "../../cli/ProgressReporter.ts"; -import { ComplianceControlRepository } from "../../compliance/ComplianceControlRepository.ts"; -import { ComplianceDocumentationGenerator } from "../../docs/ComplianceDocumentationGenerator.ts"; -import { DocumentationGenerator } from "../../docs/DocumentationGenerator.ts"; import { DocumentationRepository } from "../../docs/DocumentationRepository.ts"; -import { KitModuleDocumentationGenerator } from "../../docs/KitModuleDocumentationGenerator.ts"; -import { PlatformDocumentationGenerator } from "../../docs/PlatformDocumentationGenerator.ts"; -import { KitDependencyAnalyzer } from "../../kit/KitDependencyAnalyzer.ts"; -import { KitModuleRepository } from "../../kit/KitModuleRepository.ts"; import { CollieRepository } from "../../model/CollieRepository.ts"; import { FoundationRepository } from "../../model/FoundationRepository.ts"; import { ModelValidator } from "../../model/schemas/ModelValidator.ts"; import { GlobalCommandOptions } from "../GlobalCommandOptions.ts"; import { TopLevelCommand } from "../TopLevelCommand.ts"; import { getCurrentWorkingFoundation } from "../../cli/commandOptionsConventions.ts"; +import { exists } from "std/fs"; interface DocsCommandOptions { update?: boolean; @@ -89,59 +82,34 @@ export function registerDocsCmd(program: TopLevelCommand) { } async function updateDocumentation( - repo: CollieRepository, + _repo: CollieRepository, foundation: FoundationRepository, logger: Logger, ) { + const docsModulePath = foundation.resolvePath("docs"); + + if (!await exists(docsModulePath)) { + logger.error( + `Foundation-level docs module at "${docsModulePath}" does not exist.`, + ); + logger.tip( + "Import a starter docs module using 'collie kit import docs' command.", + ); + return; + } + const foundationProgress = new ProgressReporter( "generating docs", `foundation "${foundation.name}"`, logger, ); - const validator = new ModelValidator(logger); - const modules = await KitModuleRepository.load(repo, validator, logger); - const controls = await ComplianceControlRepository.load( - repo, - validator, - logger, - ); - const moduleDocumentation = new KitModuleDocumentationGenerator( - repo, - modules, - controls, - logger, - ); - - const complianceDocumentation = new ComplianceDocumentationGenerator( - repo, - logger, - ); - - const analyzer = new KitDependencyAnalyzer(repo, modules, logger); - const factory = new CliApiFacadeFactory(logger); const terragrunt = factory.buildTerragrunt(); - const platformDocumentation = new PlatformDocumentationGenerator( - repo, - foundation, - analyzer, - controls, - terragrunt, - logger, - ); - const docsRepo = new DocumentationRepository(foundation); - - await prepareSiteTemplate(docsRepo, repo, logger); - - const generator = new DocumentationGenerator( - moduleDocumentation, - complianceDocumentation, - platformDocumentation, - ); - - await generator.generateFoundationDocumentation(docsRepo); + await terragrunt.run(docsModulePath, { raw: ["apply"] }, { + autoApprove: true, + }); foundationProgress.done(); } @@ -171,34 +139,3 @@ async function buildDocumentation( await npm.run(["install"], { cwd: dir }); await npm.run(["run", "docs:build"], { cwd: dir }); } - -async function prepareSiteTemplate( - docsRepo: DocumentationRepository, - repo: CollieRepository, - logger: Logger, -) { - // TODO: throw if it doesn't work - const srcDir = repo.resolvePath("kit", "foundation", "docs", "template"); - - try { - await fs.copy(srcDir, docsRepo.resolvePath(), { overwrite: true }); - } catch (e) { - if (e instanceof Deno.errors.NotFound) { - logger.error( - (fmt) => - `could not find kit module with template for documentation site at ${ - fmt.kitPath( - srcDir, - ) - }`, - ); - - logger.tipCommand( - "This module is essential for documentation generation. To import this module run", - "kit import foundation/docs", - ); - Deno.exit(1); - } - throw e; - } -} diff --git a/src/docs/DocumentationRepository.ts b/src/docs/DocumentationRepository.ts index 617e69a..b124f9e 100644 --- a/src/docs/DocumentationRepository.ts +++ b/src/docs/DocumentationRepository.ts @@ -7,7 +7,7 @@ export class DocumentationRepository { // we use a "hidden" directory with a leading "." because terragrunt excludes hidden files and dirs // when building a terragrunt-cache folder, see https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#terraform "include_in_copy" // > By default, Terragrunt excludes hidden files and folders during the copy step. - private readonly docsRootDir = ".docs"; + private readonly docsRootDir = ".docs-v2"; private readonly docsContentDir = "docs"; constructor(private readonly foundation: FoundationRepository) {} diff --git a/src/model/CollieHub.ts b/src/model/CollieHub.ts index a3badb1..1326454 100644 --- a/src/model/CollieHub.ts +++ b/src/model/CollieHub.ts @@ -3,6 +3,7 @@ import { GitCliFacade } from "/api/git/GitCliFacade.ts"; import { CollieRepository } from "/model/CollieRepository.ts"; import { CollieConfig } from "./CollieConfig.ts"; import { Logger } from "../cli/Logger.ts"; +import { rimraf } from "../path.ts"; export class CollieHub { constructor( @@ -82,6 +83,6 @@ export class CollieHub { public async cleanHubClone() { const hubCacheDir = this.repo.resolvePath(...this.hubCacheDirPath); - await Deno.remove(hubCacheDir, { recursive: true }); + await rimraf(hubCacheDir); } } diff --git a/src/path.ts b/src/path.ts index fe674f1..8b86631 100644 --- a/src/path.ts +++ b/src/path.ts @@ -10,3 +10,21 @@ import * as posix from "std/path/posix"; export function convertToPosixPath(relativePath: string) { return relativePath.split(path.SEPARATOR).join(posix.SEPARATOR); } + +/** + * Removes a dir, including all its contents. Does not throw if the dir does not exist. + * Equivalent to `rm -rf dir` + * + * @param dir the directory to remove + */ +export async function rimraf(dir: string) { + try { + await Deno.remove(dir, { recursive: true }); + } catch (error) { + if (error instanceof Deno.errors.NotFound) { + // ignore, dir is already removed + } else { + throw error; + } + } +}