diff --git a/CHANGELOG.md b/CHANGELOG.md index e8715ce074..0b6bbc55c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,61 @@ NativeScript CLI Changelog ================ + +5.4.0 (2019, May 15) +== + +### Implemented +* [Implemented #3993](https://github.com/NativeScript/nativescript-cli/issues/3993): Improve `ctrl + c` handling. +* [Implemented #4374](https://github.com/NativeScript/nativescript-cli/issues/4374): Add `iCloudContainerEnvironment` build option. +* [Implemented #4394](https://github.com/NativeScript/nativescript-cli/issues/4394): Enable Using Hot Module Replacement by Default for New Projects +* [Implemented #4518](https://github.com/NativeScript/nativescript-cli/issues/4518): Show deprecation messages for things that will be dropped for 6.0.0 release +* [Implemented #4541](https://github.com/NativeScript/nativescript-cli/issues/4541): [Beta] Allow integration of Apple Watch application in NativeScript app +* [Implemented #4548](https://github.com/NativeScript/nativescript-cli/issues/4548): Deprecate support for the Legacy Workflow +* [Implemented #4602](https://github.com/NativeScript/nativescript-cli/issues/4602): Streamline CLI's logger + + +### Fixed +* [Fixed #4280](https://github.com/NativeScript/nativescript-cli/issues/4280): Incorrect message if you delete app's folder and run command with `--path` in it +* [Fixed #4512](https://github.com/NativeScript/nativescript-cli/issues/4512): App's Podfile should be applied last +* [Fixed #4573](https://github.com/NativeScript/nativescript-cli/pull/4573): logcat process is not restarted in some cases +* [Fixed #4593](https://github.com/NativeScript/nativescript-cli/issues/4593): Node.js processes not killed after `tns create` on macOS when analytics are enabled +* [Fixed #4598](https://github.com/NativeScript/nativescript-cli/issues/4598): app.css changes don't apply when debugging with --debug-brk +* [Fixed #4606](https://github.com/NativeScript/nativescript-cli/issues/4606): Unable to build application for iOS with nativescript-bottombar +* [Fixed #4616](https://github.com/NativeScript/nativescript-cli/issues/4616): `tns plugin create` command hangs + +5.3.4 (2019, April 24) +== + +### Fixed +* [Fixed #4561](https://github.com/NativeScript/nativescript-cli/issues/4561): CLI merges xcconfig files only for specified build configuration + +5.3.3 (2019, April 23) +== + +### Fixed +* [Fixed #4527](https://github.com/NativeScript/nativescript-cli/issues/4527): Unable to upload applications to App Store + +5.3.2 (2019, April 12) +== + +### Fixed +* [Fixed #1798](https://github.com/NativeScript/nativescript-cli/issues/1798): Test init command doesn't add a sample test in TypeScript for TypeScript/Angular projects +* [Fixed #4498](https://github.com/NativeScript/nativescript-cli/pull/4498): API: Change the AppStore ids for kinvey scanner and preview app +* [Fixed #4504](https://github.com/NativeScript/nativescript-cli/issues/4504): Custom tagged versions of android runtime are not supported +* [Fixed #4510](https://github.com/NativeScript/nativescript-cli/pull/4510): Handle HTTP 304 response status code + +5.3.1 (2019, April 03) +== + +### Implemented +* [Implemented #4492](https://github.com/NativeScript/nativescript-cli/pull/4492): API(kinvey): provide correct data to preview-sdk based on the schema + +### Fixed +* [Fixed #4370](https://github.com/NativeScript/nativescript-cli/issues/4370): NativeScript CLI installation fails on linux +* [Fixed #4451](https://github.com/NativeScript/nativescript-cli/issues/4451): Error while trying to start application on Android emulator with API level Q +* [Fixed #4483](https://github.com/NativeScript/nativescript-cli/pull/4483): Detection fixes for emulator/device + 5.3.0 (2019, March 27) == diff --git a/Gruntfile.js b/Gruntfile.js index fdaa5f0827..fb02e2b240 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -236,7 +236,7 @@ module.exports = function (grunt) { }); grunt.registerTask("lint", ["tslint:build"]); grunt.registerTask("all", ["clean", "test", "lint"]); - grunt.registerTask("rebuild", ["clean", "ts:devlib"]); + grunt.registerTask("rebuild", ["clean", "default"]); grunt.registerTask("default", ["ts:devlib", "generate_unit_testing_dependencies"]); grunt.registerTask("docs-jekyll", ['template']); }; diff --git a/PublicAPI.md b/PublicAPI.md index a2f251389e..3fdbba0e30 100644 --- a/PublicAPI.md +++ b/PublicAPI.md @@ -70,6 +70,18 @@ const tns = require("nativescript"); * [deviceLog](#devicelog) * [previewQrCodeService](#previewqrcodeservice) * [getPlaygroundAppQrCode](#getplaygroundappqrcode) +* [cleanupService](#cleanupservice) + * [setCleanupLogFile](#setcleanuplogfile) +* [initializeService](#initializeService) + * [initialize](#initialize) +* [logger](#logger) + * [initialize](#initialize) + * [getLevel](#getlevel) + * [appenders](#appenders) + * [emit-appender](#emit-appender) + * [cli-appender](#cli-appender) + * [custom layouts](#custom-layouts) + ## Module projectService @@ -1487,6 +1499,201 @@ tns.previewQrCodeService.getPlaygroundAppQrCode() }); ``` +## cleanupService +The `cleanupService` is used to handle actions that should be executed after CLI's process had exited. This is an internal service, that runs detached childProcess in which it executes CLI's cleanup actions once CLI is dead. As the process is detached, logs from it are not shown anywhere, so the service exposes a way to add log file in which the child process will write its logs. + +### setCleanupLogFile +Defines the log file location where the child cleanup process will write its logs. + +> NOTE: You must call this method immediately after requiring NativeScript CLI. In case you call it after the cleanup process had started, it will not use the passed log file. + +* Definition +```TypeScript +/** + * Sets the file in which the cleanup process will write its logs. + * This method must be called before starting the cleanup process, i.e. when CLI is initialized. + * @param {string} filePath Path to file where the logs will be written. The logs are appended to the passed file. + * @returns {void} + */ +setCleanupLogFile(filePath: string): void; +``` + +* Usage +```JavaScript +const tns = require("nativescript"); +tns.cleanupService.setCleanupLogFile("/Users/username/cleanup-logs.txt"); +``` + +## initializeService +The `initializeService` is used to initialize CLI's configuration at the beginning and print all warnings related to current environment. + +### initialize +This method executes initialization actions based on the passed parameters. In case `loggerOptions` are not passed, the default CLI logger will be used. +After initialization, the method will print all system warnings. + +* Definition +```TypeScript +interface IInitializeOptions { + loggerOptions?: ILoggerOptions; + settingsServiceOptions?: IConfigurationSettings; + extensibilityOptions?: { pathToExtensions: string }; +} + +interface IInitializeService { + initialize(initOpts?: IInitializeOptions): Promise; +} + +``` + +> NOTE: For more information about loggerOptions, you can check `logger`. + +* Usage + * Initialization without passing any data - `logger` will be initialized with default CLI settings. Warnings will be printed if there are any. + ```JavaScript + const tns = require("nativescript"); + tns.initializeService.initialize(); + ``` + * Initialize with custom settings service options: + ```JavaScript + const tns = require("nativescript"); + tns.initializeService.initialize({ settingsServiceOptions: { profileDir: "/Users/username/customDir", userAgentName: "MyApp" } }); + ``` + * Initialize with custom extensibility path: + ```JavaScript + const tns = require("nativescript"); + tns.initializeService.initialize({ extensibilityOptions: { pathToExtensions: "/Users/username/customDir/extensions" } }); + ``` + +## logger + +`logger` module is used to show any kind of information to the user. The `logger` uses `log4js` internally, which allows setting different levels for the messages. +The levels are available in `tns.constants.LoggerLevel` enum. Only messages from the current log level (or higher) are shown to the user, i.e. in case the log level is set to `INFO`, `DEBUG` and `TRACE` messages will not be shown to the user, but `WARN` and `ERROR` messages will be shown.
+`logger` module can be configured how to show the messages by using different appenders and layouts.
+* `appenders` are responsible for output of log events. They may write events to files, send emails, store them in a database, or anything. Most appenders use layouts to serialise the events to strings for output. +* `layout` is a function for converting a LogEvent into a string representation. + +`log4js` has predefined appenders and layouts that can be used. In case you do not pass any options to logger's initialization, CLI will default to [console appender](https://log4js-node.github.io/log4js-node/console.html) with [messagePassThrough layout](https://log4js-node.github.io/log4js-node/layouts.html#message-pass-through) with `INFO` log level.
+You can override only the properties you want, i.e. only the log level, the layout or the appender.
+`nativescript` itself has additional appenders that you can use. More information about them can be found below. You can get a full list of the available appenders by checking the `tns.constants.LoggerAppenders` object.
+ +> NOTE: When CLI is used as a command-line tool, it uses a custom appender and layout in order to write coloured messages to stdout or stderr. + +### initialize +The `initialize` method initializes the log4js settings - level, appender and layout. Once called, the settings cannot be changed anymore for the current process. + +* Definition +```TypeScript +interface IAppenderOptions extends IDictionary { + type: string; + layout?: Layout; +} + +interface ILoggerOptions { + level?: LoggerLevel; + appenderOptions?: IAppenderOptions; +} + +initialize(opts?: ILoggerOptions): void; +``` + +* Usage + * Initialize with default settings: + ```JavaScript + tns.logger.initialize(); + ``` + * Initialize with DEBUG log level: + ```JavaScript + tns.logger.initialize({ level: tns.constants.LoggerLevel.DEBUG }); + ``` + * Initialize with different appender, for example [fileSync](https://log4js-node.github.io/log4js-node/fileSync.html) appender: + ```JavaScript + tns.logger.initialize({ appenderOptions: { type: "fileSync" } }); + ``` + * Initialize with different layout, for example [Pattern](https://log4js-node.github.io/log4js-node/layouts.html#pattern) layout: + ```JavaScript + tns.logger.initialize({ appenderOptions: { layout: { type: "pattern" } } }); + ``` + * Initialize with custom appender, layout and level: + ```JavaScript + tns.logger.initialize({ appenderOptions: { type: "fileSync", layout: { type: "pattern" } }, level: tns.constants.LoggerLevel.DEBUG }); + ``` + +### getLevel +This method returns information for the current log level. + +* Definition +```TypeScript +getLevel(): string; +``` + +* Usage +```JavaScript +console.log(`Current log level is: ${tns.logger.getLevel()}`); +``` + +### appenders +The `appenders` are log4js concept. `appenders` are responsible for output of log events. You can use all predefined [log4js appenders](https://log4js-node.github.io/log4js-node/appenders.html) and also several predefined CLI appenders + +#### emit-appender +The `emit-appender` is used to emit the log events through a passed emitter instead of writing the messages. Whenever a message should be shown, the `emit-appender` emits `logData` event with an object containing the `loggingEvent` and the message passed through the specified layout stored in `formattedMessage` property. + +* Usage: +```JavaScript +const tns = require("nativescript"); +const { EventEmitter } = require("events"); +const { EMIT_APPENDER_EVENT_NAME, LoggerAppenders } = tns.constants; +const emitter = new EventEmitter(); +// IMPORTANT: Add the event handler before calling logger's initialize method. +// This is required as log4js makes a copy of the appenderOptions, where the emitter is passed +// NOTE: In case you want to debug the event handler, place `debugger` in it. +emitter.on(EMIT_APPENDER_EVENT_NAME, (logData) => { + if (logData.loggingEvent.level.levelStr === LoggerLevel.WARN) { + console.log(`WARNING: ${logData.formattedMessage}`); + } +}); + +const logger = tns.logger; +logger.initialize({ + appenderOptions: { + type: LoggerAppenders.emitAppender, + emitter + } +}); +``` + +> NOTE: In several cases CLI passes additional configuration properties in the `context` of the `loggingEvent`. Full list is available in the `tns.constants.LoggerConfigData` object. These properties are used by CLI's layout and appender to change the way the message is printed on the terminal and if it should be on stderr or stdout. + +#### cli-appender +`cli-appender` prints messages to stdout or stderr based on the passed options for the message. + +* Usage +```JavaScript +const tns = require("nativescript"); +const { EventEmitter } = require("events"); +const { EMIT_APPENDER_EVENT_NAME, LoggerAppenders } = tns.constants; + +const logger = tns.logger; +logger.initialize({ + appenderOptions: { + type: LoggerAppenders.cliAppender, + } +}); +``` + +### custom layouts +You can define your own layout function in the following way: +```JavaScript +const log4js = require("nativescript/node_modules/log4js"); +const util = require("util"); +log4js.addLayout("myCustomLayout", (config) => { + return (loggingEvent) => { + return util.format.apply(null, loggingEvent.data); + } +}); + +tns.logger.initialize({ appenderOptions: { layout: { type: "myCustomLayout" } } }); +``` + ## How to add a new method to Public API CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification. For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`. diff --git a/config/test-dependencies.json b/config/test-dependencies.json index 7a4868e2fb..879c04a950 100644 --- a/config/test-dependencies.json +++ b/config/test-dependencies.json @@ -28,5 +28,25 @@ { "name": "karma-qunit", "framework": "qunit" + }, + { + "name": "@types/karma-chai", + "framework": "mocha", + "projectType": ".ts" + }, + { + "name": "@types/mocha", + "framework": "mocha", + "projectType": ".ts" + }, + { + "name": "@types/jasmine", + "framework": "jasmine", + "projectType": ".ts" + }, + { + "name": "@types/qunit", + "framework": "qunit", + "projectType": ".ts" } ] \ No newline at end of file diff --git a/docs/build-jekyll-md.sh b/docs/build-jekyll-md.sh index df30621d91..832c7afbb2 100755 --- a/docs/build-jekyll-md.sh +++ b/docs/build-jekyll-md.sh @@ -5,5 +5,7 @@ rm -rf docs-cli npm install --ignore-scripts grunt docs-jekyll -cd docs-cli -mv index.md start.md \ No newline at end of file +if [ -d docs-cli ]; then + cd docs-cli + mv index.md start.md +fi \ No newline at end of file diff --git a/docs/man_pages/lib-management/plugin-create.md b/docs/man_pages/lib-management/plugin-create.md index bfa6d6f7ad..b267887ade 100644 --- a/docs/man_pages/lib-management/plugin-create.md +++ b/docs/man_pages/lib-management/plugin-create.md @@ -28,6 +28,8 @@ Create from a custom plugin seed | `$ tns plugin create * `--path` - Specifies the directory where you want to create the project, if different from the current directory. * `--username` - Specifies the Github username, which will be used to build the URLs in the plugin's package.json file. * `--pluginName` - Used to set the default file and class names in the plugin source. +* `--includeTypeScriptDemo` - Specifies if TypeScript demo should be created. Default value is `y` (i.e. `demo` will be created), in case you do not want to create this demo, pass `--includeTypeScriptDemo=n` +* `--includeAngularDemo` - Specifies if Angular demo should be created. Default value is `y` (i.e. `demo-angular` will be created), in case you do not want to create this demo, pass `--includeAngularDemo=n` * `--template` - Specifies the custom seed archive, which you want to use to create your plugin. If `--template` is not set, the NativeScript CLI creates the plugin from the default NativeScript Plugin Seed. `