Skip to content

Commit

Permalink
fix: add prompt for existing documentation directory if renamed
Browse files Browse the repository at this point in the history
  • Loading branch information
kathikraemer committed Feb 19, 2024
1 parent 2d63bc2 commit d7b4c72
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 49 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
## :information_source: Table of contents

- [Deven Documentation Skeleton](#deven-documentation-skeleton)
- [:information\_source: Table of contents](#information_source-table-of-contents)
- [:information_source: Table of contents](#information_source-table-of-contents)
- [:star: Introduction](#star-introduction)
- [Goals](#goals)
- [:file\_folder: Documentation Structure](#file_folder-documentation-structure)
- [:file_folder: Documentation Structure](#file_folder-documentation-structure)
- [Requirements](#requirements)
- [Installation](#installation)
- [:rocket: How to use it](#rocket-how-to-use-it)
- [1. Install](#1-install)
- [2. Check](#2-check)
- [3. Update](#3-update)
- [:white\_check\_mark: How to test](#white_check_mark-how-to-test)
- [:white_check_mark: How to test](#white_check_mark-how-to-test)
- [:v: Contribute](#v-contribute)
- [:bug: Bugs and Issues](#bug-bugs-and-issues)
- [:page\_facing\_up: License](#page_facing_up-license)
- [:green\_heart: Code of conduct](#green_heart-code-of-conduct)
- [:page_facing_up: License](#page_facing_up-license)
- [:green_heart: Code of conduct](#green_heart-code-of-conduct)

# :star: Introduction

Expand Down
6 changes: 1 addition & 5 deletions src/__tests__/command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import * as fs from "fs-extra";
import { BaseCommand } from "../commands/command";
import mockFs from "mock-fs";
import {
mockProcessExit,
mockProcessStdout,
mockProcessStderr,
mockConsoleLog,
} from "jest-mock-process";

let mockExit: jest.SpyInstance;
let mockStdout: jest.SpyInstance;
let mockStderr: jest.SpyInstance;
let mockLog: jest.SpyInstance;
Expand All @@ -18,14 +16,12 @@ let command: BaseCommand;
describe("deven-cli", () => {
afterEach(() => {
mockFs.restore();
mockExit.mockRestore();
mockStdout.mockRestore();
mockStderr.mockRestore();
mockLog.mockRestore();
jest.clearAllMocks();
});
beforeEach(() => {
mockExit = mockProcessExit();
mockStdout = mockProcessStdout();
mockStderr = mockProcessStderr();
mockLog = mockConsoleLog();
Expand Down Expand Up @@ -61,7 +57,7 @@ describe("deven-cli", () => {
});
it("throws an error for docsPath if no documentation directory is set", async () => {
expect(() => command.docsPath).toThrowError(
"#documentationDirectory has not been set yet. Please ensure that it has been set before trying to access it."
"documentationDirectory has not been set yet. Please ensure that it has been set before trying to access it."
);
});
it("provides the right outdated doc path (<root>/doc)", async () => {
Expand Down
33 changes: 27 additions & 6 deletions src/__tests__/update.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Update } from "../commands";
import { logger } from "../Logger";
import mockFs from "mock-fs";
import {
mockProcessExit,
mockProcessStdout,
mockProcessStderr,
mockConsoleLog,
Expand All @@ -13,7 +12,6 @@ import { messages } from "../shared/messages";
import { ConfigFile } from "../interfaces";
import enquirer from "enquirer";

let mockExit: jest.SpyInstance;
let mockStdout: jest.SpyInstance;
let mockStderr: jest.SpyInstance;
let mockLog: jest.SpyInstance;
Expand All @@ -29,7 +27,6 @@ let update: Update;
describe("deven-cli", () => {
afterEach(() => {
mockFs.restore();
mockExit.mockRestore();
mockStdout.mockRestore();
mockStderr.mockRestore();
mockLog.mockRestore();
Expand All @@ -38,7 +35,6 @@ describe("deven-cli", () => {
jest.clearAllMocks();
});
beforeEach(() => {
mockExit = mockProcessExit();
mockStdout = mockProcessStdout();
mockStderr = mockProcessStderr();
mockLog = mockConsoleLog();
Expand Down Expand Up @@ -124,8 +120,33 @@ describe("deven-cli", () => {
});

describe("updateOutdatedDirectoryName", () => {
it("does nothing if no outdated directory exists", async () => {
await update.updateOutdatedDirectoryName();
it("does nothing if the documenation directory has been successfully read from the config", async () => {
update.documentationDirectory = "test";
const result = await update.updateOutdatedDirectoryName();
expect(result).toBeTruthy();
});
it("asks for the current documentation directory if none is in the config and no outdated doc directory exists", async () => {
const oldConfig = { ...mockConfig };
// @ts-expect-error -- purposefully testing bad data
delete oldConfig.documentationDirectory;
fs.writeFileSync(update.configFilePath, JSON.stringify(oldConfig));
enquirer.prompt = jest.fn().mockResolvedValue({ directory: "test" });
fs.mkdirSync("fake_test_folder/test");
const result = await update.updateOutdatedDirectoryName();
expect(result).toBeTruthy();
});
it("throws and error if the documentation directory provided that should be written to the config does not exist", async () => {
const oldConfig = { ...mockConfig };
// @ts-expect-error -- purposefully testing bad data
delete oldConfig.documentationDirectory;
fs.writeFileSync(update.configFilePath, JSON.stringify(oldConfig));
enquirer.prompt = jest.fn().mockResolvedValue({ directory: "test" });
const error = jest.spyOn(logger, "error");
const result = await update.updateOutdatedDirectoryName();
expect(error).toHaveBeenCalledWith(
messages.update.documentationDirectoryNotExists("test")
);
expect(result).toBeFalsy();
});
it("throws an error if no directory is provided", async () => {
const oldConfig = { ...mockConfig };
Expand Down
7 changes: 3 additions & 4 deletions src/commands/command.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as path from "path";
import * as fs from "fs-extra";
import { messages } from "../shared/messages";

export type BaseCliParams = {
basePath: string | undefined;
Expand Down Expand Up @@ -34,9 +35,7 @@ export class BaseCommand<CliParams extends BaseCliParams = BaseCliParams> {

get docsPath(): string {
if (this.documentationDirectory === null) {
throw new Error(
"#documentationDirectory has not been set yet. Please ensure that it has been set before trying to access it."
);
throw new Error(messages.error.documentationDirectoryNotSet);
}

return path.join(this.#basePath, this.documentationDirectory);
Expand Down Expand Up @@ -118,7 +117,7 @@ export class BaseCommand<CliParams extends BaseCliParams = BaseCliParams> {

async run(): Promise<void> {
if (!this.steps) {
throw new Error("Command subclass must specify steps");
throw new Error(messages.error.stepsNotSet);
}

for (const step of this.steps) {
Expand Down
72 changes: 43 additions & 29 deletions src/commands/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,44 +77,58 @@ export class Update extends BaseCommand {
}

public async updateOutdatedDirectoryName(): Promise<boolean> {
if (!this.existsOutdatedDocFolder()) {
if (this.documentationDirectory) {
return true;
}

if (this.documentationDirectory === null) {
const documentationDirectory: { directory: string } = await prompt({
type: "input",
initial: "docs",
name: "directory",
message: messages.update.useNewDocumentationDirectory,
});
const promptMessage = this.existsOutdatedDocFolder()
? messages.update.useNewDocumentationDirectory
: messages.update.provideExistingDocumenationDirectory;

if (
documentationDirectory === undefined ||
documentationDirectory.directory === ""
) {
logger.error(messages.update.noDocumentationDirectoryProvided);
const documentationDirectory: { directory: string } = await prompt({
type: "input",
initial: "docs",
name: "directory",
message: promptMessage,
});

if (
documentationDirectory === undefined ||
documentationDirectory.directory === ""
) {
logger.error(messages.update.noDocumentationDirectoryProvided);
return false;
}

this.documentationDirectory = documentationDirectory.directory;

if (!this.existsOutdatedDocFolder()) {
if (!this.existsDocsFolder()) {
logger.error(
messages.update.documentationDirectoryNotExists(
this.documentationDirectory
)
);
return false;
}
return true;
}

this.documentationDirectory = documentationDirectory.directory;

if (this.outdatedDocPath === this.docsPath) {
logger.info(messages.update.keepDocDirectory);
} else {
if (this.existsDocsFolder()) {
logger.error(
messages.update.documentationDirectoryExists(
this.documentationDirectory
)
);
return false;
}
fs.renameSync(this.outdatedDocPath, this.docsPath);
logger.info(
messages.update.renamedOutdatedDocFolder(this.documentationDirectory)
if (this.outdatedDocPath === this.docsPath) {
logger.info(messages.update.keepDocDirectory);
} else {
if (this.existsDocsFolder()) {
logger.error(
messages.update.documentationDirectoryExists(
this.documentationDirectory
)
);
return false;
}
fs.renameSync(this.outdatedDocPath, this.docsPath);
logger.info(
messages.update.renamedOutdatedDocFolder(this.documentationDirectory)
);
}

return true;
Expand Down
24 changes: 24 additions & 0 deletions src/shared/__tests__/messages.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ const stripAnsi = (s: string): string =>
);

describe("messages", () => {
it("error: documentationDirectoryNotSet", async () => {
expect(stripAnsi(messages.error.documentationDirectoryNotSet)).toBe(
"documentationDirectory has not been set yet. Please ensure that it has been set before trying to access it."
);
});
it("error: stepsNotSet", async () => {
expect(stripAnsi(messages.error.stepsNotSet)).toBe(
"Command subclass must specify steps"
);
});
it("selectDocumentationDirectory", async () => {
expect(messages.install.selectDocumentationDirectory).toContain(
"Please enter the name of the documentation directory that should be created."
Expand Down Expand Up @@ -148,6 +158,13 @@ describe("messages", () => {
"The config file hasn't been found."
);
});
it("provideExistingDocumenationDirectory", async () => {
expect(
stripAnsi(messages.update.provideExistingDocumenationDirectory)
).toContain(
`The name of the documentation directory is missing in the config file and it's not the directory the files where installed at initially ("doc").`
);
});
it("useNewDocumentationDirectory", async () => {
expect(stripAnsi(messages.update.useNewDocumentationDirectory)).toContain(
'The current documentation directory is "doc". The new suggestion for this directory is "docs", so GitHub can auto-detect files like the Code of Conduct, but you can also switch to any other directory.'
Expand All @@ -160,6 +177,13 @@ describe("messages", () => {
'Please, run the "update" command again and provide a name for the documentation directory.'
);
});
it("documentationDirectoryNotExists", async () => {
expect(
stripAnsi(messages.update.documentationDirectoryNotExists("test").message)
).toBe(
`The selected directory "test" doesn't exist. Please, run the "update" command again and provide the name of your current documentation directory.`
);
});
it("documentationDirectoryExists", async () => {
expect(
stripAnsi(messages.update.documentationDirectoryExists("test").message)
Expand Down
15 changes: 15 additions & 0 deletions src/shared/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ export type Message = {
};

export const messages = {
error: {
documentationDirectoryNotSet:
"documentationDirectory has not been set yet. Please ensure that it has been set before trying to access it.",
stepsNotSet: "Command subclass must specify steps",
},
install: {
selectDocumentationDirectory:
'Please enter the name of the documentation directory that should be created.\nIf the directory already exists, name clashes will have to be resolved manually.\nIf possible, the default of "docs" should be used, so GitHub can auto-detect files like the Code of Conduct.\nDocumentation directory:',
Expand Down Expand Up @@ -193,12 +198,22 @@ export const messages = {
},
useNewDocumentationDirectory:
'The current documentation directory is "doc". The new suggestion for this directory is "docs", so GitHub can auto-detect files like the Code of Conduct, but you can also switch to any other directory.\nIf the directory already exists, name clashes will have to be resolved manually.\nDocumentation directory:',
provideExistingDocumenationDirectory:
'The name of the documentation directory is missing in the config file and it\'s not the directory the files where installed at initially ("doc").\nPlease provide the name of the current documentation directory:',
noDocumentationDirectoryProvided: {
prefix: "[update]",
message: `Please, run the "update" command again and ${chalk.bold(
"provide a name for the documentation directory"
)}.`,
},
documentationDirectoryNotExists: (directory: string) => {
return {
prefix: "[update]",
message: `The selected directory "${directory}" doesn't exist. Please, run the "update" command again and ${chalk.bold(
"provide the name of your current documentation directory"
)}.`,
};
},
documentationDirectoryExists: (directory: string) => {
return {
prefix: "[update]",
Expand Down

0 comments on commit d7b4c72

Please sign in to comment.