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

water-drop

v2.0.1

Published

💧 very easy to use multi-language scaffolding/boilerplate tool for creating code for your existing projects

Downloads

13

Readme

water-drop Build Status

💧 very easy to use multi-language scaffolding/boilerplate tool for creating code for your existing projects

Idea

A growing big project might eventually require contributors to write different boilerplates/code templates to be used as a starting point for new modules. Most often those templates are files to copy-paste followed by few variable renamings to reflect new module's name. water-drop is a scaffolding/boilerplate tool which allows to create new code based on the provided existing templates written by anyone.

This tool was created keeping in mind the following conditions:

  1. It has to work for multiple languages (Go, JavaScript, Python, etc).
  2. It has to be easy to use. Nobody should go through pages of documentation or reading many lines of code in order to understand how this tool works.
  3. It has to be easy to setup new templates to be used by everyone. (For this project Handlebars was picked as the main templating engine for its simplicity. You can read more on Handlebars templating here)

Installation

Global installation (suggested)

$ npm i -g water-drop
$ water-drop

Local installation

$ npm install water-drop
$ node_modules/.bin/water-drop

Usage

USAGE
  $ water-drop <command>

where <command> is one of:
  init, list, template, create, uninit

water-drop <command> -i     quick help on <command>

EXAMPLES
  $ water-drop init

  $ water-drop create myNewShinyModule -t exampleModule -p path/within/my/project -v

  $ water-drop list

  $ water-drop template mySecondShinyModule

  $ water-drop template moduleToRemove -d

  $ water-drop uninit

Template Creation Example

  • Let's imagine our team need to create lots of new modules which have the same comment about MIT license.
  • Let's imagine we need to include a constant file inside our new module.

Step 1 (Init water-drop in the folder with future templates)

$ cd /my/amazing/project/

$ water-drop init

Step 2 (Bootstrap new template)

$ water-drop template licensedCode

Step 3 (Modify auto-generated config)

modify water-drop-templates/licensedCode/config.json file

{
    "steps": [
        { "cmd": "mkdir", "path": "{{myProjectPath}}/{{_mPath}}" },
        {
            "cmd": "cpf",
            "what": "licensedFile.js",
            "to": "{{myProjectPath}}/{{_mPath}}/{{lcase _mName}}.js"
        },
        {
            "cmd": "cp",
            "what": "constants.js",
            "to": "{{myProjectPath}}/{{_mPath}}/constants.js"
        }
    ],

    "vars": {
        "myProjectPath": "./",
        "author": "Alexey Novak"
    }
}

Step 4 (Add template files)

Create file water-drop-template/licensedCode/__files/licensedFile.js

// MIT © {{author}}

import * from './constants.js';

function {{ucase _mName}}() {

}

export default {{ucase _mName}};

Create file water-drop-template/licensedCode/__files/constants.js

const config = {
    VERSION: '1.0.0',

    // place your config files here
};

export default config;

Step 5 (Run water-drop to generate new module based on the template)

Run $ water-drop create NewModule -t licensedCode -p /ui/utils -v

New folder ui/utils/ should be generated in the same folder as water-drop.json config file.

With new files ui/utils/constants.js and ui/utils/newModule.js

Available 3 Config Steps

mkdir

{ "cmd": "mkdir", "path": "some/folder/structure" }

| Property | Description | Can Use Templating :---|:---|:--- | path | New folder path. The whole folder tree will be created if does not exist. Path is relative to the folder where water-drop command is executed. | Yes |

cp

{
    "cmd": "cp",
    "what": "fileTemplate.txt",
    "to": "some/folder/structure/file.txt"
},

| Property | Description | Can Use Templating :---|:---|:--- | what | Path to the file within water-drop-template/<template_type>/ to be used for a file copy operation. | No | | to | Path to where file will be copied over. Path is relative to the folder where water-drop command is executed. | Yes |

cpf

{
    "cmd": "cpf",
    "what": "fileTemplate.txt",
    "to": "some/folder/structure/file.txt"
},

| Property | Description | Can Use Templating :---|:---|:--- | what | Path to the file within water-drop-template/<template_type>/ to be used for a file copy operation. water-drop will apply templating to the content of the file to make changes on its content. | No | | to | Path to where file will be copied over. Path is relative to the folder where water-drop command is executed. | Yes |

Available (extra) Handlebar Helpers

| Helper | Description | Example :---|:---|:--- | ucase | Uppercases first character | myModule -> MyModule | | lcase | Lowercases first character | MyModule -> myModule | | ucaseall | Uppercases the whole string | myModule -> MYMODULE | | lcaseall | Lowercases the whole string | MyModule -> mymodule | | u_case_all | Uppercases the whole string and also adds _ character between each uppercase character | MyModule -> MY_MODULE | | l_case_all | Lowercases the whole string and also adds _ character between each uppercase character | MyModule -> my_module |

Context

Handlebars uses context object for templating function. Context for each template consist of the following variables:

  • All variables within vars property of the config withijn water-drop.json file
  • All variables within vars property of the template configuration within water-drop.json file
  • _mType - template type used to create new module (passed through CLI)
  • _mName - new module name (passed through CLI)
  • _mPath - path to the new module (passed through CLI)

Also some specific water-drop tool configuration which most of the times you do not need to modify:

  • _tFolder - location of the folder with template files
  • _tOpenTag - special open tag to be used for cpf command
  • _tCloseTag - special close tag to be used for cpf command

Limitation

It is very important to remember that Handlebars keeps {{ and }} reserved for its template logic. Use <%% and %%> respectively in case when a template needs to preserve those tags.

Example:

style=<%% weight: 50px, height: 50px %%>

will be converted to

style={{ weight: 50px, height: 50px }}

Also you might face a problem when trying to replace a value within the object. Example:

// some of my react code

object={this.props.{{lcase _mName}}}

// this would fail since Handlebars would not like those closing }}}

You will need to re-write it as

object={this.props.{{lcase _mName}} }

Future Improvements

  1. There are no tests present for this project yet.
  2. Step command which will be able to inject a line of code into another existing file "in a smart way".
  3. Roll-back mechanism for any auto-generated content in case when there is an error during execution.
  4. Ability to pre-parse and detect issues within the config prior steps execution.
  5. More detailed logging to identify an exact problem when there is a failure.

License

MIT license; see LICENSE.

(c) 2017 by Alexey Novak