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

lenv-cli

v2.1.4

Published

![](./cover.png)

Downloads

4

Readme

Install

NPM

$ npm install --global lenv-cli

YARN

$ yarn global add lenv-cli

Run

$ lenv

What is LENV?

LENV is a CLI tool which allows to configure and build docker-compose file from modules, secrets and automation artifacts.

What is module?

Module is a small piece of configuration. It may contain multiple configuration variants. For example local, staging and production. End user of LENV CLI has to select which modules to run and configuration variant for each module. LENV will resolve dependencies and use all required modules to build docker-compose file.

How to create a module?

Modules are built from multiple files. At least two files are required:

  • Module declaration file ./modules/MODULE_DIR/*.module.js
  • Module configuration variant ./modules/MODULE_DIR/configs/*.js

Module declaration file has only two fields:

module.exports = {
  name: "mongodb", // module name
  defaultConfig: "local", // default configuration variant
};

Module configuration variant:

module.exports = {
  name: "local", // variant name
  requires: [
	  /* 
		Array of dependencies. 
		Values are names of other modules.
		(optional)
	  */
  ],
  jobs: [
	  /* 
		Array of jobs required for this configuration. 
		Values are names of other modules.
		(optional)
	  */
  ],
  output: {
    /*
		Object with exported variables 
		which other modules may use
		(optional)
	  */
  },
  docker: {
    /*
		This object will be merged into the final
		docker-compose file
		(optional)
	  */
  },
};

How to share variables between modules?

There are to steps.

  • Export values from one module
  • Import values in another

How to export values?

Add them into the output section

module.exports = {
  name: "local", // variant name
  output: {
    host: "mongodb"
  },
};

How to import values?

We can use values from other modules inside two sections:

  • output
  • docker

There is a function getVar. Input of the function is a string MODULE_NAME.VARIABLE_NAME. Output is a Promise.

Example of usage:

module.exports = {
  name: "local", // variant name
  requires: [
    "mongodb",
  ],
  docker: {
    services: {
		api: {
		  /* ....... */
		  environment: {
			DB_HOST: ({ getVar }) => getVar("mongodb.host")
		  }
		  /* ....... */
		}
	  }
  },
};

If some transformations to the value are required there are two options to implement them:

  • Promise .then
  • async/await

Important!

Don’t forget to add module into the requires section.

When to use dependencies?

There are two main reasons to add module as a dependency:

  • To be able to use exported variables (output) from another module.
  • To enable module and to include it into the final docker-compose file.

How to add custom logic?

All configurations are unique and sometimes there is a requirement to add custom logic into the configuration process. There are two options to do this:

  • Jobs
  • Custom functions

What are Jobs?

During build process LENV CLI runs some code which is grouped into the Jobs. Jobs are grouped into the Stages.

Out of the box there are two stages:

  • build
  • run

And two jobs:

  • docker-compose
  • docker-compose up One job in one stage.

LENV runs all jobs in one stage simultaneously. LENV will not continue to the next stage in case not all of the jobs from the current stage have Success state.

A few examples for jobs:

  • Check that code repository is cloned
  • Check that /etc/hosts contains required records
  • There is a dynamic configuration which requires user input or manual actions

How to add Stages?

LENV checks for stages inside lenv.config.js .

module.exports={
    runStages:[
        "prepare", 
        "build",
        "run"
    ]
}

In case file doesn’t exist the default fallback is:

module.exports={
    runStages:[
        "build",
        "run"
    ]
}

Note

It is possible to completely replace list of stages, but:

  • if build stage doesn’t exist LENV will not create docker-compose file
  • if run stage doesn’t exist LENV will not run containers automatically

How to add Jobs?

LENV looks for jobs at ./jobs/*.job.js

module.exports = {
  name: "check-sources", // job name
  stage: "prepare", // stage to run the job
  requires: [
	  /* 
		Array of dependencies. 
		Values are names of other modules.
		(optional)
	  */
  ],
  jobs: [
	  /* 
		Array of jobs required for this configuration. 
		Values are names of other modules.
		(optional)
	  */
  ],
  body: (params) => {
		// code to be executed inside JS function
	}
};

requires and jobs sections are identical to the same sections in modules. More information here

body is a simple JS function which receives object with parameters:

interface Params {
  /* 
      log, error and info allows to log message to the job's
      output with different level
	*/
  log: (msg: string) => void,
  error: (msg: string) => void,
  info: (msg: string) => void,

	/*
		adds log to the job's output and updates job status to
      'success' 
	*/
  success: (msg?: string) => void, 

	/*
		adds log to the job's output and updates job status to
      'failed' 
	*/
  fail:  (msg?: string) => void,

	/*
		updates job status to 'waiting'
      user has to enter string to continue 
	*/
  textInput: () => Promise<string>,

	/*
		array of all parameters passed to the job
	*/
	args: any[]

  /*
		get and set artifacts
  */
  getArtifacts: () => Record<string, any>,
  updateArtifacts: (data: Record<string, any>) => void,
}

Artifacts

Artifacts are persistent storage for the jobs. They may be used in modules similar to outputs with getArtifact function.

module.exports = {
  jobs: [
    "get-user-token",
    { target: "SERIVCE_NAME" }
  ],
  docker: {
    services: {
		api: {
		  /* ....... */
		  environment: {
			SERVICE_TOKEN: ({ getArtifact }) => getArtifact("get-user-token.artifactNameForTheToken")
		  }
		  /* ....... */
		}
	  }
  },
};

Job example

module.exports = {
  name: "get-token",
  stage: "prepare",
  body: async ({ textInput, updateArtifacts, success }) => {
		const token = await textInput();
		updateArtifacts({ token });
		success();
	}
};

More job examples here (TBD)

What are custom functions?

TBD

How does LENV resolve dependencies (requires, jobs)?

TBD