ievv buildstatic — A static file builder (less, coffee, …)

The ievv buildstatic command is a fairly full featured general purpose static asset builder that solves the same general tasks as Grunt and Gulp, but in a very Django friendly and pythonic way.

You extend the system with object oriented python programming, and you configure the system using python classes.

Getting started

First of all, make sure you have the following in your INSTALLED_APPS setting:

'ievv_opensource.ievvtasks_common',

ievv buildstatic assumes you have the sources for your static files in the staticsources/<appname>/ directory within each Django app.

For this example, we will assume your Django app is named myapp, and that it is located in myproject/myapp/.

First you need to create the staticsources directory:

$ mkdir -p myproject/myapp/staticsource/myapp/

Setup building of LESS files

To kick things off, we will configure building of LESS sources into CSS. Create myproject/myapp/staticsource/myapp/styles/theme.less, and add some styles:

.myclass {
    color: red;
}

Now we need to add configurations to settings.py for building this less file. Add the following Django setting:

from ievv_opensource.utils import ievvbuildstatic
IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='myapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.lessbuild.Plugin(sourcefile='theme.less'),
        ]
    ),
)

Now run the following command in your terminal:

$ ievv buildstatic

This should create myproject/myapp/static/myapp/1.0.0/styles/theme.css.

Add media files

You will probably need some media files for your styles (fonts, images, ect.). First, put an image in myproject/myapp/staticsource/myapp/media/images/, then add the following to the plugins list in the IEVVTASKS_BUILDSTATIC_APPS Django setting:

ievvbuildstatic.mediacopy.Plugin()

Run:

$ ievv buildstatic

This should add your image to myproject/myapp/static/myapp/1.0.0/media/images/.

Watch for changes

Re-running ievv buildstatic each time you make changes is tedious. You can watch for changes using:

$ ievv buildstatic --watch

Advanced topics

Using multiple apps

Using multiple apps is easy. You just add another ievv_opensource.utils.ievvbuildstatic.config.App to the IEVVTASKS_BUILDSTATIC_APPS setting:

from ievv_opensource.utils import ievvbuildstatic
IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='myapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.lessbuild.Plugin(sourcefile='theme.less'),
        ]
    ),
    ievvbuildstatic.config.App(
        appname='anotherapp',
        version='2.3.4',
        plugins=[
            ievvbuildstatic.lessbuild.Plugin(sourcefile='theme.less'),
        ]
    ),
)

NPM packages and ievv buildstatic

How ievv buildstatic interracts with package.json

Many of the ievv buildstatic plugins install their own npm packages, so they will modify package.json if needed. Most plugins do not specify a specific version of a package, but they will not override your versions if you specify them in package.json.

Yarn or NPM?

ievv buildstatic uses yarn by default, but you can configure it to use npm with the following settings:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='myapp',
        version='1.0.0',
        installers_config={
            'npm': {
                'installer_class': ievvbuildstatic.installers.npm.NpmInstaller
            }
        },
        plugins=[
            # ...
        ]
    )
)

Working with npm packages guide

Note

You can create your package.json manually, using npm init/yarn init. If you do not create a package.json, ievv buildstatic will make one for you if you use any plugins that require npm packages.

You work with npm/yarn just like you would for any javascript project. The package.json file must be in:

<django appname>/staticsources/<django appname>/package.json

So you should be in <django appname>/staticsources/<django appname>/ when running npm or yarn commands.

Example

  1. Create the staticsources/myapp/ directory in your django app. Replace myapp with your django app name.

  2. Create staticsources/myapp/scripts/javascript/app.js.

  3. Configure ievv buildstatic with the following in your django settings:

    IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
        ievvbuildstatic.config.App(
            appname='myapp',
            version='1.0.0',
            plugins=[
                ievvbuildstatic.browserify_jsbuild.Plugin(
                    sourcefile='app.js',
                    destinationfile='app.js',
                ),
            ]
        )
    )
    
  4. Run ievv buildstatic to build this app. This will create a package.json file.

  5. Lets add momentjs as a dependency:

    $ cd /path/to/myapp/staticsources/myapp/
    $ yarn add momentjs
    
  6. … and so on …

Plugins

Overview

pluginbase.Plugin([group]) Base class for all plugins in ievvbuildstatic.
cssbuildbaseplugin.AbstractPlugin([lint, …]) Base class for builders that produce CSS.
sassbuild.Plugin(sourcefile[, sourcefolder, …]) SASS build plugin — builds .scss files into css, and supports watching for changes.
lessbuild.Plugin(sourcefile[, sourcefolder, …]) LESS build plugin — builds .less files into css, and supports watching for changes.
mediacopy.Plugin([sourcefolder, …]) Media copy plugin — copies media files from staticsources into the static directory, and supports watching for file changes.
bowerinstall.Plugin(packages, **kwargs) Bower install plugin — installs bower packages.
npminstall.Plugin(packages, **kwargs) NPM install plugin — installs NPM packages.
browserify_jsbuild.Plugin(sourcefile, …[, …]) Browserify javascript bundler plugin.
browserify_babelbuild.Plugin([…]) Browserify javascript babel build plugin.
browserify_reactjsbuild.Plugin([…]) Browserify javascript babel build plugin.
autosetup_jsdoc.Plugin([group]) Autosetup jsdoc config and npm script.
autosetup_esdoc.Plugin([title]) Autosetup esdoc config and npm script.
npmrun.Plugin(script[, script_args]) Run a script from package.json (I.E.: npm run <something>.
npmrun_jsbuild.Plugin([extra_import_paths]) Webpack builder plugin.
run_jstests.Plugin(**kwargs) Run javascript tests by running npm test if the package.json has a "test" entry in "scripts".

Details

class ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin(group=None)[source]

Bases: ievv_opensource.utils.logmixin.LogMixin, ievv_opensource.utils.ievvbuildstatic.options_mixin.OptionsMixin

Base class for all plugins in ievvbuildstatic.

Parameters:group

The group of the plugin. Defaults to default_group. If this is None, the plugin can not be skipped when building an app.

You can use any value for groups, but these groups are convenient because the ievv buildstatic command has command line options that makes it easier to skip them:

  • "css": Should be used for plugins that build css. Skipped when running ievv buildstatic with --skip-css.
  • "js": Should be used for plugins that build javascript. Skipped when running ievv buildstatic with --skip-js.
  • "jstest": Should be used for plugins that run automatic tests for javascript code. Should also be used for tests in languages that compile to javascript such as TypeScript and CoffeeScript. Skipped when running ievv buildstatic with --skip-jstests or --skip-js.
  • "slow-jstest": Should be used instead of "jstest" for very slow tests. Skipped when running ievv buildstatic with --skip-slow-jstests, --skip-jstests or --skip-js.
name = None

The name of the plugin.

default_group = None

The default group of the plugin The default value for the group kwarg for __init__`().

install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
post_install()[source]

Called just like install, but after all apps has finished installing.

run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

watch()[source]

Configure watching for this plugin.

You normally do not override this method, instead you override get_watch_folders() and get_watch_regexes().

Returns:
A ievv_opensource.utils.ievvbuildstatic.watcher.WatchConfig
object if you want to watch for changes in this plugin, or None if you do not want to watch for changes.
Return type:WatchdogWatchConfig
get_watch_regexes()[source]

Get the regex used when watching for changes to files.

Defaults to a regex matching any files.

get_watch_folders()[source]

Get folders to watch for changes when using ievv buildstatic --watch.

Defaults to an empty list, which means that no watching thread is started for the plugin.

The folder paths must be absolute, so in most cases you should use self.app.get_source_path() (see ievv_opensource.utils.ievvbuildstatic.config.App#get_source_path()) to turn user provided relative folder names into absolute paths.

get_logger_name()[source]

Get the name of the logger.

make_temporary_build_directory()[source]

Make a temporary directory that you can use for building something.

Returns:The absolute path of the new directory.
Return type:str
register_temporary_file_or_directory(absolute_path)[source]

Register a temporary file or directory.

This will automatically be cleaned after run() is finished (even if it crashes) if the app uses keep_temporary_files=False (the default).

exception ievv_opensource.utils.ievvbuildstatic.cssbuildbaseplugin.CssBuildException[source]

Bases: Exception

Raised when AbstractPlugin.build_css() fails.

class ievv_opensource.utils.ievvbuildstatic.cssbuildbaseplugin.AbstractPlugin(lint=True, lintrules=None, lintrules_overrides=None, autoprefix=True, browserslist='> 5%', **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Base class for builders that produce CSS.

Parameters:
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
build_css(temporary_directory)[source]

Override this method and implement the code to build the css.

get_destinationfile_path()[source]

Override this method and return the absolute path of the destination/output css file.

get_all_source_file_paths()[source]

Used for utilities like the linter to get a list of all source files.

You must override this in subclasses.

run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

class ievv_opensource.utils.ievvbuildstatic.sassbuild.Plugin(sourcefile, sourcefolder='styles', destinationfolder=None, other_sourcefolders=None, sass_include_paths=None, sass_variables=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.cssbuildbaseplugin.AbstractPlugin

SASS build plugin — builds .scss files into css, and supports watching for changes.

By default, we assume sassc is available on PATH, but you can override the path to the sassc executable by setting the IEVVTASKS_BUILDSTATIC_SASSC_EXECUTABLE environment variable.

Examples

Very simple example where the source file is in demoapp/staticsources/styles/theme.scss:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.sassbuild.Plugin(sourcefile='theme.scss'),
        ]
    )
)

A more complex example that builds a django-cradmin theme where sources are split in multiple directories, and the bower install directory is on the scss path (the example also uses ievv_opensource.utils.ievvbuildstatic.bowerinstall.Plugin):

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.bowerinstall.Plugin(
                packages={
                    'bootstrap': '~3.1.1'
                }
            ),
            ievvbuildstatic.sassbuild.Plugin(
                sourcefolder='styles/cradmin_theme_demoapp',
                sourcefile='theme.scss',
                other_sourcefolders=[
                    'styles/cradmin_base',
                    'styles/cradmin_theme_default',
                ],
                sass_include_paths=[
                    'bower_components',
                ]
            )
        ]
    )
)
Parameters:
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
get_destinationfile_path()[source]

Override this method and return the absolute path of the destination/output css file.

build_css(temporary_directory)[source]

Override this method and implement the code to build the css.

get_watch_folders()[source]

We only watch the folder where the scss sources are located, so this returns the absolute path of the sourcefolder.

get_watch_regexes()[source]

Get the regex used when watching for changes to files.

Defaults to a regex matching any files.

get_all_source_file_paths()[source]

Used for utilities like the linter to get a list of all source files.

You must override this in subclasses.

class ievv_opensource.utils.ievvbuildstatic.lessbuild.Plugin(sourcefile, sourcefolder='styles', other_sourcefolders=None, less_include_paths=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

LESS build plugin — builds .less files into css, and supports watching for changes.

Examples

Very simple example where the source file is in demoapp/staticsources/styles/theme.less:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.lessbuild.Plugin(sourcefile='theme.less'),
        ]
    )
)

A more complex example that builds a django-cradmin theme where sources are split in multiple directories, and the bower install directory is on the less path (the example also uses ievv_opensource.utils.ievvbuildstatic.bowerinstall.Plugin):

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.bowerinstall.Plugin(
                packages={
                    'bootstrap': '~3.1.1'
                }
            ),
            ievvbuildstatic.lessbuild.Plugin(
                sourcefolder='styles/cradmin_theme_demoapp',
                sourcefile='theme.less',
                other_sourcefolders=[
                    'styles/cradmin_base',
                    'styles/cradmin_theme_default',
                ],
                less_include_paths=[
                    'bower_components',
                ]
            )
        ]
    )
)
Parameters:
  • sourcefile – Main source file (the one including all other less files) relative to sourcefolder.
  • sourcefolder – The folder where sourcefile is located relative to the source folder of the App.
  • less_include_paths – Less include paths as a list. Paths are relative to the source folder of the App.
  • **kwargs – Kwargs for ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

get_watch_folders()[source]

We only watch the folder where the less sources are located, so this returns the absolute path of the sourcefolder.

get_watch_regexes()[source]

Get the regex used when watching for changes to files.

Defaults to a regex matching any files.

class ievv_opensource.utils.ievvbuildstatic.mediacopy.Plugin(sourcefolder='media', destinationfolder=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin

Media copy plugin — copies media files from staticsources into the static directory, and supports watching for file changes.

Examples

Copy all files in demoapp/staticsources/demoapp/media/ into demoapp/static/1.0.0/media/:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.mediacopy.Plugin(),
        ]
    )
)

Using a different source folder. This will copy all files in demoapp/staticsources/demoapp/assets/ into demoapp/static/1.0.0/assets/:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.mediacopy.Plugin(sourcefolder="assets"),
        ]
    )
)
Parameters:
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

get_watch_folders()[source]

We only watch the folder where the less sources are located, so this returns the absolute path of the sourcefolder.

class ievv_opensource.utils.ievvbuildstatic.bowerinstall.Plugin(packages, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Bower install plugin — installs bower packages.

The packages are installed when ievv buildstatic starts up. The plugin creates a bower.json file, and runs bower install using the created bower.json-file.

You will most likely want to add bower.json and bower_components to your VCS ignore file.

Examples

Install bootstrap 3.1.1 and angularjs 1.4.1:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.bowerinstall.Plugin(
                packages={
                    'bootstrap': '~3.1.1',
                    'angular': '~1.4.1'
                }
            ),
        ]
    )
)
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

class ievv_opensource.utils.ievvbuildstatic.npminstall.Plugin(packages, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

NPM install plugin — installs NPM packages.

The packages are installed when ievv buildstatic starts up.

Examples

Install uniq and momentjs packages:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.npminstall.Plugin(
                packages={
                    'uniq': None,
                    'momentjs': None
                }
            ),
        ]
    )
)

You can specify a version instead of None if you do not want to install the latest version.

install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
class ievv_opensource.utils.ievvbuildstatic.browserify_jsbuild.Plugin(sourcefile, destinationfile, sourcefolder='scripts/javascript', destinationfolder='scripts', extra_watchfolders=None, extra_import_paths=None, sourcemap=True, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Browserify javascript bundler plugin.

Examples

Simple example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_jsbuild.Plugin(
                sourcefile='app.js',
                destinationfile='app.js',
            ),
        ]
    )
)

Custom source folder example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_jsbuild.Plugin(
                sourcefolder=os.path.join('scripts', 'javascript', 'api'),
                sourcefile='api.js',
                destinationfile='api.js',
            ),
        ]
    )
)
Parameters:
  • sourcefile – The source file relative to sourcefolder.
  • destinationfile – Path to destination file relative to destinationfolder.
  • sourcefolder – The folder where sourcefiles is located relative to the source folder of the App. Defaults to scripts/javascript.
  • destinationfolder – The folder where destinationfile is located relative to the destination folder of the App. Defaults to scripts/.
  • extra_watchfolders – List of extra folders to watch for changes. Relative to the source folder of the App.
  • **kwargs – Kwargs for ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.
install()[source]

Installs the browserify NPM package.

The package is installed with no version specified, so you probably want to freeze the version using the ievv_opensource.utils.ievvbuildstatic.npminstall.Plugin plugin.

get_browserify_extra_args()[source]

Get extra browserify args.

Override this in subclasses to add transforms and such.

make_browserify_args()[source]

Make browserify args list.

Adds the following in the listed order:

Should normally not be extended. Extend get_browserify_extra_args() instead.

post_run()[source]

Called at the start of run(), after the initial command start logmessage, but before any other code is executed.

Does nothing by default, but subclasses can hook in configuration code here if they need to generate config files, perform validation of file structure, etc.

run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

get_watch_folders()[source]

We only watch the folder where the javascript is located, so this returns the absolute path of the sourcefolder.

get_watch_extensions()[source]

Returns a list of the extensions to watch for in watch mode.

Defaults to ['js'].

Unless you have complex needs, it is probably easier to override this than overriding get_watch_regexes().

get_watch_regexes()[source]

Get the regex used when watching for changes to files.

Defaults to a regex matching any files.

class ievv_opensource.utils.ievvbuildstatic.browserify_babelbuild.Plugin(echmascript_version='es2015', autocreate_babelrc=True, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.browserify_jsbuild.Plugin

Browserify javascript babel build plugin.

Examples

Simple example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_babelbuild.Plugin(
                sourcefile='app.js',
                destinationfile='app.js',
            ),
        ]
    )
)

Custom source folder example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_babelbuild.Plugin(
                sourcefolder=os.path.join('scripts', 'javascript', 'api'),
                sourcefile='api.js',
                destinationfile='api.js',
            ),
        ]
    )
)
Parameters:
install()[source]

Installs the babelify and babel-preset-<echmascript_version kwarg> NPM packages in addition to the packages installed by ievv_opensource.utils.ievvbuildstatic.browserify_jsbuild.Plugin.install().

The packages are installed with no version specified, so you probably want to freeze the versions using the ievv_opensource.utils.ievvbuildstatic.npminstall.Plugin plugin.

get_babel_presets()[source]

Get a list of babelify presets.

This is the presets that go into <HERE> in babelify -t [ babelify --presets [ <HERE> ] ].

Defaults to ["<the echmascript_version kwarg>"].

get_browserify_extra_args()[source]

Get extra browserify args.

Override this in subclasses to add transforms and such.

post_run()[source]

Called at the start of run(), after the initial command start logmessage, but before any other code is executed.

Does nothing by default, but subclasses can hook in configuration code here if they need to generate config files, perform validation of file structure, etc.

class ievv_opensource.utils.ievvbuildstatic.browserify_reactjsbuild.Plugin(echmascript_version='es2015', autocreate_babelrc=True, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.browserify_babelbuild.Plugin

Browserify javascript babel build plugin.

Examples

Simple example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_reactjsbuild.Plugin(
                sourcefile='app.js',
                destinationfile='app.js',
            ),
        ]
    )
)

Custom source folder example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.browserify_reactjsbuild.Plugin(
                sourcefolder=os.path.join('scripts', 'javascript', 'api'),
                sourcefile='api.js',
                destinationfile='api.js',
            ),
        ]
    )
)
Parameters:
install()[source]

Installs the babel-preset-react NPM package in addition to the packages installed by ievv_opensource.utils.ievvbuildstatic.browserify_babelbuild.Plugin.install().

The packages are installed with no version specified, so you probably want to freeze the versions using the ievv_opensource.utils.ievvbuildstatic.npminstall.Plugin plugin.

get_babel_presets()[source]

Adds react to the babelify presets added by ievv_opensource.utils.ievvbuildstatic.browserify_babelbuild.Plugin.get_babel_presets().

get_watch_extensions()[source]

Returns a list of the extensions to watch for in watch mode.

Defaults to ['js'].

Unless you have complex needs, it is probably easier to override this than overriding get_watch_regexes().

class ievv_opensource.utils.ievvbuildstatic.autosetup_jsdoc.Plugin(group=None)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Autosetup jsdoc config and npm script.

Examples

It is really simple to use:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.autosetup_jsdoc.Plugin(),
        ]
    )
)

If you need to adjust the config, simply setup your own build-docs script in package.json instead of using this plugin.

Parameters:group

The group of the plugin. Defaults to default_group. If this is None, the plugin can not be skipped when building an app.

You can use any value for groups, but these groups are convenient because the ievv buildstatic command has command line options that makes it easier to skip them:

  • "css": Should be used for plugins that build css. Skipped when running ievv buildstatic with --skip-css.
  • "js": Should be used for plugins that build javascript. Skipped when running ievv buildstatic with --skip-js.
  • "jstest": Should be used for plugins that run automatic tests for javascript code. Should also be used for tests in languages that compile to javascript such as TypeScript and CoffeeScript. Skipped when running ievv buildstatic with --skip-jstests or --skip-js.
  • "slow-jstest": Should be used instead of "jstest" for very slow tests. Skipped when running ievv buildstatic with --skip-slow-jstests, --skip-jstests or --skip-js.
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

class ievv_opensource.utils.ievvbuildstatic.autosetup_esdoc.Plugin(title=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Autosetup esdoc config and npm script.

The plugin creates the esdoc.json config file automatically. It also creates a directory named esdoc and a file named index.md within that directory. That file is the frontpage of your docs, and you should edit it and provide some information about the app/library.

If you want to add a manual “page” to your docs, you do that by adding files and/or directories to the esdoc/manual/ directory (relative to the source directory - the directory with package.json). Esdoc has a specific set of manual sections that you can add:

  • asset
  • overview
  • installation
  • usage
  • tutorial
  • configuration
  • example
  • faq
  • changelog

This plugin automatically adds these to the esdoc.json with the following rules:

  • Does esdoc/manual/<section>.md exist? Add that as the first entry in the manual.<section> list.
  • Does esdoc/manual/<section>/ exist? Add all .md files in that directory to the manual.<section> list in sorted order.

Examples

It is really simple to use:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.autosetup_esdoc.Plugin(),
        ]
    )
)

Lets add a tutorial! First create esdoc/manual/tutorial.md and run ievv buildstatic. That file should end up in esdoc.json and if you build the docs you should get a “manual” link at the top of the manual. If your tutorial grows, simply create the esdoc/manual/tutorial/ directory and add markdown files to it. The files are sorted by filename and the output in the docs is still a single file. The esdoc/manual/tutorial.md file will still end up first if it is present. You can choose if you want to use the esdoc/manual/tutorial.md, the esdoc/manual/tutorial/ directory or both. The tutorial example works for all the manual sections documented above.

Parameters:
install()[source]

Installs the esdoc and esdoc-importpath-plugin npm packages as dev dependencies.

run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

class ievv_opensource.utils.ievvbuildstatic.npmrun.Plugin(script, script_args=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Run a script from package.json (I.E.: npm run <something>.

Examples

Lets say you have the following in your package.json:

{
  "scripts": {
    "myscript": "echo 'hello'"
  }
}

You can then make this script run with:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.npmrun.Plugin(script='myscript'),
        ]
    )
)
Parameters:
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

class ievv_opensource.utils.ievvbuildstatic.npmrun_jsbuild.Plugin(extra_import_paths=None, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Webpack builder plugin.

Examples

Simple example:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.npmrun_jsbuild.Plugin(),
        ]
    )
)

Webpack example:

Install webpack:

$ yarn add webpack

Add the following to your package.json:

    {
        ...
        "scripts": {
            ...
            "jsbuild": "webpack --config webpack.config.js",
            "jsbuild-production": "webpack --config webpack.config.js -p"
            ...
        }
        ...
    }

Create a webpack.config.js with something like this:

    let path = require('path');

    const isProduction = process.env.IEVV_BUILDSTATIC_MODE == 'production';
    const appconfig = require("./ievv_buildstatic.appconfig.json");
    console.log(isProduction);
    console.log(appconfig);

    let webpackConfig = {
        entry: './scripts/javascript/ievv_jsbase/ievv_jsbase_core.js',
        output: {
            filename: 'ievv_jsbase_core.js',
            path: path.resolve(appconfig.destinationfolder, 'scripts')
        },
        module: {
            loaders: [
                {
                    test: /.jsx?$/,
                    loader: 'babel-loader',
                    // exclude: /node_modules/
                    include: [
                        path.resolve(__dirname, "scripts/javascript/ievv_jsbase"),
                    ]
                }
            ]
        }
    };

    if(isProduction) {
        webpackConfig.devtool = 'source-map';
    } else {
        webpackConfig.devtool = 'cheap-module-eval-source-map';
        webpackConfig.output.pathinfo = true;
    }

    module.exports = webpackConfig;
install()[source]

Install any packages required for this plugin.

Should use ievv_opensource.utils.ievvbuild.config.App.get_installer().

Examples

Install an npm package:

def install(self):
    self.app.get_installer('npm').install(
        'somepackage')
    self.app.get_installer('npm').install(
        'otherpackage', version='~1.0.0')
run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

watch()[source]

Configure watching for this plugin.

You normally do not override this method, instead you override get_watch_folders() and get_watch_regexes().

Returns:
A ievv_opensource.utils.ievvbuildstatic.watcher.WatchConfig
object if you want to watch for changes in this plugin, or None if you do not want to watch for changes.
Return type:WatchdogWatchConfig
class ievv_opensource.utils.ievvbuildstatic.run_jstests.Plugin(**kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin

Run javascript tests by running npm test if the package.json has a "test" entry in "scripts".

Examples

Lets say you have the following in your package.json:

{
  "scripts": {
    "test": "jest"
  }
}

You can then make jest run at startup (not on watch change) with:

IEVVTASKS_BUILDSTATIC_APPS = ievvbuildstatic.config.Apps(
    ievvbuildstatic.config.App(
        appname='demoapp',
        version='1.0.0',
        plugins=[
            ievvbuildstatic.run_jstests.Plugin(),
        ]
    )
)

If you have a NPM script named "test-debug", that will be run instead of "test" when loglevel is DEBUG. This means that if you add something like this to your package.json:

{
  "scripts": {
    "test": "jest",
    "test-debug": "jest --debug"
  }
}

and run ievv buildstatic --debug, jest --debug would be run instead of jest.

Parameters:**kwargs – Kwargs for ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.
log_shell_command_stderr(line)[source]

Called by run_shell_command() each time the shell command outputs anything to stderr.

run()[source]

Run the plugin. Put the code executed by the plugin each time files change here.

Apps and App

Overview

App(appname, version, plugins[, …]) Configures how ievv buildstatic should build the static files for a Django app.
Apps(*apps, **kwargs) Basically a list around App objects.

Details

class ievv_opensource.utils.ievvbuildstatic.config.App(appname, version, plugins, sourcefolder='staticsources', destinationfolder='static', keep_temporary_files=False, installers_config=None, docbuilder_classes=None, default_skipgroups=None, default_includegroups=None)[source]

Bases: ievv_opensource.utils.logmixin.LogMixin

Configures how ievv buildstatic should build the static files for a Django app.

Parameters:
  • appname – Django app label (I.E.: myproject.myapp).
  • plugins – Zero or more ievv_opensource.utils.ievvbuild.pluginbase.Plugin objects.
  • sourcefolder – The folder relative to the app root folder where static sources (I.E.: less, coffescript, … sources) are located. Defaults to staticsources.
add_plugin(plugin)[source]

Add a ievv_opensource.utils.ievvbuildstatic.lessbuild.Plugin.

run(skipgroups=None, includegroups=None)[source]

Run ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.run() for all plugins within the app.

install(skipgroups=None, includegroups=None)[source]

Run ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.install() for all plugins within the app.

get_app_config()[source]

Get the AppConfig for the Django app.

get_appfolder()[source]

Get the absolute path to the Django app root folder.

get_app_path(apprelative_path)[source]

Returns the path to the directory joined with the given apprelative_path.

get_source_path(*path)[source]

Returns the absolute path to a folder within the source folder of this app or another app.

Examples

Get the source path for a coffeescript file:

self.get_source_path('mylib', 'app.coffee')

Getting the path of a source file within another app using a ievv_opensource.utils.ievvbuildstatic.filepath.SourcePath object (a subclass of ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface) as the path:

self.get_source_path(
    ievvbuildstatic.filepath.SourcePath('myotherapp', 'scripts', 'typescript', 'app.ts'))
Parameters:*path – Zero or more strings to specify a path relative to the source folder of this app - same format as os.path.join(). A single ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface object to specify an absolute path.
get_destination_path(*path, **kwargs)[source]

Returns the absolute path to a folder within the destination folder of this app or another app.

Examples

Get the destination path for a coffeescript file - extension is changed from .coffee to .js:

self.get_destination_path('mylib', 'app.coffee', new_extension='.js')

Getting the path of a destination file within another app using a ievv_opensource.utils.ievvbuildstatic.filepath.SourcePath object (a subclass of ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface) as the path:

self.get_destination_path(
    ievvbuildstatic.filepath.DestinationPath(
        'myotherapp', '1.1.0', 'scripts', 'typescript', 'app.ts'),
    new_extension='.js')
Parameters:
watch(skipgroups=None, includegroups=None)[source]

Start a watcher thread for each plugin.

get_installer(alias)[source]

Get an instance of the installer configured with the provided alias.

Parameters:alias – A subclass of .
Returns:
An instance
of the requested installer.
Return type:ievv_opensource.utils.ievvbuildstatic.installers.base.AbstractInstaller
get_logger_name()[source]

Get the name of the logger.

make_temporary_build_directory(name)[source]

Make a temporary directory that you can use for building something.

Returns:The absolute path of the new directory.
Return type:str
class ievv_opensource.utils.ievvbuildstatic.config.Apps(*apps, **kwargs)[source]

Bases: ievv_opensource.utils.logmixin.LogMixin

Basically a list around App objects.

Parameters:appsApp objects to add initially. Uses add_app() to add the apps.
add_app(app)[source]

Add an App.

get_app(appname)[source]

Get app by appname.

install(appnames=None, skipgroups=None, includegroups=None)[source]

Run ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.install() for all plugins within all apps.

iterapps(appnames=None)[source]

Get an interator over the apps.

run(appnames=None, skipgroups=None, includegroups=None)[source]

Run ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.run() for all plugins within all apps.

watch(appnames=None, skipgroups=None, includegroups=None)[source]

Start watcher threads for all folders that at least one plugin within any of the apps has configured to be watched for changes.

Blocks until CTRL-c is pressed.

get_logger_name()[source]

Get the name of the logger.

Utils

class ievv_opensource.utils.ievvbuildstatic.utils.RegexFileList(include_patterns=None, exclude_patterns=None)[source]

Bases: object

A list of regexes for matching files.

Examples

Get all javascript files in a directory:

from ievv_opensource.utils import ievvbuildstatic

filelist = ievvbuildstatic.utils.RegexFileList(include_patterns=['^.*?\.js$'])
filelist.get_files_as_list('/path/to/javascript/sources/')

Exclude some files:

filelist = ievvbuildstatic.utils.RegexFileList(
    include_patterns=['^.*\.js$'],
    exclude_patterns=['^.*\.spec\.js$']
)
filelist.get_files_as_list('/path/to/javascript/sources/')
class ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface[source]

Bases: object

Base interface for file path objects.

We provide subclasses if this interface with different use cases:

abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

class ievv_opensource.utils.ievvbuildstatic.filepath.AbsoluteFilePath(*path)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface

Absolute file path.

Works just like os.path.join(), and we just assume that you provide a path that is absolute.

Parameters:*path – One or more strings that make up an absolute path when joined with os.path.join(*path).

Returns:

abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

class ievv_opensource.utils.ievvbuildstatic.filepath.AbstractDjangoAppPath[source]

Bases: ievv_opensource.utils.ievvbuildstatic.filepath.FilePathInterface

Abstract base class for file paths within a Django app.

abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

class ievv_opensource.utils.ievvbuildstatic.filepath.SourcePath(appname, *path)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.filepath.AbstractDjangoAppPath

A path to a file or directory within the source directory of a ievv_opensource.utils.ievvbuildstatic.config.App.

Assumes that the sourcefolder of the App is "staticsources" (the default).

Parameters:
abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

class ievv_opensource.utils.ievvbuildstatic.filepath.DestinationPath(appname, version, *path)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.filepath.AbstractDjangoAppPath

A path to a file or directory within the destination directory of a ievv_opensource.utils.ievvbuildstatic.config.App.

Assumes that the destinationfolder of the App is "static" (the default).

Parameters:
abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

class ievv_opensource.utils.ievvbuildstatic.filepath.AppPath(appname, *path)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.filepath.AbstractDjangoAppPath

A path to a file or directory within the root directory of a ievv_opensource.utils.ievvbuildstatic.config.App.

Parameters:
abspath

Property that returns the absolute path to the file (or directory).

Must be overridden in subclasses.

Installers

Overview

base.AbstractInstaller(app) Base class for installers.
npm.NpmInstaller(*args, **kwargs) NPM installer.
yarn.YarnInstaller(*args, **kwargs) Yarn installer.

Details

class ievv_opensource.utils.ievvbuildstatic.installers.base.AbstractInstaller(app)[source]

Bases: ievv_opensource.utils.logmixin.LogMixin, ievv_opensource.utils.shellcommandmixin.ShellCommandMixin, ievv_opensource.utils.ievvbuildstatic.options_mixin.OptionsMixin

Base class for installers.

Each installer defines most of their own API, the only thing they have in common is a reference to their ievv_opensource.utils.ievvbuildstatic.config.App, a name and the methods defined in ievv_opensource.utils.logmixin.LogMixin and ievv_opensource.utils.ievvbuildstatic.shellcommand.ShellCommandMixin.

Plugins instantiate installers using ievv_opensource.utils.ievvbuildstatic.config.App.get_installer().

Parameters:app – The ievv_opensource.utils.ievvbuildstatic.config.App where this installer object was instantiated using ievv_opensource.utils.ievvbuildstatic.config.App.get_installer().
name = None

The name of the installer.

get_logger_name()[source]

Get the name of the logger.

exception ievv_opensource.utils.ievvbuildstatic.installers.npm.NpmInstallerError[source]

Bases: Exception

exception ievv_opensource.utils.ievvbuildstatic.installers.npm.PackageJsonDoesNotExist[source]

Bases: ievv_opensource.utils.ievvbuildstatic.installers.npm.NpmInstallerError

class ievv_opensource.utils.ievvbuildstatic.installers.npm.NpmInstaller(*args, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.installers.abstract_npm_installer.AbstractNpmInstaller

NPM installer.

log_shell_command_stderr(line)[source]

Called by run_shell_command() each time the shell command outputs anything to stderr.

run_packagejson_script(script, args=None)[source]

Run a script in the scripts section of the package.json.

Parameters:
  • script – The npm script to run.
  • args (list) – List of arguments.
exception ievv_opensource.utils.ievvbuildstatic.installers.yarn.NpmInstallerError[source]

Bases: Exception

exception ievv_opensource.utils.ievvbuildstatic.installers.yarn.PackageJsonDoesNotExist[source]

Bases: ievv_opensource.utils.ievvbuildstatic.installers.yarn.NpmInstallerError

class ievv_opensource.utils.ievvbuildstatic.installers.yarn.YarnInstaller(*args, **kwargs)[source]

Bases: ievv_opensource.utils.ievvbuildstatic.installers.abstract_npm_installer.AbstractNpmInstaller

Yarn installer.

log_shell_command_stdout(line)[source]

Called by run_shell_command() each time the shell command outputs anything to stdout.

log_shell_command_stderr(line)[source]

Called by run_shell_command() each time the shell command outputs anything to stderr.

run_packagejson_script(script, args=None)[source]

Run a script in the scripts section of the package.json.

Parameters:
  • script – The npm script to run.
  • args (list) – List of arguments.

Low level API

class ievv_opensource.utils.ievvbuildstatic.watcher.WatchdogWatchConfig(watchfolders, watchregexes, plugin)[source]

Bases: object

Used by plugins to configure watching.

See ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.watch().

Parameters:
class ievv_opensource.utils.ievvbuildstatic.watcher.ProcessWatchConfig(plugin)[source]

Bases: object

Parameters:plugin – A ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin object.
class ievv_opensource.utils.ievvbuildstatic.watcher.WatchConfigPool[source]

Bases: ievv_opensource.utils.logmixin.LogMixin

get_logger_name()[source]

Get the name of the logger.

class ievv_opensource.utils.ievvbuildstatic.watcher.EventHandler(*args, **kwargs)[source]

Bases: watchdog.events.RegexMatchingEventHandler

Event handler for watchdog — this is used by each watcher thread to react to changes in the filesystem.

This is instantiated by ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.watch() to watch for changes in files matching ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.get_watch_regexes() in the folders specified in ievv_opensource.utils.ievvbuildstatic.pluginbase.Plugin.get_watch_folders().

on_any_event(event)[source]

Catch-all event handler.

Parameters:event (FileSystemEvent) – The event object representing the file system event.