Skip to content

Commit

Permalink
feat: added support for applying vocab and decorators to a model
Browse files Browse the repository at this point in the history
Signed-off-by: Muskan Bararia <[email protected]>
  • Loading branch information
Muskan Bararia committed Oct 19, 2023
1 parent 51989bc commit f98734a
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 1 deletion.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,22 @@ Options:
--output output directory path [string] [default: "./"]
```

### Concerto Decorate

The `decorate` command allows you to add decorators and vocabularies to your local CTO file from a set of local DCS and Vocab Command Set files

```
concerto decorate
apply the decorators and vocabs to the target models from given list of dcs files and vocab files
Options:
--model The CTO file
--voc The List of vocab files
--dcs The List of decorator command set files
--f output format (cto or json), default: cto
```

## License <a name="license"></a>
Accord Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file. Accord Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/.

41 changes: 41 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,47 @@ require('yargs')
Logger.error(err.message);
});
})
.command('decorate', 'apply the decorators and vocabs to the target models from given list of dcs files and vocab files', yargs => {
yargs.demandOption('model', 'Please provide a model');
yargs.option('model', {
describe: 'The file location of the source model',
type: 'string',
});
yargs.option('dcs', {
describe: 'List of dcs files to be applied to model',
type: 'string',
array:true
});
yargs.option('voc', {
describe: 'List of vocab files to be applied to model',
type: 'string',
array:true
});
yargs.option('f', {
describe: 'Output format (json or cto)',
type: 'string',
default:'cto',
choices: ['json', 'cto']
});
yargs.check((args) => {
// Custom validation to ensure at least one of the two options is provided
if (!args.dcs && !args.voc) {
throw new Error('You must provide at least one of dcs files or voc files');
}
return true;
});
}, argv => {
let options={};
options.format=argv.f;

return Commands.decorate(argv.model, argv.dcs,argv.voc,options)
.then(obj => {
console.log(obj);
})
.catch((err) => {
Logger.error(err.message);
});
})
.option('verbose', {
alias: 'v',
default: false
Expand Down
44 changes: 43 additions & 1 deletion lib/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const Concerto = require('@accordproject/concerto-core').Concerto;
const CodeGen = require('@accordproject/concerto-codegen').CodeGen;

const { Compare, compareResultToString } = require('@accordproject/concerto-analysis');
const { ModelFile, ModelManager } = require('@accordproject/concerto-core');
const { ModelFile, ModelManager,DecoratorManager } = require('@accordproject/concerto-core');
const { VocabularyManager } = require('@accordproject/concerto-vocabulary');

/**
* Utility class that implements the commands exposed by the CLI.
Expand Down Expand Up @@ -628,6 +629,47 @@ class Commands {
inferredConcertoJsonModel.models[0]
);
}

/**
* Decorate a given model with given list of dcs and vocab files and print the result
* @param {string} modelFile - the model to which vocab and decorator has to be applied
* @param {string[]} dcsFiles - the decorator files to be applied to model
* @param {string[]} vocFiles - the vocab files to be applied to model
* @param {object} options - optional parameters
* @returns {string} - Depending on the options, CTO string or JSON string
*/
static async decorate(modelFile, dcsFiles,vocFiles,options) {
try {
const modelContent = fs.readFileSync(path.resolve(modelFile), 'utf-8');
const allDCSFiles = dcsFiles ? dcsFiles.map(file => fs.readFileSync(file, 'utf8')) : [];
const allVocsFiles = vocFiles ? vocFiles.map(file => fs.readFileSync(file, 'utf8')) : [];
const modelManager = new ModelManager();
modelManager.addModel(modelContent);
let updatedModelManager = modelManager;
if (allDCSFiles.length > 0) {
allDCSFiles.forEach(content => {
updatedModelManager = DecoratorManager.decorateModels(updatedModelManager, JSON.parse(content));
});
}
if (allVocsFiles.length > 0) {
const vocManager = new VocabularyManager({ missingTermGenerator: VocabularyManager.englishMissingTermGenerator });
allVocsFiles.forEach(content => {
vocManager.addVocabulary(content);
});
const commandSet = vocManager.generateDecoratorCommands(updatedModelManager, 'en-gb');
updatedModelManager = DecoratorManager.decorateModels(updatedModelManager, commandSet);
}
const namespace = updatedModelManager.getModels().map(obj=>obj.name.replace(/\.cto$/, ''))[0];
let modelAst = updatedModelManager.getModelFile(namespace).getAst();
if (options.format === 'cto') {
return Printer.toCTO(modelAst);
} else {
return JSON.stringify(modelAst);
}
} catch (e) {
throw new Error(e);
}
}
}

module.exports = Commands;
61 changes: 61 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -682,4 +682,65 @@ describe('concerto-cli', () => {
expect(obj.fatherName.length >= 1).to.be.true;
});
});

describe('#decorate', () => {
it('should apply the list of decorators to model and output in cto by default', async () => {
const dir = await tmp.dir({ unsafeCleanup: true });
const model = (path.resolve(__dirname, 'models', 'decorate-model.cto'));
const decorators = [path.resolve(__dirname, 'data', 'decorate-dcs.json')];
const vocabs = undefined;
const options={
format:'cto'
};
const expected = fs.readFileSync(path.resolve(__dirname, 'models', 'decorate-model-expected-with-dcs.cto'),'utf-8');
const result =await Commands.decorate(model,decorators,vocabs,options);
result.replace(/[\r\n]+/g, '\n').should.equal(expected.replace(/[\r\n]+/g, '\n'));
dir.cleanup();
});

it('should apply the list of vocabs to the model and output in cto by default', async () => {
const dir = await tmp.dir({ unsafeCleanup: true });
const model = path.resolve(__dirname, 'models', 'decorate-model.cto');
const vocabs = [path.resolve(__dirname, 'data', 'decorate-voc')];
const decorators = undefined;
const options={
format:'cto'
};
const expected = fs.readFileSync(path.resolve(__dirname, 'models', 'decorate-model-expected-with-vocabs-only.cto'),'utf-8');
const result =await Commands.decorate(model,decorators,vocabs,options);
result.replace(/[\r\n]+/g, '\n').should.equal(expected.replace(/[\r\n]+/g, '\n'));
dir.cleanup();
});

it('should apply the list of vocabs and list of decorators to the model and output in asked format', async () => {
const dir = await tmp.dir({ unsafeCleanup: true });
const model = path.resolve(__dirname, 'models', 'decorate-model.cto');
const vocabs = [path.resolve(__dirname, 'data', 'decorate-voc')];
const decorators = [path.resolve(__dirname, 'data', 'decorate-dcs.json')];
const options={
format:'json'
};
const expected = fs.readFileSync(path.resolve(__dirname, 'models', 'decorate-model-expected-with-vocabs-and-deco.json'),'utf-8');
const result =await Commands.decorate(model,decorators,vocabs,options);
result.should.equal(expected);
dir.cleanup();
});
it('should throw error if data is invalid', async () => {
const dir = await tmp.dir({ unsafeCleanup: true });
const model = path.resolve(__dirname, 'models', 'decorate-invalid-model.cto');
const vocabs = [path.resolve(__dirname, 'data', 'decorate-voc')];
const decorators =undefined;
const options={
format:'json'
};
const expected = fs.readFileSync(path.resolve(__dirname, 'models', 'decorate-model-expected-with-vocabs-and-deco.json'),'utf-8');
try {
const result =await Commands.decorate(model,decorators,vocabs,options);
result.should.eql(expected);
} catch (err) {
(typeof err).should.equal('object');
}
dir.cleanup();
});
});
});

0 comments on commit f98734a

Please sign in to comment.