Skip to content

Commit 0f6a3b2

Browse files
authored
DOP-3202: Persistence Module (#697)
* DOP-3202: Scaffold new module * lint * DOP-3202: Add upload w/ buildId logic * DOP-3202: Add basic error handling * fixup * various productionization changes * lint fixup * fixup * fixup * fixup * fixup * fixup * Incorporate feedback: Round 1 * lint * fixup * update readme, add try-catch, stronger typing * fixup * fixup * Update README.md * Derive created_at from objectID * update comments * rename entries -> pages
1 parent df71ce2 commit 0f6a3b2

19 files changed

+15544
-3
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
node_modules
22
build
3+
modules/**/build
4+
modules/**/dist
5+
modules/**/.env
36
npm-debug.log
47
.env
58
.DS_Store

jest.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module.exports = {
22
collectCoverage: true,
33
collectCoverageFrom: ['src/**/*.ts'],
4-
coveragePathIgnorePatterns: ['node_modules', 'tests', 'errors', 'app', 'app_test'],
5-
modulePathIgnorePatterns: ['<rootDir>/infrastructure/'],
4+
coveragePathIgnorePatterns: ['node_modules', 'modules', 'tests', 'errors', 'app', 'app_test'],
5+
modulePathIgnorePatterns: ['<rootDir>/infrastructure/', '<rootDir>/modules'],
66
coverageDirectory: '<rootDir>/coverage/',
77
verbose: false,
88
// coverageThreshold: {

modules/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Overview
2+
3+
This directory contains various build-time modules for use in makefiles or for use as published modules utilized in other CI/CD routines.

modules/persistence/.babelrc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-typescript"
5+
],
6+
"plugins": [
7+
"@babel/plugin-transform-runtime"
8+
]
9+
}

modules/persistence/.eslintrc.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
es6: true,
5+
},
6+
extends: 'plugin:@typescript-eslint/recommended',
7+
globals: {
8+
Atomics: 'readonly',
9+
SharedArrayBuffer: 'readonly',
10+
},
11+
parser: '@typescript-eslint/parser',
12+
parserOptions: {
13+
ecmaVersion: 2018,
14+
sourceType: 'module',
15+
},
16+
rules: {
17+
'no-console': 'off',
18+
},
19+
};

modules/persistence/.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v14.17.6

modules/persistence/README.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Snooty Transport Module
2+
3+
As part of integrating Snooty Parser with the unified Snooty toolchain, this module holds exclusive responsibility over transporting and persisting AST and metadata output artifacts from the parser into datastores.
4+
5+
Currently, this module supports persistence to Mongodb Atlas instances, and is also responsible for mutation of entries at persist time.
6+
7+
## Installation
8+
9+
By default, this module requires Node v14.17.6 and uses a `.nvmrc` file if using nvm.
10+
Running `npm ci` to install all dependencies is required for usage.
11+
12+
An example environment file is available at `sample.env`.
13+
Copy this file to `.env` in order to use a local environment file.
14+
15+
## Building and Running
16+
17+
### `npm run build`
18+
19+
Compiles the module using `tsc`. By default, compiles to the `./dist` directory.
20+
21+
### `npm run start`
22+
23+
Runs the contents of the `./dist` directory.
24+
Requires usage of `-- -path` argument, eg `npm run start -- --path ./build/artifacts.zip`.
25+
Recommended command for running this module in higher than local environments.
26+
Requires parser output artifacts to be present in specified directory and zip file at `--path` value specified.
27+
28+
### `npm run dev`
29+
30+
Cleans dist, compiles, and runs with arguments `-path ./build/artifacts.zip`.
31+
Requires parser output artifacts to be present in specified directory and zip file at `./build/artifacts.zip`.
32+
33+
## Available Arguments
34+
35+
This module utilizes [minimist](https://www.npmjs.com/package/minimist) for argument parsing.
36+
For more information on accepted argument formats, please consult [its documentation](https://www.npmjs.com/package/minimist).
37+
38+
### `-path`
39+
40+
| values | any string |
41+
| ------ | ---------- |
42+
43+
Required string formatted filepath where build artifacts are housed.
44+
45+
### `-strict`
46+
47+
| values | 'y', 'yes', 'true' |
48+
| ------ | ------------------ |
49+
50+
Optional string formatted argument for whether module should exit with non-zero status on failure.
51+
Highly recommended for use in production environments.
52+
53+
## Using/Developing This Module
54+
55+
Usage and development of this module requires specifying the following environment variables. Use of a `.env` file is supported, but only recommended for local development.
56+
57+
If adding a new environment variable, please update the `sample.env`. The `sample.env` should be considered the primary documentation for supported environment variables within this module.

modules/persistence/index.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as dotenv from 'dotenv';
2+
// dotenv.config() should be invoked immediately, before any other imports, to ensure config is present
3+
dotenv.config();
4+
5+
import AdmZip from 'adm-zip';
6+
import minimist from 'minimist';
7+
import * as mongodb from 'mongodb';
8+
import { insertPages } from './src/services/pages';
9+
import { insertMetadata } from './src/services/metadata';
10+
11+
interface ModuleArgs {
12+
path: string;
13+
strict: string;
14+
[props: string | number | symbol]: unknown;
15+
}
16+
17+
const missingPathMessage = 'No path specified in arguments - please specify a build directory at arg "path"';
18+
19+
// Callable via npm run start, with -- --path='' --strict=''
20+
// being accepted args
21+
// Also callable w/ default args via npm run dev
22+
// Load command line args into a parameterized argv
23+
const argv: ModuleArgs = minimist(process.argv.slice(2));
24+
25+
const app = async (path: string) => {
26+
try {
27+
if (!path) throw missingPathMessage;
28+
const zip = new AdmZip(path);
29+
// atomic buildId for all artifacts read by this module - fundamental assumption
30+
// that only one build will be used per run of this module.
31+
const buildId = new mongodb.ObjectId();
32+
await Promise.all([insertPages(buildId, zip), insertMetadata(buildId, zip)]);
33+
process.exit(0);
34+
} catch (error) {
35+
console.error(`Persistence Module encountered a terminal error: ${error}`);
36+
throw error;
37+
}
38+
};
39+
40+
try {
41+
console.log(argv);
42+
app(argv['path']);
43+
} catch (error) {
44+
console.log('caught in terminal handling');
45+
// only exit with non zero error code if running with strict mode on
46+
if (['y', 'yes', 'true'].includes(argv['strict'].toLowerCase())) {
47+
process.exit(1);
48+
} else {
49+
process.exit(0);
50+
}
51+
}

0 commit comments

Comments
 (0)