Skip to content

Commit

Permalink
Merge pull request #82 from inrupt/feature/75_yaml-init
Browse files Browse the repository at this point in the history
Resolves #75 

Added a config file generation feature
  • Loading branch information
Zwifi authored Oct 18, 2019
2 parents a6d2948 + 6b48c5c commit fc78daf
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 140 deletions.
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
.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

0 comments on commit fc78daf

Please sign in to comment.