Skip to content

Helper for managing external NPM module executables in Nova extensions

Notifications You must be signed in to change notification settings

ashur/nova-npm-executable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nova-npm-executable

If your Nova extension relies on an NPM package's executable, it's a good idea to provide a fallback or default installation.

Users of your extension might already have the package installed globally or as a dependency of a given project. If so, your extension can prefer those locations automatically. However, if the user doesn't have the package installed, providing a fallback instance is a helpful way of letting them get started without having to install tools on the command line.

nova-npm-executable provides a helper class to make offering this functionality easier:

  • Install the fallback package inside the Nova extension bundle
  • Instantiate a Process instance constructed with options that are ideal for running the executable in the user's environment

Installation

npm install --save nova-npm-executable

See Using NPM Packages in Nova Extensions for information on structuring your project and using a module bundler to include the nova-npm-executable API in your extension.

Defining Extension Dependencies

In addition to your project's top-level package.json, your extension bundle should also include its own package.json file. Use this to define the package or packages whose CLI executables you wish to install as a fallback.

For example, if you are building a JSONLint extension that relies on the jsonlint executable:

cd nova-jsonlint/JSONLint.novaextension
npm install --save jsonlint

⚠️ NPMExecutable.install will only install packages defined in dependencies, not from devDependencies.

Usage

const {NPMExecutable} = require( "nova-npm-executable" );

Examples

Check whether the fallback dependency has been installed inside the extension bundle, and install it if not:

class JSONLint
{
	constructor()
	{
		this.jsonlint = new NPMDependency( "jsonlint" );
		if( !this.jsonlint.isInstalled )
		{
			this.jsonlint.install()
				.catch( error =>
				{
					console.error( error );
				});
		}

API

constructor(binName)

  • {string} binName - The name of the executable found in node_modules/.bin

Example:

let jsonlint = new NPMExecutable("jsonlint");

install()

Install NPM dependencies defined in the package.json file located inside your extension bundle.

See Defining Extension Dependencies for more information.

↩️ Returns Promise, which resolves or rejects depending on the success of installation

isInstalled

Whether the package has already been installed inside the extension bundle.

↩️ Returns boolean

process(options)

  • {Object} options
  • {[string]} [options.args]
  • {string} [options.cwd]
  • {Object} [options.env]
  • {string|boolean} [options.shell]
  • {[string]} [options.stdio]

Helper function for instantiating Process object with options needed to run the module executable using npx.

In addition to constructing Process arguments as ["npx","<binName>"], process() automatically augments the user's $PATH to create a preferential cascade of possible executable locations:

  1. Current Workspace
  2. Global Installation
  3. Extension Bundle

💡 If the user is working in a project, for example, which defines a specific version of your extension's executable, that installation will be preferred, followed by any version they may have installed globally via npm install -g, followed finally by your extension's fallback.

Example:

/**
 * Write a string to the JSONLint process's STDIN. Equivalent to running
 * `echo <string> | npx jsonlint -c` on the command line.
 *
 * @param {String} string
 * @param {String} fileURI
 * @return {Promise}
 */
async lint( string, fileURI )
{
	try
	{
		let process = await this.jsonlint.process( { args: ["-c"] } );

		let output = "";
		process.onStdout( line => output += line.trimRight() );
		process.onStderr( line => output += line.trimRight() );
		process.onDidExit( status =>
		{
			let results = status === 0 ? [] : this.parseOutput( output );
			this.report( results, fileURI );
		});

		process.start();

		let writer = process.stdin.getWriter();
		writer.write( string );
		writer.close();

↩️ Returns Promise, which resolves with an pre-instantiated Process object.

About

Helper for managing external NPM module executables in Nova extensions

Topics

Resources

Stars

Watchers

Forks