From eb6efcbb54b332ef75259d80246d7bebc0a716d5 Mon Sep 17 00:00:00 2001 From: Jerome Simeon Date: Fri, 4 Oct 2019 14:40:32 -0400 Subject: [PATCH] feature(logger) Proper logger support and error reporting in CLI Signed-off-by: Jerome Simeon --- package-lock.json | 653 +++++++++++++++++- packages/concerto-cli/index.js | 18 +- .../concerto-cli/test/models/parseerror.cto | 221 ++++++ .../concerto-cli/test/models/typenotfound.cto | 221 ++++++ packages/concerto-core/index.js | 1 + .../lib/codegen/fromjs/plantumlgenerator.js | 13 +- packages/concerto-core/lib/codegen/parsejs.js | 7 +- packages/concerto-core/lib/logger.js | 130 ++++ packages/concerto-core/lib/tools/changelog.js | 3 +- .../lib/tools/plantumltoimage.js | 2 - .../concerto-core/lib/tools/versionchecker.js | 3 +- packages/concerto-core/package.json | 6 +- .../concerto-core/scripts/api-changelog.js | 3 +- packages/concerto-core/test/logger.js | 124 ++++ .../test/models/animaltracking.js | 5 +- 15 files changed, 1378 insertions(+), 32 deletions(-) create mode 100644 packages/concerto-cli/test/models/parseerror.cto create mode 100644 packages/concerto-cli/test/models/typenotfound.cto create mode 100644 packages/concerto-core/lib/logger.js create mode 100644 packages/concerto-core/test/logger.js diff --git a/package-lock.json b/package-lock.json index 21515c5b75..9e03bf348c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3483,6 +3483,15 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3496,11 +3505,33 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } }, "columnify": { "version": "1.5.4", @@ -3817,6 +3848,20 @@ } } }, + "coveralls": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.4.tgz", + "integrity": "sha512-eyqUWA/7RT0JagiL0tThVhjbIjoiEUyWCjtUJoOPcWoeofP5WK/jb2OJYoBFrR6DvplR+AxOyuBqk4JHkk5ykA==", + "dev": true, + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.86.0" + } + }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", @@ -4124,6 +4169,16 @@ "wrappy": "1" } }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "requires": { + "colorspace": "1.1.x", + "enabled": "1.0.x", + "kuler": "1.0.x" + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -4227,6 +4282,14 @@ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "requires": { + "env-variable": "0.0.x" + } + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", @@ -4260,6 +4323,11 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, + "env-variable": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", + "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" + }, "err-code": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", @@ -4822,6 +4890,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", @@ -4997,6 +5075,12 @@ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", @@ -6907,6 +6991,238 @@ } } }, + "istanbul-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-merge/-/istanbul-merge-1.1.1.tgz", + "integrity": "sha1-db5kNDbU3nI+A6lNHKX1+ZSwvXI=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "glob": "^7.0.5", + "istanbul-lib-coverage": "^1.0.0", + "mkdirp": "^0.5.1", + "yargs": "^4.8.1" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + } + } + }, "istanbul-reports": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", @@ -6986,6 +7302,208 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" }, + "jsome": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/jsome/-/jsome-2.5.0.tgz", + "integrity": "sha1-XkF+70NB/+uD7ov6kmWzbVb+Se0=", + "requires": { + "chalk": "^2.3.0", + "json-stringify-safe": "^5.0.1", + "yargs": "^11.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -7011,8 +7529,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { "version": "1.0.1", @@ -7066,6 +7583,14 @@ "graceful-fs": "^4.1.9" } }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "requires": { + "colornames": "^1.1.1" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -7074,6 +7599,12 @@ "invert-kv": "^2.0.0" } }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, "lerna": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.15.0.tgz", @@ -7246,6 +7777,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -7307,6 +7844,12 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -7343,6 +7886,25 @@ } } }, + "logform": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "lolex": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", @@ -8434,6 +8996,11 @@ "wrappy": "1" } }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", @@ -8998,8 +9565,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.4.0", @@ -9611,6 +10177,21 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sinon": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz", @@ -9975,6 +10556,11 @@ "figgy-pudding": "^3.5.1" } }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -10316,6 +10902,11 @@ "integrity": "sha512-F91ZqLgvi1E0PdvmxMgp+gcf6q8fMH7mhdwWfzXnl1k+GbpQDmi8l7DzLC5JTASKbwpY3TfxajAUzAXcv2NmsQ==", "dev": true }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10453,6 +11044,11 @@ "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -10917,6 +11513,51 @@ "execa": "^1.0.0" } }, + "winston": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "requires": { + "async": "^2.6.1", + "diagnostics": "^1.1.1", + "is-stream": "^1.1.0", + "logform": "^2.1.1", + "one-time": "0.0.4", + "readable-stream": "^3.1.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.3.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "requires": { + "readable-stream": "^2.3.6", + "triple-beam": "^1.2.0" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/packages/concerto-cli/index.js b/packages/concerto-cli/index.js index 6a4a4fe5cc..b6701ec95e 100755 --- a/packages/concerto-cli/index.js +++ b/packages/concerto-cli/index.js @@ -15,7 +15,7 @@ 'use strict'; - +const Logger = require('@accordproject/concerto-core').Logger; const Commands = require('./lib/commands'); require('yargs') @@ -35,15 +35,15 @@ require('yargs') }); }, (argv) => { if (argv.verbose) { - console.log(`validate sample in ${argv.format} against the models ${argv.ctoFiles}`); + Logger.info(`validate sample in ${argv.format} against the models ${argv.ctoFiles}`); } return Commands.validate(argv.sample, argv.ctoFiles) .then((result) => { - console.log(result); + Logger.info(result); }) .catch((err) => { - console.log(err.message + ' ' + err); + Logger.error(err.message); }); }) .command('generate', 'generate code from model files', (yargs) => { @@ -65,15 +65,15 @@ require('yargs') }); }, (argv) => { if (argv.verbose) { - console.log(`generate code in format ${argv.format} from the models ${argv.ctoFiles} into directory ${argv.outputDirectory}`); + Logger.info(`generate code in format ${argv.format} from the models ${argv.ctoFiles} into directory ${argv.outputDirectory}`); } return Commands.generate(argv.format, argv.ctoFiles, argv.outputDirectory) .then((result) => { - console.log(result); + Logger.info(result); }) .catch((err) => { - console.log(err.message + ' ' + err); + Logger.error(err.message); }); }) .command('get', 'save local copies of external model dependencies', (yargs) => { @@ -90,12 +90,12 @@ require('yargs') }); }, (argv) => { if (argv.verbose) { - console.log(`Saving external models from ${argv.ctoFiles} into directory: ${argv.outputDirectory}`); + Logger.info(`Saving external models from ${argv.ctoFiles} into directory: ${argv.outputDirectory}`); } return Commands.getExternalModels(argv.ctoFiles, argv.outputDirectory) .catch((err) => { - console.log(err.message + ' ' + err); + Logger.error(err.message); }); }) .option('verbose', { diff --git a/packages/concerto-cli/test/models/parseerror.cto b/packages/concerto-cli/test/models/parseerror.cto new file mode 100644 index 0000000000..2a5255f382 --- /dev/null +++ b/packages/concerto-cli/test/models/parseerror.cto @@ -0,0 +1,221 @@ +namespace org.accordproject.money + +/** + * Represents an amount of Cryptocurrency + */ +concept CryptoMonetaryAmount { + o Double doubleValue + o CryptoCurrencyCode cryptoCurrencyCode +//} Error here + +/** + * Cyptocurrency codes. From https://en.wikipedia.org/wiki/List_of_cryptocurrencies + */ +enum CryptoCurrencyCode { + o ADA + o BCH + o BTC + o DASH + o EOS + o ETC + o ETH + o LTC + o NEO + o XLM + o XMR + o XRP + o ZEC +} + +/** + * Represents an amount of money + */ +concept MonetaryAmount { + o Double doubleValue // convert to fixed-point? + o CurrencyCode currencyCode +} + +/** + * ISO 4217 codes. From https://en.wikipedia.org/wiki/ISO_4217 + * https://www.currency-iso.org/en/home/tables/table-a1.html + */ +enum CurrencyCode { +o AED +o AFN +o ALL +o AMD +o ANG +o AOA +o ARS +o AUD +o AWG +o AZN +o BAM +o BBD +o BDT +o BGN +o BHD +o BIF +o BMD +o BND +o BOB +o BOV +o BRL +o BSD +o BTN +o BWP +o BYN +o BZD +o CAD +o CDF +o CHE +o CHF +o CHW +o CLF +o CLP +o CNY +o COP +o COU +o CRC +o CUC +o CUP +o CVE +o CZK +o DJF +o DKK +o DOP +o DZD +o EGP +o ERN +o ETB +o EUR +o FJD +o FKP +o GBP +o GEL +o GHS +o GIP +o GMD +o GNF +o GTQ +o GYD +o HKD +o HNL +o HRK +o HTG +o HUF +o IDR +o ILS +o INR +o IQD +o IRR +o ISK +o JMD +o JOD +o JPY +o KES +o KGS +o KHR +o KMF +o KPW +o KRW +o KWD +o KYD +o KZT +o LAK +o LBP +o LKR +o LRD +o LSL +o LYD +o MAD +o MDL +o MGA +o MKD +o MMK +o MNT +o MOP +o MRU +o MUR +o MVR +o MWK +o MXN +o MXV +o MYR +o MZN +o NAD +o NGN +o NIO +o NOK +o NPR +o NZD +o OMR +o PAB +o PEN +o PGK +o PHP +o PKR +o PLN +o PYG +o QAR +o RON +o RSD +o RUB +o RWF +o SAR +o SBD +o SCR +o SDG +o SEK +o SGD +o SHP +o SLL +o SOS +o SRD +o SSP +o STN +o SVC +o SYP +o SZL +o THB +o TJS +o TMT +o TND +o TOP +o TRY +o TTD +o TWD +o TZS +o UAH +o UGX +o USD +o USN +o UYI +o UYU +o UZS +o VEF +o VND +o VUV +o WST +o XAF +o XAG +o XAU +o XBA +o XBB +o XBC +o XBD +o XCD +o XDR +o XOF +o XPD +o XPF +o XPT +o XSU +o XTS +o XUA +o XXX +o YER +o ZAR +o ZMW +o ZWL +} diff --git a/packages/concerto-cli/test/models/typenotfound.cto b/packages/concerto-cli/test/models/typenotfound.cto new file mode 100644 index 0000000000..65a1c7d502 --- /dev/null +++ b/packages/concerto-cli/test/models/typenotfound.cto @@ -0,0 +1,221 @@ +namespace org.accordproject.money + +/** + * Represents an amount of Cryptocurrency + */ +concept CryptoMonetaryAmount { + o BUBBLE doubleValue // Error here + o CryptoCurrencyCode cryptoCurrencyCode +} + +/** + * Cyptocurrency codes. From https://en.wikipedia.org/wiki/List_of_cryptocurrencies + */ +enum CryptoCurrencyCode { + o ADA + o BCH + o BTC + o DASH + o EOS + o ETC + o ETH + o LTC + o NEO + o XLM + o XMR + o XRP + o ZEC +} + +/** + * Represents an amount of money + */ +concept MonetaryAmount { + o Double doubleValue // convert to fixed-point? + o CurrencyCode currencyCode +} + +/** + * ISO 4217 codes. From https://en.wikipedia.org/wiki/ISO_4217 + * https://www.currency-iso.org/en/home/tables/table-a1.html + */ +enum CurrencyCode { +o AED +o AFN +o ALL +o AMD +o ANG +o AOA +o ARS +o AUD +o AWG +o AZN +o BAM +o BBD +o BDT +o BGN +o BHD +o BIF +o BMD +o BND +o BOB +o BOV +o BRL +o BSD +o BTN +o BWP +o BYN +o BZD +o CAD +o CDF +o CHE +o CHF +o CHW +o CLF +o CLP +o CNY +o COP +o COU +o CRC +o CUC +o CUP +o CVE +o CZK +o DJF +o DKK +o DOP +o DZD +o EGP +o ERN +o ETB +o EUR +o FJD +o FKP +o GBP +o GEL +o GHS +o GIP +o GMD +o GNF +o GTQ +o GYD +o HKD +o HNL +o HRK +o HTG +o HUF +o IDR +o ILS +o INR +o IQD +o IRR +o ISK +o JMD +o JOD +o JPY +o KES +o KGS +o KHR +o KMF +o KPW +o KRW +o KWD +o KYD +o KZT +o LAK +o LBP +o LKR +o LRD +o LSL +o LYD +o MAD +o MDL +o MGA +o MKD +o MMK +o MNT +o MOP +o MRU +o MUR +o MVR +o MWK +o MXN +o MXV +o MYR +o MZN +o NAD +o NGN +o NIO +o NOK +o NPR +o NZD +o OMR +o PAB +o PEN +o PGK +o PHP +o PKR +o PLN +o PYG +o QAR +o RON +o RSD +o RUB +o RWF +o SAR +o SBD +o SCR +o SDG +o SEK +o SGD +o SHP +o SLL +o SOS +o SRD +o SSP +o STN +o SVC +o SYP +o SZL +o THB +o TJS +o TMT +o TND +o TOP +o TRY +o TTD +o TWD +o TZS +o UAH +o UGX +o USD +o USN +o UYI +o UYU +o UZS +o VEF +o VND +o VUV +o WST +o XAF +o XAG +o XAU +o XBA +o XBB +o XBC +o XBD +o XCD +o XDR +o XOF +o XPD +o XPF +o XPT +o XSU +o XTS +o XUA +o XXX +o YER +o ZAR +o ZMW +o ZWL +} diff --git a/packages/concerto-core/index.js b/packages/concerto-core/index.js index 1a74f678aa..b4c2b26ae3 100644 --- a/packages/concerto-core/index.js +++ b/packages/concerto-core/index.js @@ -36,6 +36,7 @@ module.exports.FileWriter = require('./lib/codegen/filewriter'); module.exports.Factory = require('./lib/factory'); module.exports.Globalize = require('./lib/globalize'); module.exports.Introspector = require('./lib/introspect/introspector'); +module.exports.Logger = require('./lib/logger'); module.exports.ModelFile = require('./lib/introspect/modelfile'); module.exports.ModelManager = require('./lib/modelmanager'); module.exports.DefaultModelFileLoader = require('./lib/introspect/loaders/defaultmodelfileloader'); diff --git a/packages/concerto-core/lib/codegen/fromjs/plantumlgenerator.js b/packages/concerto-core/lib/codegen/fromjs/plantumlgenerator.js index ee4e690ffe..190deeaa1f 100644 --- a/packages/concerto-core/lib/codegen/fromjs/plantumlgenerator.js +++ b/packages/concerto-core/lib/codegen/fromjs/plantumlgenerator.js @@ -16,6 +16,7 @@ const fs = require('fs'); const path = require('path'); +const Logger = require('../../logger'); const FileWriter = require('../filewriter'); /** @@ -39,11 +40,11 @@ class PlantUMLGenerator { if (classes.length > 0) { let fileWriter = new FileWriter(program.outputDir); const umlFilename = this.toUMLFilename(program.inputDir, program.outputDir, file); - console.log('open file: ' + umlFilename); + Logger.info('open file: ' + umlFilename); fileWriter.openFile(umlFilename); fileWriter.writeLine(0, '@startuml'); - console.log('+'); + Logger.info('+'); fileWriter.writeLine(0, '!include ' + program.outputDir + '/../../jsdoc-template/umlstyle.uml'); for (let n = 0; n < includes.length; n++) { // only include files that exist @@ -102,12 +103,12 @@ class PlantUMLGenerator { * @private */ toUMLFilename(inputDir, outputDir, filename) { - console.log('inputDir' + inputDir); - console.log('outputDir' + outputDir); - console.log('filename' + filename); + Logger.info('inputDir' + inputDir); + Logger.info('outputDir' + outputDir); + Logger.info('filename' + filename); let index = filename.indexOf(inputDir); - console.log('index ' + index); + Logger.info('index ' + index); let rest = filename.substr(index + 1 + inputDir.length); // let out = outputDir + '/' + rest; let i = rest.lastIndexOf('.'); diff --git a/packages/concerto-core/lib/codegen/parsejs.js b/packages/concerto-core/lib/codegen/parsejs.js index 54a0cfc0ed..ba7946705a 100644 --- a/packages/concerto-core/lib/codegen/parsejs.js +++ b/packages/concerto-core/lib/codegen/parsejs.js @@ -18,6 +18,7 @@ const fs = require('fs-extra'); const klaw = require('klaw'); const path = require('path'); const program = require('commander'); +const Logger = require('../logger'); const PlantUMLGenerator = require('./fromjs/plantumlgenerator'); const APISignatureGenerator = require('./fromjs/apisignaturegenerator'); const JavaScriptParser = require('./javascriptparser'); @@ -100,11 +101,11 @@ case 'JSON': if (program.inputDir) { // Loop through all the files in the input directory - console.log('Input dir ' + program.inputDir); + Logger.info('Input dir ' + program.inputDir); processDirectory(program.inputDir, fileProcessor); } else if (program.single) { - console.log('Single file ' + program.single); + Logger.info('Single file ' + program.single); processFile(path.resolve(program.single), fileProcessor); } else { - console.log('no file option given'); + Logger.info('no file option given'); } diff --git a/packages/concerto-core/lib/logger.js b/packages/concerto-core/lib/logger.js new file mode 100644 index 0000000000..feac1c2c57 --- /dev/null +++ b/packages/concerto-core/lib/logger.js @@ -0,0 +1,130 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const winston = require('winston'); +const { LEVEL, MESSAGE } = require('triple-beam'); +const jsonStringify = require('fast-safe-stringify'); +const jsome = require('jsome'); +const fs = require('fs'); +const env = process.env.NODE_ENV || 'development'; +const tsFormat = () => (new Date()).toLocaleTimeString(); + +/** + * Helper function to test is a string is a stringified version of a JSON object + * @param {string} str - the input string to test + * @returns {boolean} - true iff the string can be parsed as JSON + * @private + */ +function isJSON(str) { + try { + return (JSON.parse(str) && !!str); + } catch (e) { + return false; + } +} + +jsome.params.lintable = true; + +const jsonColor = winston.format(info => { + const padding = info.padding && info.padding[info.level] || ''; + + if(info[LEVEL] === 'error' && info.stack) { + info[MESSAGE] = `${tsFormat()} - ${info.level}:${padding} ${info.message}\n${info.stack}`; + return info; + } + + if (info[LEVEL] === 'info' || info[LEVEL] === 'warn') { + if(typeof info.message === 'object') { + info[MESSAGE] = `${tsFormat()} - ${info.level}:${padding}\n${jsome.getColoredString(info.message, null, 2)}`; + } else if(isJSON(info.message)) { + info[MESSAGE] =`${tsFormat()} - ${info.level}:${padding}\n${jsome.getColoredString(JSON.parse(info.message), null, 2)}`; + } else { + info[MESSAGE] = `${tsFormat()} - ${info.level}:${padding} ${info.message}`; + } + return info; + } + + const stringifiedRest = jsonStringify(Object.assign({}, info, { + level: undefined, + message: undefined, + splat: undefined + })); + + if (stringifiedRest !== '{}') { + info[MESSAGE] = `${tsFormat()} - ${info.level}:${padding} ${info.message} ${stringifiedRest}`; + } else { + info[MESSAGE] = `${tsFormat()} - ${info.level}:${padding} ${info.message}`; + } + return info; + +}); + +const enumerateErrorFormat = winston.format(info => { + if (info.message instanceof Error) { + info.message = Object.assign({ + message: info.message.message, + stack: info.message.stack + }, info.message); + } + + if (info instanceof Error) { + return Object.assign({ + message: info.message, + stack: info.stack + }, info); + } + + return info; +}); + +let logger = winston.createLogger({ + format: winston.format.combine( + winston.format.json(), + enumerateErrorFormat(), + winston.format.colorize(), + jsonColor(), + ), + transports: [ + new winston.transports.Console({ + level: 'info', + }), + ] +}); + +// Only write log files to disk if we're running in development +// and not in a browser (webpack or browserify) +const setupLogger = ((process,env,logDir) => { + if (env === 'development' && !process.browser) { + // Create the log directory if it does not exist + if (!fs.existsSync(logDir)) { + fs.mkdirSync(logDir); + } + + logger.add(new winston.transports.File({ + name: 'logs-file', + filename: `${logDir}/trace.log`, + level: 'debug' + })); + } +}); + +const logDir = 'log'; +setupLogger(process,env,logDir); +logger.setup = setupLogger; +logger.entry = logger.debug; +logger.exit = logger.debug; + +module.exports = logger; \ No newline at end of file diff --git a/packages/concerto-core/lib/tools/changelog.js b/packages/concerto-core/lib/tools/changelog.js index ff7f8316d3..2517e47bb2 100644 --- a/packages/concerto-core/lib/tools/changelog.js +++ b/packages/concerto-core/lib/tools/changelog.js @@ -16,6 +16,7 @@ const fs = require('fs'); const yargs = require('yargs'); +const Logger = require('../logger'); const VersionChecker = require('./versionchecker'); /** @@ -40,6 +41,6 @@ try { VersionChecker.check(changelog, publicApi, packageJson); } catch(err) { - console.log(err); + Logger.error(err); process.exit(1); } diff --git a/packages/concerto-core/lib/tools/plantumltoimage.js b/packages/concerto-core/lib/tools/plantumltoimage.js index 204b0e0ab0..66c65c5aab 100644 --- a/packages/concerto-core/lib/tools/plantumltoimage.js +++ b/packages/concerto-core/lib/tools/plantumltoimage.js @@ -19,8 +19,6 @@ const path = require('path'); const yargs = require('yargs'); const plantuml = require('node-plantuml'); - - /** * Generate an image file from a PlantUML source file * @private diff --git a/packages/concerto-core/lib/tools/versionchecker.js b/packages/concerto-core/lib/tools/versionchecker.js index a737533968..03cc690583 100644 --- a/packages/concerto-core/lib/tools/versionchecker.js +++ b/packages/concerto-core/lib/tools/versionchecker.js @@ -16,6 +16,7 @@ const crypto = require('crypto'); const semver = require('semver'); +const Logger = require('../logger'); /** * Checks that a change log file takes into account @@ -89,7 +90,7 @@ class VersionChecker { throw new Error('Did not find any version in changelog'); } else { - console.log('SUCCESS: validated public API against package.json and changelog.txt.'); + Logger.info('SUCCESS: validated public API against package.json and changelog.txt.'); } return true; diff --git a/packages/concerto-core/package.json b/packages/concerto-core/package.json index db40398e96..8caf2c89f4 100644 --- a/packages/concerto-core/package.json +++ b/packages/concerto-core/package.json @@ -65,12 +65,16 @@ "axios": "0.19.0", "debug": "4.1.1", "doctrine": "3.0.0", + "fast-safe-stringify": "2.0.7", + "jsome": "2.5.0", "lorem-ipsum": "1.0.6", "mkdirp": "0.5.1", "moment-mini": "2.22.1", "semver": "6.3.0", + "triple-beam": "1.3.0", "urijs": "1.19.1", - "uuid": "3.3.2" + "uuid": "3.3.2", + "winston": "3.2.1" }, "license-check-and-add-config": { "folder": "./lib", diff --git a/packages/concerto-core/scripts/api-changelog.js b/packages/concerto-core/scripts/api-changelog.js index a8f1f9dc7e..4f05b26ecd 100755 --- a/packages/concerto-core/scripts/api-changelog.js +++ b/packages/concerto-core/scripts/api-changelog.js @@ -17,6 +17,7 @@ const child_process = require('child_process'); const fs = require('fs'); const path = require('path'); +const Logger = require('../lib/logger'); const parentDirectory = path.resolve(__dirname, '..'); const apiSignatureFile = path.resolve(parentDirectory, 'api.txt'); @@ -51,6 +52,6 @@ return Promise.resolve() }); }) .catch((error) => { - console.error(error); + Logger.error(error); process.exit(1); }); diff --git a/packages/concerto-core/test/logger.js b/packages/concerto-core/test/logger.js new file mode 100644 index 0000000000..edc21d644c --- /dev/null +++ b/packages/concerto-core/test/logger.js @@ -0,0 +1,124 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const Logger = require('../lib/logger'); +const Fs = require('fs'); +const Chai = require('chai'); + +Chai.should(); +Chai.use(require('chai-things')); + +describe('logger', () => { + + describe('#logger.error', function () { + it('should call logger.error', async function () { + Logger.error('This is logging some error'); + }); + it('should call logger.error', async function () { + Logger.log({ + level: 'error', + message: 'Hey! Log something?', + stack: 'stack says boo!' + }); + }); + it('should call logger.error with a stack', async function () { + Logger.log({ + level: 'error', + message: 'Hey! Log something?', + stack: 'stack says boo!' + }); + }); + it('should call logger.error with some padding', async function () { + Logger.log({ + level: 'error', + message: 'Hey! Log something?', + padding: { error: '>>>' } + }); + }); + }); + describe('#logger.warn', function () { + it('should call logger.warn', async function () { + Logger.warn('This is logging some warning'); + }); + it('should call logger.warn with JSON', async function () { + Logger.log({ + level: 'warn', + message: { 'message' : 'This is a JSON message' } + }); + }); + it('should call logger.warn with stringified JSON', async function () { + Logger.warn('{ "message" : "This is a JSON message" }'); + }); + }); + describe('#logger.info', function () { + it('should call logger.info', async function () { + Logger.info('This is logging some useful information'); + }); + it('should call logger.info with JSON', async function () { + Logger.log({ + level: 'info', + message: { 'message' : 'This is a JSON message' } + }); + }); + it('should call logger.info with stringified JSON', async function () { + Logger.info('{ "message" : "This is a JSON message" }'); + }); + }); + describe('#logger.debug', function () { + it('should call logger.debug', async function () { + Logger.debug('This is logging some debug message'); + }); + it('should call logger.debug with an Error object', async function () { + Logger.debug(new Error('This is some debug message')); + }); + it('should call logger.info with an Error object in the message', async function () { + Logger.log({ + level: 'info', + message: new Error('The proof is in the pudding') + }); + }); + }); + describe('#logger.info (in production)', function () { + it('should call logger.info', async function () { + process.env.NODE_ENV = 'production'; + Logger.info('This is logging some useful information'); + }); + }); + describe('#setuplogger', () => { + const logDir = 'log'; + const logDirTest = 'logtest'; + it('should setup logger', async function () { + Logger.setup(process,'development',logDir); + }); + it('should setup logger (production)', async function () { + Logger.setup(process,'production',logDir); + }); + it('should setup logger with log directory', async function () { + Logger.setup(process,'development',logDirTest); + Fs.existsSync(logDir).should.be.true; + try { Fs.unlinkSync(`${logDirTest}/trace.log`); } catch (err) { Logger.info(err); } + try { Fs.rmdirSync(logDirTest, (err) => {}); } catch (err) { Logger.info(err); } + Logger.setup(process,'development',logDir); + }); + it('should setup logger with log directory (in production)', async function () { + Logger.setup(process,'production',logDirTest); + Fs.existsSync(logDir).should.be.true; + try { Fs.unlinkSync(`${logDirTest}/trace.log`); } catch (err) { Logger.info(err); } + try { Fs.rmdirSync(logDirTest, (err) => {}); } catch (err) { Logger.info(err); } + Logger.setup(process,'development',logDir); + }); + }); +}); diff --git a/packages/concerto-core/test/models/animaltracking.js b/packages/concerto-core/test/models/animaltracking.js index 70d9316d45..23948a3f51 100644 --- a/packages/concerto-core/test/models/animaltracking.js +++ b/packages/concerto-core/test/models/animaltracking.js @@ -16,6 +16,7 @@ //const assert = require('assert'); require('chai').should(); +const Logger = require('../../lib/logger'); const Factory = require('../../lib/factory'); const ModelManager = require('../../lib/modelmanager'); const Relationship = require('../../lib/model/relationship'); @@ -40,8 +41,8 @@ describe('animaltracking Model', function(){ animaltrackingModel = fs.readFileSync('./test/data/model/animaltracking.cto', 'utf8'); animaltrackingModel.should.not.be.null; modelManager.addModelFile(animaltrackingModel, 'animaltracking.cto'); - console.log('no###'); - console.log(modelManager.getNamespaces()); + Logger.info('no###'); + Logger.info(modelManager.getNamespaces()); modelFile = modelManager.getModelFile('com.hyperledger.composer.animaltracking'); modelFile.should.not.be.null;