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

incremental-installer-maker

v0.0.4

Published

A module that helps create scripts that install non-npm dependencies for a project. Allows for smoothly and incremental adding dependencies during development

Downloads

3

Readme

incremental-installer-maker

A module that helps create scripts that install non-npm dependencies for a project. Allows for smoothly and incremental adding dependencies during development.

During development, multiple engineers on a project will need to add dependencies and configuration for the project - things like database schema changes, version upgrades, and additions to the technology stack. This library helps you create installers that can be run quickly on every pull from the repository to ensure all the correct configuration is in place. The installers created with this will be idempotent - meaning you can run them multiple times without bad things happening. The installer will only install pieces that have not yet been installed.

This way, engineers can easily be sure they have the correct setup, automatically.

What is it good for?

  • absolutely nothing!
  • Wait actually, its good for creating installers for one-time dependencies of a project (databases, caching systems, encryption packages, etc),
  • installers for automatically setting up and configuring development environments (git, nano, adding package repositories, configuring test users or test data, etc), for example installing on vagrant virtual machines,
  • or setting up shared environments (creating users, creating directory structures, setting up groups and permissions, etc)

Example

var makeInstaller = require('incremental-installer-maker')
var run = makeInstaller.run

makeInstaller('myInstaller.sh', {
    nodeVersions: ['0.10.25'], // indicates what node.js versions can be installed
    stateFile: function(args) {
        var installationLocation = args[1]
        return installationLocation+'/install.state'
    },

    scripts: [
        function(args) { // runs first, only if the state is 0
            run('yum install -y nano')
        },
        function(args) { // runs second, only if the state is less than 1
			run('yum install -y locate')
        },
        {  install: function(args) { // runs third, only if the 'check' function returns true
              run('yum install -y git')
           },
           check: function(args) { // checks to see if the install function of this object should be run
              if(isGitInstalled()) {
                  return false
              } else {
                  return true
              }
           }
        }
    ]

})

Install

npm install incremental-installer-maker

#Usage

Steps

  1. Write the script builder - Create a node.js script that requires 'incremental-installer-maker' (it must be that name, currently, for the resulting script to work)
  • any non-built-in required modules other than 'incremental-installer-maker' must be added to the files list.
  • the script should specify a stateFile location (via the options.stateFile function) where the state of the install can be saved on the machine
  1. Run the script builder - Running the node.js script you created will output a shell script at the filepath you specified
  • You must run the script in an environment where the commandstar, uuencode, cp -Rf, and rm -Rf are all available (so basically, a linux machine)
  1. Run the shell script on the target machine - The resulting shell script should be copied to the machine on which you want to run the installation. Run the shell script wherever is appropriate with whatever commandline arguments are appropriate.
  • The script can be copied via scp or even simply copy-pasted into a terminal editor and saved.
  • currently this has to be a machine that can execute bash scripts, but does not require the tar or uudecode commands to already be installed (they will be automatically installed)
  • The script only needs to be run with sudo if you expect it to install node.js, tar, or uudecode. Otherwise you shouldn't have to use sudo unless your installation script itself requires it.
  1. Add to the script builder - When you need to add more to the installation, add another function to the end of the options.scripts list and repeat steps 1-3
  • Running the installer will skip over the already-ran functions and only run the new one(s)

Note: The node install script runs in a temporary directory that is be deleted after the install process. If you want to access the directory that the shell script was run from, it is the parent directory of the directory in which the node script is run in (ie process.directory+"/..").

Vagrant note: this installer (like many many other things) won't work in a linux-vagrant shared directory in a windows host environment. Run it in a location outside the shared directory

node API

var makeInstaller = require('incremental-installer-maker')

makeInstaller(filepath, options) - creates an installer shell script

  • filepath - The shell script is created in this location
  • options - A set of options for how the installer is created. Has the following properties:
  • nodeVersions - An array of acceptable node.js versions, each in the format 'X.XX.XX' (e.g. '0.10.25'). Currently the version of node.js is not checked.
  • stateFile(args) - A function that returns the path to where the state file will be stored
    • The full path to the state-file location will be created if it doesn't already exist.
    • The function takes in the commandline arguments to the shell script as its only parameter. args comes directly from process.argv of the top-level script)
  • files - A list of files and folders the installation script will need to run. These files will be embedded in the shell script. They can be accessed from the script as if the files were in their current relative locations.
  • scripts - A list of functions to run in order. In maintaining this installer script, it is important that the order of these functions remains the same, and new functions are only added at the end. This is because the installation state of the machine is recorded as the number of functions run. If the order is changed, the next time the installer is run on a partially installed machine, already-ran functions may run, and necessary functions may not run.
    • Each element in the array can either be:
      • A function. In this case, the function is run if the stateFile contains a number greater-than-or-equal-to the index of the element. The function takes in the commandline arguments to the shell script as its only parameter.
        • If a function returns a future (see async-future), the next function will wait until that future resolves before running the next function.
      • An object with the following properties:
        • install(args) - A function.
          • If the function returns a future (see async-future), the next function will wait until that future resolves before running the next function.
        • check(args) - A function that returns Future(true) (see async-future) if the install function of the object should be run.
        • Both these functions take in the commandline arguments to the shell script as its only parameter.

makeInstaller.run(command, printToConsole) - runs a system command, displays the output on the console, and returns when the command is done. Throws an exception if the command returns an exit code other than 0.

  • command - a string of the command to run
  • printToConsole - (Optional- default true) If true, output is displayed to the console. If false, its not.

makeInstaller.Future - a reference to async-future for convenience (e.g. to use in options.scripts[n].check above)

Recommendations

I recommend using node-fibers for concurrency. This library uses async-future because requiring multiple versions of node-fibers isn't safe (causes bugs). But you can

Tested OSes

  • Centos 6.5

Todo

  • separate the shell script creation from the incremental node.js function runner into two different modules, and use each to remake this one
  • have a way for files to be renamed/re-pathed in the files list
  • Test on various operating systems
  • if node.js exists, check to make sure the version is one of the listed nodeVersions
  • Improve the way incremental-installer-maker creates the archive:
    • Either use this for the original tarring instead of creating a temporary folder: http://stackoverflow.com/questions/21790843/how-to-rename-files-you-put-into-a-tar-archive-using-linux-tar/21795845
    • or use tar-stream and zlip to create the archive (best solution, but more complex)
      • You can use tar-fs to pack directories!
  • use browserify to package together the main script, so the user doesn't have to manually specify which dependencies to package up
  • Make this work for windows

How to Contribute!

Anything helps:

  • Creating issues (aka tickets/bugs/etc). Please feel free to use issues to report bugs, request features, and discuss changes
  • Updating the documentation: ie this readme file. Be bold! Help create amazing documentation!
  • Submitting pull requests.

How to submit pull requests:

  1. Please create an issue and get my input before spending too much time creating a feature. Work with me to ensure your feature or addition is optimal and fits with the purpose of the project.
  2. Fork the repository
  3. clone your forked repo onto your machine and run npm install at its root
  4. If you're gonna work on multiple separate things, its best to create a separate branch for each of them
  5. edit!
  6. If it's a code change, please add to the unit tests (at test/protoTest.js) to verify that your change
  7. When you're done, run the test and test the resulting installer on a fresh linux installation (try vagrant) to make sure things still work right
  • The resulting installer ("mytestinstaller.sh") should print out all the files in the embedded package, then should print 'one', 'checking two', 'Running two. ...' and print the command line arguments, 'three', then 'four' the first time
  • Subsequent runs should not print out 'one', 'three', or 'four' but should print out the rest.
  • I recommend using vagrant snapshots to test your work
  1. Commit and push your changes
  2. Submit a pull request: https://help.github.com/articles/creating-a-pull-request

Change Log

  • 0.0.1 - first!

License

Released under the MIT license: http://opensource.org/licenses/MIT