Skip to content

Commit 86bffb6

Browse files
committed
Merge pull request #1516 from NativeScript/ikoevska-patch-1
Updates to extending-cli
2 parents 80ff90b + 2074526 commit 86bffb6

File tree

1 file changed

+98
-60
lines changed

1 file changed

+98
-60
lines changed

extending-cli.md

+98-60
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,118 @@
11
Extending the CLI
22
=================
33

4-
NativeScript CLI allows you to extend its behavior and customize it according to your needs.
5-
Each time the CLI executes a particular command (for example `tns build`) it checks whether you have added any extending hooks and executes them.
6-
Additionally, plugins can use these hooks to control the compilation of the program.
7-
8-
What are the hooks
9-
==================
10-
11-
Hooks can be executable code, Node.js script, or even a directory containing other files. To be executed however, the hooks must be placed under the `hooks` subdirectory of your project.
12-
The hook name must follow a strict scheme, describing:
13-
14-
- the action being hooked
15-
- whether the user code must be called before or after the action
16-
17-
For example, to execute your code before the `prepare` command starts, create a file named `before-prepare` and place it in the `hooks` directory.
18-
To execute your code after a command completes, create `after-prepare`.
19-
All file extensions (if present) are accepted but JavaScript files are treated specially, which is explained bellow.
20-
21-
The project structure looks like this:
22-
23-
```
24-
my-app/
25-
├── index.js
26-
├── package.json
27-
└── hooks/
28-
├── before-prepare.js (this is a Node.js script)
29-
└── after-prepare (this is an executable file)
30-
```
31-
32-
To support multiple scripts extending the same action, you ccan create a sub-directory in the `hooks` directory using the naming convention described below.
33-
When you place code files into that folder, the CLI executes each file one after another, but not in a guaranteed order.
34-
35-
```
36-
my-app/
37-
├── index.js
38-
├── package.json
39-
└── hooks/
40-
└── before-prepare (a directory)
41-
├── hook1 (this is an executable file)
42-
└── hook2 (this is an executable file)
43-
```
44-
45-
Execute hooks as child process
4+
The NativeScript CLI lets you extend its behavior and customize it to fit your needs by using [hooks](https://en.wikipedia.org/wiki/Hooking).
5+
6+
When you run one of the [extendable commands](#commands-with-hooking-support) (for example, `tns build`), the CLI checks for hooks and executes them. Plugins can also use hooks to control the compilation of the application package.
7+
8+
## Hooks in the NativeScript CLI
9+
10+
For the NativeScript CLI to execute your hooks, you must place them in the `hooks` subdirectory of your project and name them using a specific convention. Your hooks might be executable code, a Node.js script, or a directory containing Node.js scripts or executable code. All file extensions are supported but JavaScript files are treated [differently](#execute-hooks-in-process).
11+
12+
You can attach the hook before or after `prepare` operations or to `--watch` operations.
13+
14+
Note that `watch` hooks can be executed only at the time of running `--watch` operations. The `watch` hooks are the last thing executed before launching the file system watcher which tracks for changes to your code.
15+
16+
Your hooks must conform to the following naming and placement conventions:
17+
18+
* If you want to attach a single before or after hook to `prepare` operations, you must place the hook in the root of the `hooks` subdirectory. The file must be named `before-prepare` or `after-prepare`. For example:
19+
20+
```
21+
my-app/
22+
├── index.js
23+
├── package.json
24+
└── hooks/
25+
├── before-prepare.js (this is a Node.js script)
26+
└── after-prepare (this is an executable file)
27+
```
28+
* If you want to attach multiple hooks before or after a prepare operation, you must place them inside a `before-prepare` or `after-prepare` subdirectory of the `hooks` subdirectory. You can specify any meaningful name for the the hooks inside the subdirectory. For example:
29+
30+
```
31+
my-app/
32+
├── index.js
33+
├── package.json
34+
└── hooks/
35+
└── before-prepare (a directory)
36+
├── hook1 (this is an executable file)
37+
└── hook2 (this is an executable file)
38+
```
39+
* If you want to attach a hook for `--watch` operations, you must place the hook in the root of the `hooks` subdirectory. The file must be named `watch`. For example:
40+
41+
```
42+
my-app/
43+
├── index.js
44+
├── package.json
45+
└── hooks/
46+
└── watch.js (this is a Node.js script)
47+
```
48+
* If you want to attach multiple hooks for `--watch` operations, you must place them inside a `watch` subdirectory of the `hooks` subdirectory. You can specify any meaningful name for the the hooks inside the subdirectory. For example:
49+
50+
```
51+
my-app/
52+
├── index.js
53+
├── package.json
54+
└── hooks/
55+
└── watch (a directory)
56+
├── hook1 (this is an executable file)
57+
└── hook2 (this is an executable file)
58+
```
59+
60+
> **NOTE:** When multiple hooks are attached to a single event (i.e. multiple hooks are stored in dedicated subdirectories), at the specified time, the CLI executes each hook one by one. However, the order of hook execution is not strict and might change over command executions.
61+
62+
Execute Hooks as Child Process
4663
========================
4764
48-
If your hook is an executable file which is not a Node.js code, NativeScript executes it using the normal OS API for creating a child process. This gives you the flexibility to write it in any way you want.
49-
The hook receives three variables in its OS environment:
65+
If your hook is an executable file which is not a Node.js JavaScript file, the CLI executes it using the normal OS API for creating a child process. This gives you the flexibility to write it in any way you want.
66+
67+
The hook receives the following three variables in its OS environment.
5068
51-
- NATIVESCRIPT-COMMANDLINE - the full command line which triggered the hook execution, for example: `/usr/local/bin/node /usr/local/lib/node_modules/nativescript/bin/nativescript-cli.js build android`
52-
- NATIVESCRIPT-HOOK_FULL_PATH - the full path to the hook file name, for example `/home/user/app/hooks/after-prepare/myhook`
53-
- NATIVESCRIPT-VERSION - the version of the NativeScript CLI which invokes the hook, for example `1.5.2`
69+
Variable | Description | Sample Value
70+
---|---|---
71+
`NATIVESCRIPT-COMMANDLINE` | The complete command line which triggered the hook execution. | `/usr/local/bin/node /usr/local/lib/node_modules/nativescript/bin/nativescript-cli.js build android`
72+
`NATIVESCRIPT-HOOK_FULL_PATH` | The complete command line to the hook file name. | `/home/user/app/hooks/after-prepare/myhook`
73+
`NATIVESCRIPT-VERSION` | the version of the NativeScript CLI which invokes the hook. | `1.5.2`
5474
55-
Execute hooks in-process
75+
Execute Hooks In-Process
5676
========================
5777
5878
When your hook is a Node.js script, the CLI executes it in-process. This gives you access to the entire internal state of the CLI and all of its functions.
59-
The CLI assumes that this is a CommonJS module and calls its single exported function with four parameters.
60-
The type of the parameters are described in the .d.ts files which are part of the CLI source code [here](https://github.com/NativeScript/nativescript-cli/tree/master/lib/definitions) and [here](https://github.com/telerik/mobile-cli-lib/tree/master/definitions)
6179
62-
- $logger: ILogger. Use the members of this class to show messages to the user cooperating with the CLI internal state.
63-
- $projectData: IProjectData. Contains data about the project, like project directory, id, dependencies, etc.
64-
- $usbLiveSyncService:ILiveSyncService. Use this variable to check whether a LiveSync or normal build is in progress.
65-
- hookArgs: any. Contains all the parameters of the original function in the CLI which is being hooked.
80+
The CLI assumes that this is a CommonJS module and calls its single exported function with four parameters. The type of the parameters is described in the `.d.ts` files which are part of the CLI source code [here](https://github.com/NativeScript/nativescript-cli/tree/master/lib/definitions) and [here](https://github.com/telerik/mobile-cli-lib/tree/master/definitions).
81+
82+
Parameter | Type | Description
83+
---|---|---
84+
`$logger` | ILogger | Use the members of this class to show messages to the user cooperating with the CLI internal state.
85+
`$projectData` | IProjectData | Contains data about the project, such as project directory, ID, dependencies, etc.
86+
`$usbLiveSyncService` | ILiveSyncService | Use this variable to check whether a LiveSync or normal build is in progress.
87+
`hookArgs` | Any | Contains all the parameters of the original function in the CLI which is being hooked.
6688
6789
The hook must return a Promise. If the hook succeeds, it must fullfil the promise, but the fullfilment value is ignored.
68-
The hook can also reject the promise with an instance of Error. The returned error can have two optional members controlling the CLI:
90+
The hook can also reject the promise with an instance of Error. The returned error can have two optional members controlling the CLI.
6991
70-
- stopExecution: boolean - set this to false to let the CLI continue executing this command
71-
- errorAsWarning: boolean: set this to treat the returned error as warning. The CLI prints the error.message colored as a warning and continues executing the current command
92+
Member | Type | Description
93+
---|---|---
94+
`stopExecution` | Boolean | Set this to `false` to let the CLI continue executing this command.
95+
`errorAsWarning` | Boolean | Set this to treat the returned error as warning. The CLI prints the error.message colored as a warning and continues executing the current command.
7296
7397
If these two members are not set, the CLI prints the returned error colored as fatal error and stops executing the current command.
7498
75-
Furthermore, the global variable `$injector: IInjector` gives access to the CLi Dependency Injector, through which all code services are available.
99+
Furthermore, the global variable `$injector` of type `IInjector` provides access to the CLI Dependency Injector, through which all code services are available.
76100
77-
Supported commands for hooking
101+
Commands with Hooking Support
78102
==============================
79103
80-
Only the `prepare` comand can be hooked. Internally, this command is also invoked during build and livesync. The later commands will execute the prepare hooks at the proper moment of their execution.
104+
The only two operations to which you can attach hooks are `prepare` operations and `--watch` operations.
105+
106+
The NativeScriot CLI executes hooks attached to `prepare` when you run the following commands:
107+
108+
* `tns prepare <Platform>`
109+
* `tns build <Platform>`
110+
* `tns deploy <Platform>`
111+
* `tns run <Platform>`
112+
* `tns livesync <Platform>`
113+
* `tns test <Platform>`
114+
115+
The NativeScriot CLI executes hooks attached to `--watch` operations when you run the following commands:
116+
117+
* `tns test <Platform>` with the `--watch` option.
118+
* `tns livesync <Platform>` with the `--watch` option.

0 commit comments

Comments
 (0)