Skip to content

Commit

Permalink
preserve comments when updating config
Browse files Browse the repository at this point in the history
  • Loading branch information
karmaniverous committed Jul 17, 2024
1 parent 3bc5dee commit 0b3a2ac
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 21 deletions.
34 changes: 27 additions & 7 deletions src/configFile.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import fs from 'fs-extra';
import _ from 'lodash';
import { resolve } from 'path';
import yaml from 'yaml';
import { Document, parse, parseDocument, stringify, YAMLMap } from 'yaml';

import { Config, configSchema } from './Config';
import { type Config, configSchema } from './Config';
import { pkgDir } from './pkgDir';

const resolveConfigPath = async (path?: string) => {
Expand All @@ -15,7 +16,7 @@ const resolveConfigPath = async (path?: string) => {

if (await fs.exists(resolvedPath)) {
try {
const { configPath } = yaml.parse(
const { configPath } = parse(
await fs.readFile(resolvedPath, 'utf8'),
) as Partial<Config>;

Expand All @@ -34,14 +35,33 @@ const resolveConfigPath = async (path?: string) => {
return resolvedPath;
};

export const readConfigFile = async (path?: string) =>
const readConfigDoc = async (path?: string) =>
parseDocument(await fs.readFile(await resolveConfigPath(path), 'utf8'));

export const readConfig = async (path?: string) =>
configSchema.parse(
yaml.parse(await fs.readFile(await resolveConfigPath(path), 'utf8')),
parse(await fs.readFile(await resolveConfigPath(path), 'utf8')),
);

export const writeConfigFile = async (config: Config, path?: string) => {
export const writeConfig = async (config: Config, path?: string) => {
const doc = await readConfigDoc(path);

await fs.writeFile(
await resolveConfigPath(path),
yaml.stringify(config, { doubleQuotedAsJSON: true }),
stringify(updateYamlDoc(doc, config), { doubleQuotedAsJSON: true }),
);
};

function updateYamlDoc(doc: Document.Parsed, update: object | object[]) {
for (const key in update) {
const value = _.get(update, key) as object | object[];
if (_.isPlainObject(value)) {
if (!doc.has(key)) doc.set(key, new YAMLMap());
updateYamlDoc(doc.get(key) as Document.Parsed, value);
} else {
doc.set(key, value);
}
}

return doc;
}
4 changes: 2 additions & 2 deletions src/parseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Handlebars } from '@karmaniverous/handlebars';
import chalk from 'chalk';

import { type Config } from './Config';
import { readConfigFile } from './configFile';
import { readConfig } from './configFile';
import { type ConsoleParams } from './ConsoleParams';
import { getErrorMessage } from './getErrorMessage';

Expand All @@ -17,7 +17,7 @@ export const parseConfig = async ({
process.stdout.write(chalk.black.bold('Parsing config file...'));

// Load & parse config file.
config = await readConfigFile(configPath);
config = await readConfig(configPath);

// Recursively apply config to itself as a handlebars template.
let thisPass = JSON.stringify(config);
Expand Down
6 changes: 3 additions & 3 deletions src/updateConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import _ from 'lodash';
import { resolve } from 'path';

import { type Actionable, type Config } from './Config';
import { readConfigFile, writeConfigFile } from './configFile';
import { readConfig, writeConfig } from './configFile';
import { type ConsoleParams } from './ConsoleParams';
import { getErrorMessage } from './getErrorMessage';
import { pkgDir } from './pkgDir';
Expand Down Expand Up @@ -33,7 +33,7 @@ export const updateConfig = async ({
);

// Load & parse config file.
const config = await readConfigFile(configPath);
const config = await readConfig(configPath);

// Validate batch.
if (!config.batches?.[batch]) {
Expand Down Expand Up @@ -66,7 +66,7 @@ export const updateConfig = async ({
);

// Write updated config to file.
await writeConfigFile(config, configPath);
await writeConfig(config, configPath);

if (stdOut) process.stdout.write(chalk.black.bold(' Done!\n'));
} catch (error) {
Expand Down
20 changes: 11 additions & 9 deletions test/metastructure.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
# ******************* DO NOT EDIT THIS NOTICE *****************
# This legal notice is added to every supported source code
# file at every commit. See the README for more info!
# file at every commit. See the README for more info!
# *************************************************************
accounts:
dev:
id: "339712993254"
email: [email protected]
name: Development Account
organizational_unit: dev
id: '339712993254'
master:
id: "891377150698"
id: '891377150698'
email: [email protected]
name: Master Account
prod:
id: "381491905215"
id: '381491905215'
email: [email protected]
name: Production Account
organizational_unit: prod
test:
id: "381491918621"
id: '381491918621'
email: [email protected]
name: Testing Account
organizational_unit: test
shared_services:
id: "975050301644"
id: '975050301644'
email: [email protected]
name: Shared Services Account
organizational_unit: infrastructure
Expand Down Expand Up @@ -89,14 +89,16 @@ organizational_units:
name: Workloads OU
terraform:
aws_profile: KARMA-INIT
aws_version: ">= 5.56.1"
aws_version: '>= 5.56.1'
paths: test
roles:
admin: TerraformAdmin
deployment: TerraformDeployment
reader: TerraformReader
state_account: shared_services
state_bucket: "{{#if organization.namespace}}{{organization.namespace}}-{{/if}}terraform-state"
state_bucket: '{{#if
organization.namespace}}{{organization.namespace}}-{{/if}}terraform-state'
state_key: terraform.tfstate
state_lock_table: terraform-state-lock
terraform_version: ">= 1.9.0"
terraform_version: '>= 1.9.0'

0 comments on commit 0b3a2ac

Please sign in to comment.