Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a config file generation feature #82

Merged
merged 6 commits into from
Oct 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ generated/

.idea/
*.iml

# VSCode
NSeydoux marked this conversation as resolved.
Show resolved Hide resolved
.vscode/
vscode_wspace.code-workspace
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ lit-artifact-generator --help

# How to run

1. To generate source code from a vocabulary or from a config YAML file:
```shell
node index.js --inputResources <ontology files>
node index.js generate --inputResources <ontology files>
```
2. To create an initial YAML file that should be edited manually
```shell
node index.js init
```

The output is a Node Module containing a Javascript file with constants defined for the RDF terms found in the vocabulary specified by the 'inputResources' flag. This module is located inside the **./generated** folder by default.
Expand Down
251 changes: 158 additions & 93 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,123 @@
require('mock-local-storage');

const logger = require('debug')('lit-artifact-generator:index');
const debug = require('debug');
const yargs = require('yargs');
const App = require('./src/App');

console.log(`Command: [${process.argv.join(' ')}]`);
const yargsConfig = yargs
.alias('i', 'inputResources')
.array('inputResources')
.describe(
'inputResources',
"One or more ontology resources (i.e. local RDF files, or HTTP URI's) used to generate source-code artifacts representing the contained vocabulary terms."
.command(
'generate',
'generate code artifacts from RDF',
yargs =>
yargs
.alias('i', 'inputResources')
.array('inputResources')
.describe(
'inputResources',
"One or more ontology resources (i.e. local RDF files, or HTTP URI's) used to generate source-code artifacts representing the contained vocabulary terms."
)

.alias('l', 'vocabListFile')
.describe(
'vocabListFile',
'Name of a YAML file providing a list of individual vocabs to bundle together into a single artifact (or potentially multiple artifacts for multiple programming languages).'
)

.alias('lv', 'litVocabTermVersion')
.describe('litVocabTermVersion', 'The version of the LIT Vocab Term to depend on.')
.default('litVocabTermVersion', '^0.1.0')

.alias('in', 'runNpmInstall')
.boolean('runNpmInstall')
.describe(
'runNpmInstall',
'If set will attempt to NPM install the generated artifact from within the output directory.'
)
.default('runNpmInstall', false)

.alias('p', 'runNpmPublish')
.boolean('runNpmPublish')
.describe('runNpmPublish', 'If set will attempt to publish to the configured NPM registry.')
.default('runNpmPublish', false)

.alias('b', 'bumpVersion')
.describe(
'bumpVersion',
'Bump up the semantic version of the artifact from the currently published version.'
)
.choices('bumpVersion', ['patch', 'minor', 'major'])

.alias('vtf', 'vocabTermsFrom')
.describe('vocabTermsFrom', 'Generates Vocab Terms from only the specified ontology file.')

.alias('av', 'artifactVersion')
.describe('artifactVersion', 'The version of the artifact(s) to be generated.')
.default('artifactVersion', '0.0.1')

.alias('at', 'artifactType')
.describe('artifactType', 'The artifact type that will be generated.')
.choices('artifactType', ['nodejs', 'java']) // Add to this when other languages are supported.
.default('artifactType', 'nodejs')

.alias('mnp', 'moduleNamePrefix')
.describe('moduleNamePrefix', 'A prefix for the name of the output module')
.default('moduleNamePrefix', '@lit/generated-vocab-')

.alias('nr', 'npmRegistry')
.describe('npmRegistry', 'The NPM Registry where artifacts will be published')
.default('npmRegistry', 'https://verdaccio.inrupt.com')

.alias('w', 'runWidoco')
.boolean('runWidoco')
.describe(
'runWidoco',
'If set will run Widoco to generate documentation for this vocabulary.'
)

.alias('s', 'supportBundling')
.boolean('supportBundling')
.describe(
'supportBundling',
'If set will use bundling support within generated artifact (currently supports Webpack only).'
)
.default('supportBundling', true)
// Can't provide an explicit version, and then also request a version bump!
.conflicts('artifactVersion', 'bumpVersion')

// Must provide either an input vocab file, or a file containing a list of vocab files (but how can we demand at
// least one of these two...?)
.conflicts('inputResources', 'vocabListFile')
.strict(),
argv => {
if (!argv.inputResources && !argv.vocabListFile) {
// this.yargsConfig.showHelp();
logger(argv.help);
debug.enable('lit-artifact-generator:*');
throw new Error(
"You must provide input, either a single vocabulary using '--inputResources' (e.g. a local RDF file, or a URL that resolves to an RDF vocabulary), or a YAML file using '--vocabListFile' listing multiple vocabularies."
);
}
runGeneration(argv);
}
)

.alias('l', 'vocabListFile')
.describe(
'vocabListFile',
'Name of a YAML file providing a list of individual vocabs to bundle together into a single artifact (or potentially multiple artifacts for multiple programming languages).'
)

.alias('lv', 'litVocabTermVersion')
.describe('litVocabTermVersion', 'The version of the LIT Vocab Term to depend on.')
.default('litVocabTermVersion', '^0.1.0')

.alias('o', 'outputDirectory')
.describe('outputDirectory', 'The output directory for the generated artifacts.')
.default('outputDirectory', './generated')

.alias('in', 'runNpmInstall')
.boolean('runNpmInstall')
.describe(
'runNpmInstall',
'If set will attempt to NPM install the generated artifact from within the output directory.'
.command(
'init',
'initializes a config file used for generation',
yargs => yargs,
argv => {
runInitialization(argv);
}
)
.default('runNpmInstall', false)

.alias('p', 'runNpmPublish')
.boolean('runNpmPublish')
.describe('runNpmPublish', 'If set will attempt to publish to the configured NPM registry.')
.default('runNpmPublish', false)

.alias('b', 'bumpVersion')
// The following options are shared between the different commands
.alias('q', 'quiet')
.boolean('quiet')
.describe(
'bumpVersion',
'Bump up the semantic version of the artifact from the currently published version.'
'quiet',
`If set will not display logging output to console (but you can still use DEBUG environment variable, set to 'lit-artifact-generator:*').`
)
.choices('bumpVersion', ['patch', 'minor', 'major'])
.default('quiet', false)

.alias('np', 'noprompt')
.boolean('noprompt')
Expand All @@ -62,61 +134,54 @@ const yargsConfig = yargs
)
.default('noprompt', false)

.alias('q', 'quiet')
.boolean('quiet')
.describe(
'quiet',
`If set will not display logging output to console (but you can still use DEBUG environment variable, set to 'lit-artifact-generator:*').`
)
.default('quiet', false)

.alias('vtf', 'vocabTermsFrom')
.describe('vocabTermsFrom', 'Generates Vocab Terms from only the specified ontology file.')

.alias('av', 'artifactVersion')
.describe('artifactVersion', 'The version of the artifact(s) to be generated.')
.default('artifactVersion', '0.0.1')

.alias('at', 'artifactType')
.describe('artifactType', 'The artifact type that will be generated.')
.choices('artifactType', ['nodejs', 'java']) // Add to this when other languages are supported.
.default('artifactType', 'nodejs')

.alias('mnp', 'moduleNamePrefix')
.describe('moduleNamePrefix', 'A prefix for the name of the output module')
.default('moduleNamePrefix', '@lit/generated-vocab-')

.alias('nr', 'npmRegistry')
.describe('npmRegistry', 'The NPM Registry where artifacts will be published')
.default('npmRegistry', 'https://verdaccio.inrupt.com')

.alias('w', 'runWidoco')
.boolean('runWidoco')
.describe('runWidoco', 'If set will run Widoco to generate documentation for this vocabulary.')
.alias('o', 'outputDirectory')
.describe('outputDirectory', 'The output directory for the generated artifacts.')
.default('outputDirectory', './generated')

.alias('s', 'supportBundling')
.boolean('supportBundling')
.describe(
'supportBundling',
'If set will use bundling support within generated artifact (currently supports Webpack only).'
)
.default('supportBundling', true)

// Can't provide an explicit version, and then also request a version bump!
.conflicts('artifactVersion', 'bumpVersion')

// Must provide either an input vocab file, or a file containing a list of vocab files (but how can we demand at
// least one of these two...?)
.conflicts('inputResources', 'vocabListFile')
.strict();

new App(yargsConfig)
.run()
.then(data => {
logger(`\nGeneration process successful to directory [${data.outputDirectory}]!`);
process.exit(0);
})
.catch(error => {
logger(`Generation process failed: [${error}]`);
process.exit(-1);
});
.help().argv;

function configureLog(argv) {
// Unless specifically told to be quiet (i.e. no logging output, although that
// will still be overridden by the DEBUG environment variable!), then
// determine if any generator-specific namespaces have been enabled. If they
// haven't been, then turn them all on,
if (!argv.quiet) {
// Retrieve all currently enabled debug namespaces (and then restore them!).
const namespaces = debug.disable();
debug.enable(namespaces);

// Unless our generator's debug logging has been explicitly configured, turn
// all debugging on.
if (namespaces.indexOf('lit-artifact-generator') === -1) {
debug.enable('lit-artifact-generator:*');
}
}
}

function runGeneration(argv) {
configureLog(argv);
new App(argv)
.run()
.then(data => {
logger(`\nGeneration process successful to directory [${data.outputDirectory}]!`);
process.exit(0);
})
.catch(error => {
logger(`Generation process failed: [${error}]`);
process.exit(-1);
});
}

function runInitialization(argv) {
configureLog(argv);
new App(argv)
.init()
.then(data => {
logger(`\nSuccessfully initialized config file [${data}]`);
process.exit(0);
})
.catch(error => {
logger(`Generation process failed: [${error}]`);
process.exit(-1);
});
}
60 changes: 29 additions & 31 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,29 @@
const debug = require('debug');
const path = require('path');
const moment = require('moment');

const ArtifactGenerator = require('./generator/ArtifactGenerator');
const CommandLine = require('./CommandLine');
const FileGenerator = require('./generator/FileGenerator');
const packageDotJson = require('../package.json');

const DEFAULT_CONFIG_TEMPLATE_PATH = '../../templates/initial-config.hbs';
const DEFAULT_CONFIG_NAME = 'lit-vocab.yml';

module.exports = class App {
constructor(yargsConfig) {
if (!yargsConfig) {
constructor(argv) {
if (!argv) {
throw new Error('Application must be initialised with a configuration - none was provided.');
}

this.yargsConfig = yargsConfig;
this.argv = argv;

// Extend the received arguments with contextual data
this.argv.generatedTimestamp = moment().format('LLLL');
this.argv.generatorName = packageDotJson.name;
this.argv.generatorVersion = packageDotJson.version;
}

async run() {
// Process the YARGS config data...
this.argv = this.yargsConfig.argv;

if (!this.argv.inputResources && !this.argv.vocabListFile) {
this.yargsConfig.showHelp();
debug.enable('lit-artifact-generator:*');
throw new Error(
"You must provide input, either a single vocabulary using '--inputResources' (e.g. a local RDF file, or a URL that resolves to an RDF vocabulary), or a YAML file using '--vocabListFile' listing multiple vocabularies."
);
}

// Unless specifically told to be quiet (i.e. no logging output, although that
// will still be overridden by the DEBUG environment variable!), then
// determine if any generator-specific namespaces have been enabled. If they
// haven't been, then turn them all on,
if (!this.argv.quiet) {
// Retrieve all currently enabled debug namespaces (and then restore them!).
const namespaces = debug.disable();
debug.enable(namespaces);

// Unless our generator's debug logging has been explicitly configured, turn
// all debugging on.
if (namespaces.indexOf('lit-artifact-generator') === -1) {
debug.enable('lit-artifact-generator:*');
}
}

const artifactGenerator = new ArtifactGenerator(this.argv, CommandLine.askForArtifactInfo);

return artifactGenerator
Expand All @@ -48,4 +33,17 @@ module.exports = class App {
.then(CommandLine.askForArtifactToBeNpmPublished)
.then(CommandLine.askForArtifactToBeDocumented);
}

async init() {
return new Promise(resolve => {
const targetPath = path.join(this.argv.outputDirectory, DEFAULT_CONFIG_NAME);

FileGenerator.createDirectory(this.argv.outputDirectory);
// This method is synchronous, so the wrapping promise just provices uniformity
// with the other methods of the class

FileGenerator.createFileFromTemplate(DEFAULT_CONFIG_TEMPLATE_PATH, this.argv, targetPath);
resolve(targetPath);
});
}
};
Loading