npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fluid-launcher

v1.0.0

Published

A launcher that merges options from the command line, environment, options files with the launcher defaults.

Downloads

4

Readme

fluid-launcher

This package provides a fluid.launcher Fluid component that standardizes the launching of Fluid components with custom options. The component is based on yargs and Kettle.

fluid.launcher

The launcher component uses yargs to generate a set of merged options that reflect (in order of precedence):

  1. Any options passed on the command line.
  2. The value of environment variables.
  3. Options configured using the optionsFile parameter (see below).
  4. The defaults configured using options.yargsOptions (see below).

It's possible to bypass this order, see the section "Pulling Environment Variables by Reference" below for more details. Once the options have been constructed, a component will be launched with the merged options.

Component Options

| Option | Type | Description | | --------------- | ----------- | ----------- | | filterKeys | {Boolean} | Whether or not to filter the list of options. If set to true, only known options configured using yargsOptions will be used. If set to false, any arbitrary options will be passed. Set to true by default. | | excludeKeys | {Array} | The keys to exclude from the final merged options. Defaults to ["optionsFile"], which strips the built-in optionsFile parameter (see below) from the output.| | includeKeys | {Array} | The keys to include in the final merged options. Defaults to Object.keys(that.options.yargsOptions.describe), so that all of the properties yargs is aware of are passed through to the merged options. | | yargsOptions | {Object} | A map of yargs function names and arguments to pass to the function. See below for more details, and for the defaults. |

The yargsOptions option

To give you an example of how yargsOptions can be used, here are the defaults provided by the base fluid.launcher grade:

yargsOptions: {
    env: true, // Parse environment variables
    demandOption: "optionsFile", // Which arguments are required.
    describe: {
        "optionsFile": "A file to load configuration options from."
    },
    help: true, // Provide a `--help` option that displays our usage information.
    usage: "Usage $0 [options]" // Display a "usage" message if args are missing or incorrect.
},

This provides support for a single required variable, optionsFile, which can be provided either as a command line argument or environment variable (env: true).

For full documentation on all available functions and arguments, see the yargs documentation.

The optionsFile parameter and configuration file format

The launcher supports an implicit optionsFile parameter, which allows you to load one or more options from a JSON file. You are expected to supply a single path, which must either be a path relative to the working directory, a full filesystem path, or a package-relative path that can be parsed by fluid.module.resolvePath (for example, %package/path/to/file.json). You can set the optionsFile option using an environment variable, a command line parameter, or by specifying it in the defaults, as in:

fluid.defaults("my.launcher", {
    gradeNames: ["fluid.launcher"],
    yargsOptions: {
        defaults: {
            optionsFile: "%my-package/configs/config.json"
        }
    }
});

The contents of this file will be loaded using the configuration loading built into kettle. The file is expected to correspond roughly to a component definition, but supports additional options for including other configuration files.

In general, the config file format is a superset of a normal subcomponent definition. As with subcomponents, you are expected to enclose the component options in an options keyword. Although a subcomponent definition requires a type field, in the case of a configuration file type is optional, but should be filled in with a unique name (for example, the name of the configuration file minus the extension). The type will be a part of the constructed grade name, and will appear in log messages, so a unique name helps make it clear which options are being used for a given launch. If type is omitted, it will be replace with a generated ID, which makes troubleshooting more difficult.

See the kettle documentation for more details about the configuration file format, including the special keywords that support merging material from other configuration files.

Using the global launcher

This package includes a generic launcher that can be used to load any options file (see above) directly. When using this package as a dependency, this script is available under node_modules/.bin/fluid-launcher. You can also install this package globally, in which case the fluid-launcher command will be available in your path.

The generic launcher supports the two core options provided by the base fluid.launcher grade, namely the optionsFile parameter (see above) and a logLevel parameter that you can use to toggle logging. The generic launcher allows you to set any arbitrary option (see the filterKeys option above). However, it only accepts command-line arguments (see the yargsOptions.env example above).

Creating a custom launcher

If you wish to make use of the wider range of yargs features supported by this package, you need to define and launch a fluid.launcher instance, as in the example included with this package.

/* eslint-env node */
"use strict";
var fluid = require("infusion");
fluid.setLogging(true);

var my = fluid.registerNamespace("my");
fluid.require("%fluid-launcher");

fluid.defaults("my.launcher.worker", {
    gradeNames: ["fluid.component"],
    var1:    "set in the component",
    listeners: {
        "onCreate.log": {
            funcName: "fluid.log",
            args: ["Var 1:", "{that}.options.var1"]
        },
        "onCreate.destroy": {
            func: "{that}.destroy",
            priority: "after:log"
        }
    }
});

fluid.registerNamespace("my.launcher");

fluid.defaults("my.launcher", {
    gradeNames: ["fluid.launcher"],
    yargsOptions: {
        describe: {
            "var1": "you can set this option"
        },
        defaults: {
            "optionsFile": "%fluid-launcher/examples/my-launcher-config.json"
        }
    }
});

my.launcher();

Note that we have defined a component grade my.launcher.worker, which is visible from our launch file. We could also have defined a grade in an external file, but we must require that file from the launcher file itself, so that it is defined when we try to instantiate the component.

In this example, we set a default for optionsFile, which is used to load a sample configuration file:

{
    "type": "launcherConfig",
    "options": {
        "gradeNames": ["my.launcher.worker"],
        "var1": "set in the options file."
    }
}

Note the gradeNames parameter refers to the my.launcher.worker grade we defined in the same file where we defined our launcher grade itself. The gradeNames keyword in a configuration file is the the primary way in which we associate our launcher with the component grade(s) to be launched.

As with sub-components, we can have multiple gradeNames, which will be merged as they would when instantiating a sub-component. Grades are merged from left to right, so that that rightmost grade's options take precedence.

So, assuming the above launcher and configuration file, here are some examples of the output that results when using various combinations of command line parameters and environment variables:

$ node examples/my-launcher.js
Var 1: Set in the options file.

$ node examples/my-launcher.js --var1 "Set from the command line."
Var 1: Set from the command line.

$ var1="Set by an environment variable." node examples/my-launcher.js
Var 1: Set by an environment variable

$ node examples/my-launcher.js --optionsFile "%fluid-launcher/examples/my-alternate-launcher-config.json"
Var 1: Set in the alternate options file.

Referencing Deep Variables

By default, yargs supports using "dot notation" to refer to deep variables. To allow someone to set arbitrary deep paths, set filterKeys (see above) to false in your launcher options. To "describe" or "demand" a deep variable, you would use yargsOptions like the following:

yargsOptions: {
    describe: {
        "deep.path": "A deep path, which is required."
    },
    demandOption: "deep.path"
}

You can then pass in an option using a command like node my-launcher.js --deep.path /tmp

The resulting options would contain a path string within a deep object, as in:

{
    deep: {
        path: "/tmp"
    }
}

IoC Reference Resolution

All IoC references are resolved when the component is instantiated, and you can pass IoC options from a command line argument or environment variable. For example, launch the supplied example script in this package using a command like the following:

node examples/my-launcher.js --optionsFile %fluid-launcher/examples/my-launcher-config.json --var2 "{that}.options.var1"

In the resulting output, you will see that var2 is drawn from options.var1, which in this case is a value loaded from a configuration file.

Pulling Environment Variables by Reference

The previous examples covered "pushing" options information through from arguments or environment variables. It is also possible to explicitly "pull" environment variables and arguments from an options block, as shown in this sample configuration file:

{
  "type": "pullConfig",
  "options": {
    "gradeNames": ["my.grade"],
    "myvar": "{fluid.launcher.resolver}.env.myvar"
  }
}

This mechanism allows you to bypass the default order of inheritance, to prefer an environment variable over a command line argument. Let's say you run a command like the following on a UNIX-like system:

myvar=environment node my-launcher.js --optionsFile %my-package/configs/pullConfig.json --myvar command-line

Instead of the default behavior, which would result in myvar being set to command-line, with the settings shown above, the value of myvar would be environment instead.

Functions that Support Arrays

Many functions provided by yargs support a single argument. For convenience, most values used as part of the yargsOptions block (strings, objects, numbers, booleans, functions) are wrapped in an array and treated as the first argument to the underlying function. This allows you to use simple values wherever possible, as in:

fluid.defaults("fluid.launcher.simpleVars", {
    gradeNames: ["fluid.launcher"],
    yargsOptions: {
        // This object is passed to the underlying "describe" method.
        describe: {
            foo: "The first field.",
            bar: "The second."
        },
        // This boolean is passed to the underlying "env" method.
        env: false,
        // This number is passed to the underlying "wrap" method.
        wrap: 80
    }
});

However, as a byproduct of this, you must use a different syntax to directly pass an array to a yargs function, as shown in the following example:

fluid.defaults("fluid.launcher.arrayVars", {
    gradeNames: ["fluid.launcher"],
    yargsOptions: {
        "array": [["arrayVar1", "arrayVar2"]],
        "demandOption": [["outputFile", "arrayVar1"]],
        "boolean": [["bool1", "bool2"]],
        "number": [["num1", "num2"]]
    }
});

The same options can be expressed using the options method provided by yargs, as shown in the following example:

fluid.defaults("fluid.launcher.optionsObject", {
    gradeNames: ["fluid.launcher"],
    yargsOptions: {
        options: {
            "arrayVar1": {
                "array": true,
                "demandOption": true
            },
            "arrayVar2": {
                "type": "array"
            },
            "bool1": {
                "boolean": true
            },
            "bool2": {
                "type": "boolean"
            },
            "num1": {
                "number": true
            },
            "num2": {
                "type": "number"
            },
            "outputFile": {
                "demandOption": true
            }
        }
    }
});

You can choose the format which best fits your needs.