{ "info": { "author": "Tommy Yu", "author_email": "tommy.yu@auckland.ac.nz", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Environment :: Plugins", "Framework :: Setuptools Plugin", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: BSD", "Operating System :: POSIX :: Linux", "Programming Language :: JavaScript", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries", "Topic :: System :: Software Distribution", "Topic :: Utilities" ], "description": "calmjs\n======\n\nA Python framework for building toolchains and utilities for working\nwith the Node.js ecosystem from within a Python environment.\n\n.. image:: https://travis-ci.org/calmjs/calmjs.svg?branch=3.4.1\n :target: https://travis-ci.org/calmjs/calmjs\n.. image:: https://ci.appveyor.com/api/projects/status/45054tm9cfk7ryam/branch/3.4.1?svg=true\n :target: https://ci.appveyor.com/project/metatoaster/calmjs/branch/3.4.1\n.. image:: https://coveralls.io/repos/github/calmjs/calmjs/badge.svg?branch=3.4.1\n :target: https://coveralls.io/github/calmjs/calmjs?branch=3.4.1\n\n.. |AMD| replace:: AMD (Asynchronous Module Definition)\n.. |calmjs.bower| replace:: ``calmjs.bower``\n.. |calmjs| replace:: ``calmjs``\n.. |calmjs_npm| replace:: ``calmjs npm``\n.. |calmjs.rjs| replace:: ``calmjs.rjs``\n.. |calmjs.webpack| replace:: ``calmjs.webpack``\n.. |npm| replace:: ``npm``\n.. |r.js| replace:: ``r.js``\n.. |setuptools| replace:: ``setuptools``\n.. |webpack| replace:: ``webpack``\n.. |yarn| replace:: ``yarn``\n.. _AMD: https://github.com/amdjs/amdjs-api/blob/master/AMD.md\n.. _Bower: https://bower.io/\n.. _calmjs.bower: https://pypi.python.org/pypi/calmjs.bower\n.. _calmjs.rjs: https://pypi.python.org/pypi/calmjs.rjs\n.. _calmjs.webpack: https://pypi.python.org/pypi/calmjs.webpack\n.. _Node.js: https://nodejs.org/\n.. _npm: https://www.npmjs.com/\n.. _r.js: https://github.com/requirejs/r.js\n.. _setuptools: https://pypi.python.org/pypi/setuptools\n.. _webpack: https://webpack.js.org/\n.. _yarn: https://yarnpkg.com/\n\n\nIntroduction\n------------\n\nCalmjs defines an extensible framework for interoperability between\nPython and `Node.js`_ runtime for Python packages, to provide their\ndevelopers a well defined interface for bi-directional access between\nNode.js/Javascript development tools and the JavaScript code within\ntheir Python packages, such that a proper, formal integration with\nNode.js/JavaScript environment from a Python environment can be\nfacilitated. The goal of the Calmjs framework is to aid the\ndevelopment, testing, and deployment of Python packages that also\ninclude and/or integrate with external JavaScript code.\n\n\nMethodology\n-----------\n\nFirst, this is achieved by providing Python packages the ability to\ndeclare dependencies on Node.js/JavaScript packages or source files that\nare required to complete their functionality. This common framework\nwill ensure the accessibility of these metadata under a common protocol,\nto avoid incompatible declarations that are not portable between\ndifferent projects and environments, or being otherwise scattered across\ndifferent tools or locations or be duplicated within the same working\nenvironments by different sets of tools. Without a common framework,\nthe result is that Python packages will be unable to properly\ncommunicate their non-Python requirements and states between each other,\nresulting in difficulties in building, development and deployment of the\nsoftware stack, and/or becoming a source of errors for those processes.\n\nSecond, by offering a set of tools built on top of this extensible\nframework to work with these declarations for generating the\nconfiguration files for required Node.js tools, so that they can\nconstruct the required the build and/or runtime environment for their\nfunctionality.\n\nUltimately, this permits better Node.js integration with a given Python\nenvironment, lowering the amount of effort needed to achieve continuous\nintegration and/or delivery of Python packages in conjunction with\nNode.js/JavaScript packages in a reproducible manner.\n\nImplementation\n~~~~~~~~~~~~~~\n\nIn order to achieve this, the Calmjs framework provides a set of\nextension to |setuptools|_ that assists with the tracking and management\nof dependencies of JavaScript or Node.js based packages (such as ones\nthrough |npm|_) for a given Python package. It also provides a number\nof base classes that can be used to build custom toolchains that\nimplement different strategies for managing and compiling required\nJavaScript code and related assets into the deployment artifacts that an\napplication server may use, or to generate test harnesses to ensure\ncorrectness under both the development and production environment.\nThese extra functionalities will be provided by other Python packages\nunder the |calmjs| namespace in order to realize this modular\narchitecture.\n\nThe name Calmjs was originally derived from the steps in the first\niteration of the toolchain which involves the steps compile, assemble,\nand linkage into a module of JavaScript using the namespace from the\nhost Python package. The `m` in the logo is the ear of a rabbit. The\nreason this animal is chosen as the mascot for this project is because\nof their dietary habits, as it's analogous to how JavaScript code is\ntypically turned into a minimally usable level by other tools and\nframework.\n\n\nFeatures overview\n-----------------\n\nA framework for integration with Node.js based package managers\n Through |setuptools| command hooks, |calmjs| provides Python\n packages with the ability to declare and manage manifest definition\n files for Node.js based package management systems (e.g. such as\n ``package.json`` for |npm|). Under typical usage, this means the\n declaration of ``dependencies`` or ``devDependencies`` for the\n JavaScript packages needed by a given Python package can be tracked,\n all within the |setuptools| framework through the extensions\n provided by |calmjs|.\n\n The other part of this infrastructure is that these declarations\n follow the Python package dependency graph. Developers and users\n can make use of the |calmjs| console command entry point, or through\n |setuptools|, to generate a manifest file to facilitate the\n installation of Node.js packages required by the Python packages\n within the completed application stack, tailored for all the\n packages at hand.\n\n |calmjs| includes the integration support for both |npm|_ and\n |yarn|_ by default.\n\nExport JavaScript code out of Python packages with the same namespace\n A given Python package that included associated JavaScript source\n code within the same Python module and namespace structure alongside\n Python source code within the source tree, will be able to declare\n those namespaces as the root for those JavaScript modules under the\n exact same Python package namespace through |setuptools| entry\n points.\n\n These declarations will be available through registries exposed by\n the |calmjs| module registry system for other packages to turn those\n declarations through the API provided by the framework into working\n JavaScript code following the same declared module and namespace\n structures. The default module registry will make use of the ``/``\n character (instead of the ``.`` character like in Python) as the\n separator for the names due to established naming conventions in\n JavaScript (and in ES6 towards the future).\n\n Other tools that works with the Calmjs framework can then make use\n of these raw JavaScript source files in conjunction with the local\n Node.js environment, or generate artifacts for deployment over the\n web. This leads to...\n\nBetter integration of JavaScript toolchains into Python environments\n This is achieved by providing a framework for building toolchains\n for working with tools written in JavaScript for Node.js/JavaScript\n environments that integrates properly with existing Python packages\n and environments.\n\n There are no limitations as to how or what can be done with the\n tools or the source files, as this is left as an implementation\n detail. For an example please refer to the |calmjs.rjs|_ Python\n package, which allows the production of |AMD|_ artifacts from\n JavaScript packages embedded inside Python packages, or\n |calmjs.webpack|_ which integrates with |webpack|_ for the\n production of another commonly used bundled artifact format.\n\n Generally, toolchains can be built to find and load all Python\n packages (through the |calmjs| registry system) that have any\n JavaScript source files, and those will be extracted, go through the\n appropriate transpilers (if any) in order to build deployable\n artifacts. Test harnesses can be set up to aid with running of unit\n tests, functional testing and naturally the final integration tests\n needed for a successful deployment.\n\nWell-defined modular architecture to ensure code reuse and extensibility\n The features described so far are built upon a foundation of generic\n classes and modules, so that the support for additional JavaScript\n tools or custom process for handling transpilation can be as simple\n as creating a new module for a couple of classes with additional\n parameters with the relevant |setuptools| entry points.\n\n In fact, |calmjs| out of the box only ships with just the core\n framework plus the |npm|/|yarn| interfacing part, with the support\n for tools like `Bower`_ or |r.js|_ as completely separate packages\n (as |calmjs.bower|_ and |calmjs.rjs|_ respectively), such that\n projects, environments or sites that do not need the functionality\n those packages provide can simply opt to not have them installed.\n\n\nInstallation\n------------\n\nAs the goal of |calmjs| is to integrate Node.js and |npm| (or |yarn|)\ninto a Python environment, they need to be available within the\nenvironment; if they are not installed please follow the installation\nsteps for `Node.js`_ appropriate for the target operating\nsystem/environment/platform.\n\nTo install |calmjs| into a given Python environment, the following\ncommand can be executed to install directly from PyPI:\n\n.. code:: console\n\n $ pip install calmjs\n\n.. _development installation method:\n\nAlternative installation methods (for developers, advanced users)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDevelopment is still ongoing with |calmjs|, for the latest features and\nbug fixes, the development version can be installed through git like so:\n\n.. code:: console\n\n $ # standard installation mode\n $ pip install git+https://github.com/calmjs/calmjs.git#egg=calmjs\n $ # for an editable installation mode; note the upgrade flag\n $ pip install -U -e git+https://github.com/calmjs/calmjs.git#egg=calmjs\n\nNote that the ``-U`` flag for the editable installation is to ensure\nthat |setuptools| be upgraded to the latest version to avoid issues\ndealing with namespaces for development packages, which is documented in\nthe next paragraph.\n\nAlternatively, the git repository can be cloned directly and execute\n``python setup.py develop`` while inside the root of the source\ndirectory, however if this development installation method is done using\nany version of |setuptools| earlier than v31, there will be inconsistent\nerrors with importing of modules under the |calmjs| namespace. Various\n`symptoms of namespace import failures`_ are documented under the\n`troubleshooting`_ section of this document.\n\nTesting the installation\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo ensure that the |calmjs| installation is functioning correctly, the\nbuilt-in testsuite can be executed by the following:\n\n.. code:: console\n\n $ python -m unittest calmjs.tests.make_suite\n\nIf there are failures, please file an issue on the issue tracker with\nthe full traceback, and/or the method of installation. Please also\nremember to include platform specific information, such as Python\nversion, operating system environments and version, and other related\ninformation related to the issue at hand.\n\n\nUsage and description of key features\n-------------------------------------\n\nWhen installed to a particular Python environment, the |calmjs|\ncommand-line utility will become available within there.\n\n.. code:: console\n\n $ calmjs\n usage: calmjs [-h] [-d] [-q] [-v] [-V] ...\n\n positional arguments:\n \n artifact helpers for the management of artifacts\n npm npm support for the calmjs framework\n yarn yarn support for the calmjs framework\n\n optional arguments:\n -h, --help show this help message and exit\n\n global options:\n -d, --debug show traceback on error; twice for post_mortem\n '--debugger' when execution cannot continue\n -q, --quiet be more quiet\n -v, --verbose be more verbose\n -V, --version print version information\n\nAs mentioned, |npm| support is built-in so it is always available; to\naccess its help, simply execute ``calmjs npm -h``, which will then list\nthe options available for that particular subcommand. If other\nsubcommands are available (which will be provided by other |calmjs|\nintegration packages) they will be listed as a ```` and their\nspecific help messages will be accessible in the same manner.\n\nDeclare a ``package.json`` for a given Python package\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. _using package_json:\n\nIf a package wish to declare dependencies on packages hosted by |npm|,\nit may do something like this in its ``setup.py``:\n\n.. code:: python\n\n from setuptools import setup\n\n package_json = {\n \"dependencies\": {\n \"jquery\": \"~3.0.0\",\n \"underscore\": \"~1.8.0\",\n }\n }\n\n setup(\n name='example.package',\n # ...\n setup_requires=[\n 'calmjs',\n # plus other setup_requires ...\n ],\n package_json=package_json,\n # ...\n )\n\nNote that ``setup_requires`` section must specify |calmjs| in order to\nenable the ``package_json`` setup keyword for the generation of the\n``package.json`` metadata file for the given package whenever ``python\nsetup.py egg_info`` is executed (directly or indirectly), so that even\nif |calmjs| is not already installed into the current Python\nenvironment, it will be acquired from PyPI and be included as part of\nthe |setuptools| setup process, and without being a direct dependency of\nthe given package. The ``package.json`` will be generated if the\nprovided data is either a valid JSON string or a dictionary without\nincompatible data types. For example:\n\n.. code:: console\n\n $ python setup.py egg_info\n running egg_info\n writing package_json to example.package.egg-info/package.json\n ...\n $ cat example.package.egg-info/package.json\n {\n \"dependencies\": {\n \"jquery\": \"~3.0.0\",\n \"underscore\": \"~1.8.0\"\n }\n }\n\nThe key reason for using ``setup_requires`` is to not force a given\npackage's dependents to have |calmjs| as part of their dependencies, as\ntypically this is a requirement only for developers but not for\nend-users. This also mean that for developers that want to use |calmjs|\nand utilities they must install that separately (i.e. ``pip install\ncalmjs``), or declare |calmjs| as a development dependency through the\nusage of ``extras_require`` flag, for example:\n\n.. code:: python\n\n setup(\n name='example.package',\n # ...\n setup_requires=[\n 'calmjs',\n # ...\n ],\n extras_require={\n 'dev': [\n 'calmjs',\n # ... plus other development dependencies\n ],\n },\n # ...\n )\n\nThen to fully install the package as an editable package with the\ndependencies listed under the ``dev`` extras:\n\n.. code:: console\n\n $ pip install -e .[dev]\n Obtaining file://example/package\n ...\n Installing collected packages: ..., calmjs, ...\n Running setup.py develop for example.package\n Successfully installed ...\n\nNote that now the |calmjs| package remains installed in the Python\nenvironment, and the utilities they provide may now be used, covered by\nthe following sections.\n\nUsing the ``package.json`` across Python package dependencies\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. |integrate_with_calmjs_npm| replace:: integration with ``npm``\n through ``calmjs npm``\n\nWith the ``package.json`` file written to the package metadata\ndirectory, utilities such as |calmjs| make make use of it. One method\nto do this is through that package's ``setup.py``. By invoking\n``setup.py npm --init`` from there, a new ``package.json``, combined\nwith all the ``dependencies`` and ``devDependencies`` declared by the\nPython package dependencies of the given package, will be written to the\ncurrent directory. This is akin to running ``npm init``, with the\ndifference being that the dependencies are also being resolved through\nthe Python package dependency tree for the given Python package.\n\nDo note that this requires the ``package.json`` creation and handling\ncapability be available for the given package (refer to previous section\non how to achieve this) and all dependencies must be correctly installed\nand be importable from the current Python environment.\n\nAlternatively, the |calmjs_npm| utility may be used. Invoking ``calmjs\nnpm --init example.package`` from the command line will achieve the same\nthing, anywhere on the file system, provided that both |calmjs| and\n``example.package`` are installed and available through the current\nPython environment's import system. For more details and information\nabout this utility, please refer to the |integrate_with_calmjs_npm|_\nsection.\n\nDealing with |npm| dependencies with Python package dependencies\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFlat is better than nested. So all ``dependencies`` (and\n``devDependencies``) declared by any upstream Python package will be\nautomatically inherited by all its downstream packages, but they have\nthe option to override it with whatever they want through the mechanism\nas described above. They can set a JavaScript or Node.js package to\nwhatever versions desired, or even simply remove that dependency\ncompletely by setting the version to ``None``.\n\nWhenever an actual ``package.json`` is needed by |calmjs|, the\n|calmjs_npm| utility flattens all Node.js dependencies needed by the\nPython packages into a single file, which is then passed into the\nrespective JavaScript package manager for consumption. This process is\nalso done when a |calmjs| toolchain or utility make use of these\ndeclared information to to generate the desired artifacts to achieve\nwhatever desired task at hand.\n\nOf course, if the nested style of packages and dependency in the same\nstyle as |npm| is desired, no one is forced to use this, they are free\nto use whatever tools to interpret or make use of whatever data files\nand dependencies available, and/or to split their packages up to Python\nand JavaScript bits and have them be deployed and hosted on both PyPI\n(for ``pip``) and |npm| respectively and then figure out how to bring\nthem back together in a coherent manner. Don't ask (or debate with) the\nauthor on how the latter option is better or easier for everyone\n(developers, system integrators and end-users) involved.\n\nDeclare explicit dependencies on paths inside ``node_modules``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nGiven that the dependencies on specific versions of packages sourced\nfrom |npm| is explicitly specified, build tools will benefit again from\nexplicit declarations on files needed from those packages. Namely, the\ncompiled packages could be declared in the ``extras_calmjs`` section in\nJSON string much like ``package_json``, like so:\n\n.. code:: python\n\n extras_calmjs = {\n 'node_modules': {\n 'jquery': 'jquery/dist/jquery.js',\n 'underscore': 'underscore/underscore.js',\n },\n }\n\n setup(\n name='example.package',\n ...\n extras_calmjs=extras_calmjs,\n ...\n )\n\nSince ``node_modules`` is declared to be an ``extras_key``, conflicting\ndeclarations between packages within the environment will be resolved\nand merged in the same manner as dependencies conflicts declared in\n``package_json``.\n\nPlease do note that complete path names must be declared (note that the\n``.js`` filename suffix is included in the example); directories can\nalso be declared. However, as these declarations are done from within\nPython, explicit, full paths are required thus it is up to downstream\nintegration packages to properly handle and/or convert this into the\nconventions that standard Node.js tools might expect (i.e. where the\n``.js`` filename suffix is omitted).\n\nExport JavaScript code from Python packages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFurthering the previous example, if the files and directories inside\n``example.package`` are laid out like so::\n\n .\n \u251c\u2500\u2500 example\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 package\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 content.py\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 form.py\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 ui.js\n \u2502\u00a0\u00a0 \u251c\u2500\u2500 ui.py\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 widget.js\n \u2514\u2500\u2500 setup.py\n\nTo declare the JavaScript source files within ``./example/package`` as\nJavaScript modules through |calmjs|, an entry point can be declared like\nso in the ``setup.py`` file:\n\n.. code:: python\n\n setup(\n ...\n entry_points=\"\"\"\n ...\n [calmjs.module]\n example.package = example.package\n \"\"\",\n ...\n )\n\nNote that the name of the entry point is not relevant; that entry point\nname is ignored, as the intention of the default module registry is to\nprovide a module name that maps directly to the same import namespace\nas the source Python module, but with the ES5 namespace separator\n``/``, instead of the ``.`` character as in Python. If an explicit\nmapping is required, a new module registry class may be defined that\nuses the provided name as the CommonJS import name from the JavaScript\ncode.\n\nThe default method will expose the two source files with the following\nnames::\n\n - 'example/package/ui'\n - 'example/package/widget'\n\nFor some projects, it may be undesirable to permit this automated method\nto extract all the available JavaScript source files from within the\ngiven Python module.\n\nTo get around this, it is possible to declare new module registries\nthrough the Calmjs framework. Provided that the ``ModuleRegistry``\nsubclass was set up correctly to generate the desired modules from a\ngiven package, simply declare this as a ``calmjs.registry`` entry point\nlike so:\n\n.. code:: python\n\n setup(\n ...\n entry_points=\"\"\"\n ...\n [calmjs.registry]\n example.module = example.package.registry:ExampleModuleRegistry\n \"\"\",\n ...\n )\n\nDo note that while the names permitted for an entry point name is quite\nunrestricted, these registry names should be of a standard dotted\nnamespace format to ensure maximum tool compatibility, as these can be\nspecified from the command line through tools that utilizes this system.\n\nOnce the registry was declared, simply replace ``calmjs.module`` with\nthe name of that, along with a ``calmjs_module_registry`` attribute that\ndeclare this ``example.module`` registry is the default registry to use\nwith this package.\n\n.. code:: python\n\n setup(\n ...\n calmjs_module_registry=['example.package'],\n entry_points=\"\"\"\n ...\n [example.module]\n example.package = example.package\n \"\"\",\n ...\n )\n\nWithin the Calmjs framework, tools can be explicitly specified to\ncapture modules from any or all module registries registered to the\nframework. One other registry was also defined. If the entry point was\ndeclared like so:\n\n.. code:: python\n\n setup(\n ...\n entry_points=\"\"\"\n ...\n [calmjs.py.module]\n example.package = example.package\n \"\"\",\n ...\n )\n\nThe separator for the namespace and the module will use the ``.``\ncharacter instead of ``/``. However given that the ``.`` character is a\nvalid name for a JavaScript module, the usage of this may create issues\nwith certain JavaScript tools. While AMD based module systems can\ngenerally handle ``.`` characters in imports without issues, allowing\nsomewhat more Python-like feel importing using dotted names within the\nJavaScript environment, however, this may lead to incompatibilities with\nother JavaScript libraries thus the usage of this naming scheme is not\nrecommended.\n\nBy default, another registry with the ``.tests`` suffix is also declared\nas a compliment to the previously introduced registries, which packages\ncan make use of to declare JavaScript test code that accompanies the\nrespective modules that have been declared. For example:\n\n.. code:: python\n\n setup(\n ...\n entry_points=\"\"\"\n ...\n [calmjs.module]\n example.package = example.package\n\n [calmjs.module.tests]\n example.package.tests = example.package.tests\n \"\"\",\n ...\n )\n\nMuch like the first example, this declares ``example.package`` as a\nPython namespace module that exports JavaScript code, with the\nsubsequent declaration section being the module that contains the tests\nthat accompanies the first.\n\nMake available the accompanied resource files to loaders\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCertain Node.js build tools and frameworks support the concept of\n\"loaders\" for other resource files through the same import/require\nsystem for JavaScript modules. To provide the most basic support to\nease the effort required by package creators to expose other resource\nfiles to the Node.js tooling import systems, a subsidiary loader\nregistry may be declared and used in conjunction with a parent module\nregistry. To extend on the previous example, if following entry points\nare defined:\n\n.. code:: ini\n\n [calmjs.module]\n example.package = example.package\n\n [calmjs.module.loader]\n json = json[json]\n text = text[txt,json]\n\nThe ``calmjs.module.loader`` registry will reference its parent registry\n``calmjs.module`` for the specific modules that have been exposed, so\nthat it will source all the relevant filenames with the declared file\nname extensions to a specific loader by name. Unlike the base module\nregistry, the module loader registry will ignore the Python module name\nsection, while the name (on the left-hand side) is the desired loader,\nwith the extras (comma-separated tokens enclosed between the ``[]``) are\nthe file name extensions to be acquired from the package. Thus with the\npreviously defined entries for the ``example.package``, the following\n``require`` statements should resolve if the target resource files exist\nfor the package:\n\n.. code:: javascript\n\n // resolved through \"json = ...[json]\"\n var manifest_obj = require('json!example/package/manifest.json');\n // resolved through \"text = ...[txt,json]\"\n var manifest_txt = require('text!example/package/manifest.json');\n var index_txt = require('text!example/package/index.txt');\n\nAs the values generated by the registry follow the standard toolchain\nspec compile entry grammar, this should satisfy the most basic use cases\nand can be included directly as a ``calmjs_module_registry`` for the\npackage. However, the actual usage in the provided JavaScript code\nconjunction with the actual toolchain packages that integrates/interacts\nwith with their respective Node.js packages may have interactions that\nwill require special handling (such as inclusion/exclusion of the\ngenerated segments targeted for the final artifact, or how those sources\nare aliased or made available to the system, or whether or not the\nregistry itself requires manual integration); please consult the\ndocumentation for the specific integration package with regards to this\nspecific registry type.\n\nOne final note: due to the limitations of the Python entry point system,\nfile name extensions are assumed to be all lower-case.\n\n.. _integrate_with_calmjs_npm:\n\nIntegration with |npm| through |calmjs_npm|\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAs mentioned, it is possible to make use of the ``package.json``\ngeneration capabilities from outside of |setuptools|. Users can easily\ndo the same through the built-in ``calmjs npm`` tool:\n\n.. code:: console\n\n $ calmjs npm --help\n usage: calmjs npm [-h] [-d] [-q] [-v] [-V] [--view] [--init] [--install]\n [-i] [-m] [-w] [-E] [-P] [-D]\n [ ...]\n\n npm support for the calmjs framework\n\n positional arguments:\n python packages to be used for the generation of\n 'package.json'\n\n optional arguments:\n -D, --development explicitly specify development mode for npm install\n -E, --explicit explicit mode disables resolution for dependencies;\n only the specified Python package(s) will be used.\n -h, --help show this help message and exit\n -i, --interactive enable interactive prompt; if an action requires an\n explicit response but none were specified through\n flags (i.e. overwrite), prompt for response;\n disabled by default\n -m, --merge merge generated 'package.json' with the one in\n current directory; if interactive mode is not\n enabled, implies overwrite, else the difference will\n be displayed\n -P, --production explicitly specify production mode for npm install\n -w, --overwrite automatically overwrite any file changes to current\n directory without prompting\n\nNaturally, the same ``--init`` functionality shown above with the\n|setuptools| framework is available, however package names can be\nsupplied for generating the target ``package.json`` file from anywhere\non the filesystem, provided that the Python environment has all the\nrequired packages installed. For instance, if the Node.js packages for\n``example.package`` is to be installed, this can be invoked to view the\n``package.json`` that would be generated:\n\n.. code:: console\n\n $ calmjs -v npm --view example.package\n 2016-09-01 16:37:18,398 INFO calmjs.cli generating a flattened\n 'package.json' for 'example.package'\n {\n \"dependencies\": {\n \"jquery\": \"~3.0.0\",\n \"underscore\": \"~1.8.0\",\n },\n \"devDependencies\": {},\n \"name\": \"example.package\"\n }\n\nIf there is an existing ``package.json`` file already in the current\ndirectory, using the ``-i`` flag with ``--init`` or ``--install`` will\nshow what differences there may be between the generated version and the\nexisting version, and prompt for an action.\n\nToolchain\n~~~~~~~~~\n\nDocumentation on how to extend the Toolchain class to support use cases\nis currently incomplete. This is usually combined together with a\n``calmjs.runtime.DriverRuntime`` to hook into the ``calmjs`` runtime.\n\nUnfortunately at this time a detailed guide on how to create a complete\nimplementation is not completed (only documentation within the class\nare, however). For a working example on how this may be achieved please\nrefer to the implementations provided by |calmjs.rjs|_ or\n|calmjs.webpack|_.\n\nToolchain Advice\n~~~~~~~~~~~~~~~~\n\nFor package developers that need to provide additional instructions to\na toolchain execution (e.g. for compatibility between RequireJS and also\nwebpack for specific use case of features to a given package), the\ntoolchain system will also make use of the advice system such that\nadditional instructions may be created and registered for use and reuse\nby their dependents. Much like the Toolchain, this feature is currently\nlacking in documentation outside of the test cases.\n\nPre-defined artifact generation through |setuptools|\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIt is possible to define the artifacts to be generated for a given\npackage and the rule to do so. Simply define a function that return an\ninstance of a ``calmjs.toolchain.Toolchain`` subclass that have\nintegrated with the desired tool, and a ``calmjs.toolchain.Spec`` object\nwith the rules needed. These specific functions are often provided by\nthe package that offers them, please refer to the toolchain packages\nlisted and linked in the previous section for further details on how\nthese might be used.\n\nAs these are also implemented through the registry system, the entry\npoints generally look like this:\n\n.. code:: python\n\n setup(\n ...\n build_calmjs_artifacts=True,\n entry_points=\"\"\"\n ...\n [calmjs.artifacts]\n complete.bundle.js = example.toolchain:builder\n \"\"\",\n ...\n )\n\nIn the example, the ``builder`` function from the module\n``example.toolchain`` is used to generate the ``complete.bundle.js``\nfile. The generated artifact files will reside in the\n``calmjs_artifacts`` directory within the package metadata directory\n(one that ends with either ``.dist-info`` or ``.egg-info``) for that\npackage. An accompanied ``calmjs_artifacts.json`` file will also be\ngenerated, listing the versions of the various Python packages that were\ninvolved with construction of that artifact, and the version of binary\nthat was used for the task.\n\nWhen the ``build_calmjs_artifacts`` is set to ``True``, the hook for\nautomatic generation of these artifacts through the ``setup.py build``\nstep will enabled. This is useful for automatically bundling the\nartifact file with a release such as Python wheels (e.g. running\n``setup.py bdist_wheel`` will also build the declared artifacts.\nOtherwise, this step can be manually invoked using\n``setup.py build_calmjs_artifacts`` or through the\n``calmjs artifact build`` tool.\n\n\nTroubleshooting\n---------------\n\nThe following may be some issues that may be encountered with typical\nusage of |calmjs|.\n\nCRITICAL calmjs.runtime terminating due to a critical error\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf |calmjs| encounters any unexpected situation, it may abort like so:\n\n.. code:: console\n\n $ calmjs npm --install calmjs.dev\n CRITICAL calmjs.runtime terminating due to a critical error\n\nIf no useful ERROR message is listed before, please try running again\nusing a debug flag (either ``-d`` or ``--debug``).\n\n.. code:: console\n\n $ calmjs -d npm --install calmjs.dev\n CRITICAL calmjs.runtime terminating due to exception\n Traceback (most recent call last):\n ...\n\nSpecifying the debug flag twice will enable the ``post_mortem`` mode,\nwhere a debugger will be fired at the point of failure. Authors of\npackages that implement runtime classes that provide subcommands to the\n|calmjs| command may find this useful during their development cycles.\nDo note that the default debugger is only triggered if the top level\nruntime class enable the usage (which the runtime class that implement\nthe |calmjs| command does) and if the failure occur during the\ninvocation of the runtime class. Any other errors or exceptions that\noccur during the setup stage of the |calmjs| runtime will simply be\nlogged at a lower priority level (e.g. to make warnings generated during\nthe setup stage visible, additional verbose flags must be provided).\n\nERROR bad 'calmjs.runtime' entry point\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nImportError\n This is typically caused by improper removal of locally installed\n packages that had an entry point registered, an addon package to\n |calmjs| registered entry points pointing to bad import locations,\n or conflicting installation methods was used for the current\n environment as outlined in the installation section of this\n document. Either reinstall the broken package again with the\n correct installation method for the environment, or fully uninstall\n or remove files belonging to the packages or sources that are\n triggering the undesirable error messages.\n\nbad entry point\n This is caused by packages defining malformed entry point. The name\n of the package triggering this error will be noted in the log; the\n error may be reported to its developer.\n\n.. _symptoms of namespace import failures:\n\nRandom ``ImportError`` when trying to import from the |calmjs| namespace\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAs |calmjs| is declared as both namespace and package, there are certain\nlow-level setup that is required on the working Python environment to\nensure that all modules within can be located correctly. However,\nversions of |setuptools| earlier than `v31.0.0`__ does not create the\nrequired package namespace declarations when a package is installed\nusing a `development installation method`_ (e.g. using ``python setup.py\ndevelop``) into the Python environment in conjunction with another\npackage that was installed through ``pip`` within the same namespace.\nFailures can manifest as inconsistent import failures for any modules\nunder the |calmjs| namespace. As an example:\n\n.. __: https://setuptools.readthedocs.io/en/latest/history.html#v31-0-0\n\n.. code:: pycon\n\n >>> from calmjs import tests\n Traceback (most recent call last):\n File \"\", line 1, in \n ImportError: cannot import name tests\n >>> from calmjs import parse # calmjs.parse was installed via pip\n >>> from calmjs import tests\n >>> # no failure, but it was failing just earlier?\n\nIt could also manifest differently, such as an ``AttributeError``, which\nmay be triggered through the execution of unittests for |calmjs|:\n\n.. code:: console\n\n $ coverage run --include=src/* -m unittest calmjs.tests.make_suite\n Traceback (most recent call last):\n ...\n parent, obj = obj, getattr(obj, part)\n AttributeError: 'module' object has no attribute 'tests'\n $ python -m calmjs.tests.make_suite\n /usr/bin/python: No module named 'calmjs.tests'\n\nTo resolve this issue, ensure that |setuptools| is upgraded to v31 or\ngreater, which may be installed/upgraded through ``pip`` like so:\n\n.. code:: console\n\n $ pip install --upgrade setuptools\n\nThen reinstall all the required packages that are under the |calmjs|\nnamespace to resolve this import issue.\n\nEnvironmental variables being ignored/not passed to underlying tools\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nGenerally speaking, the Calmjs framework filters out all environmental\nvariables except for the bare minimum by default, and only passes a\nlimited number to the underlying tool. These are the ``PATH`` and the\n``NODE_PATH`` variables, plus platform specific variables to enable\nexecution of scripts and binaries.\n\nRuntime reporting 'unrecognized arguments:' on declared arguments\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis issue should be fully resolved for calmjs>=3.1.0.\n\nThe default behavior in the ArgumentParser defaults to uselessly blaming\nthe root parser for any unrecognized arguments caused by its subparsers.\nThe original workaround prior to calmjs-3.1.0 had the failure as\ndocumented below as its subparser resolver implementation was\nincomplete. Either of these misleading behaviors impede the end users\nfrom being able to quickly locate the misplaced argument flags.\n\nFor instance, if the |calmjs| command was executed like so resulting in\nerror message may look like this:\n\n.. code:: console\n\n $ calmjs subcmd1 subcmd2 --flag item\n usage: calmjs subcmd1 ... [--flag FLAG]\n calmjs subcmd1: error: unrecognized arguments: --flag\n\nThis means that ``--flag`` is unrecognized by the second subcommand\n(i.e. the ``calmjs subcmd1 subcmd2`` command) as that was placed after\n``subcmd2``, but the subparser for ``subcmd1`` flagged that as an error.\nUnfortunately there are a number of issues in the ``argparse`` module\nthat makes it difficult to fully resolve this problem, so for the mean\ntime please ensure the flag is provided at the correct subcommand level\n(i.e. in this case, ``calmjs subcmd1 --flag item subcmd2``), otherwise\nconsult the help at the correct level by appending ``-h`` to each of the\nvalid subcommands.\n\nModule registry not locating files from namespace packages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are a number of edge cases associated with namespace packages in\nPython, especially if they are provided on the system through different\nmethods (i.e. mix of zipped eggs, wheels and development packages).\nWhile workarounds for handling of namespace modules for the given\npackages are provided, there are limitations in place. One such cause\nis due to complexity in dealing with zipped eggs; if this is an issue,\nplease ensure that the affected package has ``zip_safe`` declared as\nfalse, or alternatively generate a Python wheel then install that wheel,\nif the target Python environment has that as the standard installation\nformat.\n\nUserWarning: Unknown distribution option: 'package_json'\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis also applies to other relevant options, as it is caused by the\nexecution of ``setup.py`` without |calmjs| being available to\n|setuptools|, such that the handling method for these keywords remain\nundefined. This can be corrected by providing |calmjs| as part of the\n``setup_requires`` section. Further information on this may be found in\nthe `using package_json`_ section of this document.\n\n\nContribute\n----------\n\n- Issue Tracker: https://github.com/calmjs/calmjs/issues\n- Source Code: https://github.com/calmjs/calmjs\n\n\nLegal\n-----\n\nThe Calmjs project is copyright (c) 2016 Auckland Bioengineering\nInstitute, University of Auckland. |calmjs| is licensed under the terms\nof the GPLv2 or later.\n\nChangelog\n=========\n\n3.4.1 (2019-05-23)\n------------------\n\n- If a toolchain execution raised the abort or cancel exception, there\n will now be an appropriate debug log entry if debug mode is enabled.\n- Avoid breaking an existing manner of assignment of advice_packages in\n related projects - ensure that a None value that was provided be\n treated as an empty list. [\n `#57 `_\n ]\n\n3.4.0 (2019-05-22)\n------------------\n\n- Clean up a failing test case on Windows due to failure to use normcase\n to normalize the path for comparison between test result and expected\n answers. [\n `#53 `_\n `#54 `_\n ]\n- Provide a means to enable/disable the invocation of the post_mortem\n debugger at the class level, such that this feature is not forcibly\n enabled for all subclasses of Runtime. [\n `#55 `_\n ]\n- Provide a registry for packages to specify which requirement (package)\n to acquire toolchain advice from to apply by default for the relevant\n toolchains. This also necessitated some changes to where the optional\n advices are applied, from the previous location applied as a setup\n level advice applied by the standard toolchain runtime, to the default\n sequence within the default toolchain itself. [\n `#56 `_\n ]\n\n - As a consequence of this feature, any setup advice that trigger a\n toolchain abort or cancel will not leave the cleanup advices not\n handled.\n - This feature is implemented in a manner that allow manual invocation\n of a toolchain with a list of manually provided advice_package be\n able to always override the default specified ones.\n\n3.3.1 (2018-08-20)\n------------------\n\n- Correct the implementation of the helper function ``which`` such that\n path arguments to valid executables are accepted and returned. [\n `#52 `_\n ]\n\n3.3.0 (2018-07-23)\n------------------\n\n- Implement the features required to simplify the process of exposing\n auxiliary resource files provided by Python packages to the Node.js\n build tools. [\n `#46 `_\n `#48 `_\n `#50 `_\n ]\n\n - Provide a standardised base child module registry and some helper\n functions for their usage.\n - Provide a loader module registry with a restrictive naming scheme\n that directly references a single parent module registry.\n - This also necessitated exposing the mapper of the parent registry\n in a way that is reusable for other filename extensions, so that\n the default mapper will also accept the globber and the filename\n extension arguments.\n - Refactor a number of registry classes so that they may be more\n easily extended.\n - The self-referential property of the root registry is now properly\n implemented.\n\n- For Node.js packages that didn't have a ``main`` or ``browser``\n section defined in their ``package.json``, make use of the default\n entry file ``index.js`` if it exists. [\n `#49 `_\n ]\n\n3.2.1 (2018-05-16)\n------------------\n\n- Pack related helpers for specific sets of package metadata files into\n functions that return them. Naturally existing ones are provided,\n with the keys/filenames parameterized for reuse by dependants. [\n `#43 `_\n ]\n- Use the ``ast`` module for parsing the es5 String Node value instead\n of the unicode-escape method as it encompasses more cases, including\n the line continuation escape sequence which can show up. [\n `#44 `_\n ]\n\n3.1.0 (2018-04-30)\n------------------\n\n- Fix the modgen function in calmjs.indexer by actually not using the\n marked as deprecated indexer functions by default, but instead use the\n ``pkg_resources`` version as originally intended. [\n `#30 `_\n `#33 `_\n ]\n- Ensure lookups on package names that have been normalized internally\n by pkg_resources can still be resolved by their original name. [\n `#31 `_\n ]\n- Correctly return an unsuccessful exit code on various partial success\n while running ``calmjs artifact build`` command and for the distutils\n ``build_calmjs_artifacts`` command. [\n `#27 `_\n `#38 `_\n ]\n- Correctly locate the subparser(s) that were responsible for whatever\n arguments they cannot recognize; includes cleaning up the interactions\n between the runtime and argparser classes and Python 3.7 compatibility\n fixes. [\n `#41 `_\n ]\n- Fix handling of working directory flag as the validation should be\n done in the beginning rather than later. Also clean up various\n logging/error messages surrounding that, plus a fix to toolchain test\n case isolation. Note that downstream packages that did not set up the\n export target as an absolute part will result in a warning. [\n `#42 `_\n ]\n\n3.0.0 (2018-01-10)\n------------------\n\n- The ``yarn`` subcommand is now provided as an alternative to ``npm``.\n- Also decreased the log verbosity during the bootstrap runtime stage,\n so that for systems that don't have the required binaries available,\n the default ``calmjs`` command won't show those pile of warnings for\n that (increasing verbosity with ``-v`` will restore those warnings).\n- Some confusing internal (but public) identifiers which are used in the\n Toolchain and Spec system have been renamed to better reflect their\n intended use and purpose. Deprecation code is applied to aid\n transition, and these will be removed in 4.0.0.\n\n - For ``Spec``:\n\n - ``*_source_map`` -> ``*_sourcepath`` (except for the key that really\n amplified the confusion which was ``generate_source_map``)\n - ``*_targets`` -> ``*_targetpaths`` (to be consistent with paths on\n the filesystem).\n\n - On the ``Toolchain``, for the similar reasons as above:\n\n - ``sourcemap_suffix`` -> ``sourcepath_suffix``\n - ``target_suffix`` -> ``targetpath_suffix``\n\n- Changed the order of binary resolution for Driver instances with\n configured NODE_PATH and current working directory to align with how\n Node.js inject them internally (in ``module.paths``, current working\n directory has higher order of precedence over NODE_PATH), for the\n method ``BaseDriver.find_node_modules_basedir``.\n- Framework for predefined artifact generation for packages through the\n ``calmjs.artifacts`` registry.\n- Also split off the directory resolution from the above method to\n ``BaseDriver.which_with_node_modules``.\n- Deprecated the existing toolchain.transpiler function as a standard\n callable. The new version must be an instance of ``BaseUnparser``\n provided by the ``calmjs.parse`` package. The NullToolchain will\n retain the usage of the legacy transpiler.\n- Generation of the full transpile targetpaths will be normalized. Note\n that targetpath is still toolchain specific.\n- Removed most of the ``vlqsm`` module as the functionality is now\n provided by ``calmjs.parse.vlq`` and ``calmjs.parse.sourcemap``. Only\n the legacy ``SourceWriter`` class remain, which is deprecated.\n- Provide generic first class support for loader plugins, such that\n downstream packages should no longer need to explicitly declare\n ``extras_calmjs`` to specify the location of loaders for all the\n different toolchains (which inevitably collide and cause conflicts).\n Toolchains downstream will need to implement support for this.\n- Artifact production support, including integration with setuptools.\n\n2.1.0 (2016-11-29)\n------------------\n\n- Namespace packages that have a module explicitly provided should still\n be able to be looked up if a valid entry point is provided; naturally\n if the module isn't declared correctly then the behavior remains\n unchanged (github issue #5)\n- Name field in ``package.json`` should contain project names standard\n to Node.js, i.e. if extras are specified, it should be stripped. This\n is done so that that ``npm`` will not choke on it with a warning and\n die. (github issue #4)\n\n2.0.0 (2016-11-16)\n------------------\n\n- Expose the indexer module functions mapper and modgen as public.\n- Completely refactored the Toolchain class to have much more consistent\n method naming convention and argument lists.\n- The compile method now reads from an instance specific list of methods\n which allow very customizable compilation steps.\n- Specific ways for a toolchain to skip specific names based.\n- Fixed copying of bundle sources to targets nested in subdirectories.\n- The ``Spec`` callback system is now renamed to advice system and more\n comprehensively implemented; every step within the toolchain will\n execute advices before and after for each respective step that have\n been registered under the matching identifiers. The identifiers for\n advices are are formalized as constants that can be imported from the\n ``calmjs.toolchain`` module.\n- The advice system has dedicated exceptions which can be raised to\n signal an abort or cleanly stop a run.\n- A couple spec keys were formalized, which are BUILD_DIR and\n CONFIG_JS_FILES, reserved for the build directory and marking out\n configuration JavaScript files.\n- On a successful toolchain call, all advices registered to the spec\n under the key ``calmjs.toolchain.SUCCESS`` will now be invoked.\n- Dedicated runtime provided for ``Toolchain`` subclasses, joining the\n ranks of a few other ``BaseDriver`` subclasses. This is implemented\n as ``calmjs.runtime.ToolchainRuntime``.\n- ``calmjs.runtime.Runtime`` can be subclassed and nested as it will now\n nest all ``BaseRuntime``. Also the ``init`` method is removed, just\n use ``__init__`` and standard subclassing ``super`` usage rules.\n- The default ``ArgumentParser`` instance for every ``Runtime`` will no\n longer be created until accessed, as it is now a property.\n- Provide a way for packages to declare the primary module registry or\n registries it declared packages for through a new setup keyword\n ``calmjs_module_registry``, if required and desired.\n- The default set of module registry names have been changed. Registry\n ``calmjs.pythonic`` is renamed to ``calmjs.py.module``; the related\n testing related registry is renamed to include the full name of its\n implied target.\n- Reserved a small set of core (already defined) registries for the\n calmjs framework, which is formally defined and enforce by the\n registry itself.\n- Corrected interactive-mode detection.\n- Helpers for source map generation for simple transpilation.\n\n1.0.3 (2016-09-07)\n------------------\n\n- Fixed the issue with bad environmental variables for subprocess.Popen\n for Windows under Python 2.7.\n- Other minor testing fixes on CI platforms.\n\n1.0.2 (2016-09-04)\n------------------\n\n- Fixed invocation of binaries on the Windows platform.\n- Corrected some minor wording.\n\n1.0.0 (2016-09-02)\n------------------\n\n- Initial release of the ``calmjs`` framework foundation.\n- A cli runtime entry point is provided, named ``calmjs``.\n- Provide core integration with ``npm`` and generation of\n ``package.json`` through the ``setuptools`` framework; this is\n accessible as a ``setuptool`` command or through ``calmjs`` runtime.\n- Provide a registry framework for use within ``calmjs``.\n- Provide core registries for registering packages for use by ``calmjs``\n through the predefined ``setuptools`` entry points and groups.\n- Provide a cli tool driver framework for interacting with ``node`` and\n other Node.js based or other command line tools.\n- Provide the base toolchain framework, built on top of the tool driver\n framework.\n- Provide modules for doing integration testing for modules that build\n on top of the ``calmjs`` framework.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/calmjs/calmjs/", "keywords": "", "license": "GPL", "maintainer": "", "maintainer_email": "", "name": "calmjs", "package_url": "https://pypi.org/project/calmjs/", "platform": "", "project_url": "https://pypi.org/project/calmjs/", "project_urls": { "Homepage": "https://github.com/calmjs/calmjs/" }, "release_url": "https://pypi.org/project/calmjs/3.4.1/", "requires_dist": [ "setuptools (>=12)", "calmjs.types", "calmjs.parse (!=1.1.0,!=1.1.1,<2,>=1.0.0)" ], "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "summary": "A Python framework for building toolchains and utilities for working with the Node.js ecosystem from within a Python environment.", "version": "3.4.1" }, "last_serial": 5306061, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "b39a5757dba5fcc17118163d35166be9", "sha256": "06723a5846b549142d4f8f2f2decf3ee78a39539778135f0fbac66924a11b602" }, "downloads": -1, "filename": "calmjs-1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b39a5757dba5fcc17118163d35166be9", "packagetype": "bdist_wheel", "python_version": "any", "requires_python": null, "size": 95662, "upload_time": "2016-09-02T17:42:39", "url": "https://files.pythonhosted.org/packages/3b/c5/a53e3005f5f6101f1f79a3285aa3eb32ef89f0209473dd2117e9ac3e4a17/calmjs-1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c2c97b2989f6b91c9c94ed02ca289ab1", "sha256": "497fb96321aa77f82d983d5b0d29d40e692f011d621693ba660f5a2fd5674b60" }, "downloads": -1, "filename": "calmjs-1.0.tar.gz", "has_sig": false, "md5_digest": "c2c97b2989f6b91c9c94ed02ca289ab1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 80865, "upload_time": "2016-09-02T17:43:14", "url": "https://files.pythonhosted.org/packages/9b/5c/d0458d3bdd706ffcd6010226db898bcde6d454649e5b73431b78ad297106/calmjs-1.0.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "1aba5dc8c802a84ffbaa43fddd31f9f3", "sha256": "21451b41c13e05bf4eb6afdd21da02bf1107bca67d772cdf9e6d417428b495fc" }, "downloads": -1, "filename": "calmjs-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1aba5dc8c802a84ffbaa43fddd31f9f3", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 97307, "upload_time": "2016-09-03T14:06:26", "url": "https://files.pythonhosted.org/packages/35/0a/80b4197bc86d26f95e4eaba430553aa18348f37947bebe2e9e0aa7f4c05a/calmjs-1.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "96d1113f4beed84666c13b99c1c0054c", "sha256": "af2303c18f8c0e407517f15f659d44c8c87aa31cd4e9971445a93aa8ebfdd120" }, "downloads": -1, "filename": "calmjs-1.0.2.tar.gz", "has_sig": false, "md5_digest": "96d1113f4beed84666c13b99c1c0054c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 82154, "upload_time": "2016-09-03T14:06:22", "url": "https://files.pythonhosted.org/packages/f1/b0/be122fb9107c707bd742362d7dc0b08727613144dc66f9888599a80d3e71/calmjs-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "66afd0512d9fa7457ea3b9acf3c5d280", "sha256": "317f06feefaf38bb0ba7b76c840a633fa0b3f85ef546f6bd339b54221514e480" }, "downloads": -1, "filename": "calmjs-1.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "66afd0512d9fa7457ea3b9acf3c5d280", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 97949, "upload_time": "2016-09-07T04:17:16", "url": "https://files.pythonhosted.org/packages/5a/87/058bd9a2f71373bd6691ff78d3127398cac093af25027d5bec11130c504a/calmjs-1.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5233bcb1f8944179a2aaf43d9f224c67", "sha256": "b3bce9d5a0ab184af02c5c835d283934747e000f3e08ff5c192908d8c72e2a9f" }, "downloads": -1, "filename": "calmjs-1.0.3.tar.gz", "has_sig": false, "md5_digest": "5233bcb1f8944179a2aaf43d9f224c67", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 82834, "upload_time": "2016-09-07T04:17:19", "url": "https://files.pythonhosted.org/packages/dd/64/46665fdb68cc97af57a2e8f6aa76def182e084b7046485262afa9fcdf684/calmjs-1.0.3.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "0b42413c7c576daa11251518ddb6d2bd", "sha256": "a827fb816b1ca62fe38fe2d24e8ae0e2da9cc2e233b13c88c209c703458f76b4" }, "downloads": -1, "filename": "calmjs-2.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0b42413c7c576daa11251518ddb6d2bd", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 142347, "upload_time": "2016-11-16T03:51:59", "url": "https://files.pythonhosted.org/packages/68/25/57a0ba28f3c5b7a95126b351fe87c0f79b66e8838bda9d02cca41d31cdd3/calmjs-2.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "08486a1051bdc43981564964a5d90a53", "sha256": "b4928c415914a6d21e86338f096ede66e5fa409104a9421e2e6cd9e777ba6ba4" }, "downloads": -1, "filename": "calmjs-2.0.0.zip", "has_sig": false, "md5_digest": "08486a1051bdc43981564964a5d90a53", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 158827, "upload_time": "2016-11-18T05:34:57", "url": "https://files.pythonhosted.org/packages/67/f6/c2f2ba683d8d847cb6d6f647c2b3931332133dbcd8428b054818d7848b6c/calmjs-2.0.0.zip" } ], "2.1.0": [ { "comment_text": "", "digests": { "md5": "03e6b002f9d79964e1e67fcc33cdb22c", "sha256": "ef13cea71c40b94ab67d9f7a7a6d9c6cbd2f58554309b2f7995dc5f300b1af4f" }, "downloads": -1, "filename": "calmjs-2.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "03e6b002f9d79964e1e67fcc33cdb22c", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 145248, "upload_time": "2016-11-29T04:13:27", "url": "https://files.pythonhosted.org/packages/b0/57/e6fe3dfc0b211c8fa91a52a6b8a893ae3c5378ab7d1de3aad31b1c1328f1/calmjs-2.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cf5ad675297251de9915eb9b91b37f63", "sha256": "d7a08843b538960abedc398729967a5a241618cd608b96324cbabdafcb6ce45f" }, "downloads": -1, "filename": "calmjs-2.1.0.zip", "has_sig": false, "md5_digest": "cf5ad675297251de9915eb9b91b37f63", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 162406, "upload_time": "2016-11-29T04:13:23", "url": "https://files.pythonhosted.org/packages/d7/23/046805323d7cb68dd376c3dffe3fb5c0f6c166a5c624a8b9d90d4b54adb8/calmjs-2.1.0.zip" } ], "3.0.0": [ { "comment_text": "", "digests": { "md5": "fbbba058e87f246033f23dff19225cce", "sha256": "db7c1268f6c36206078f3b6aa620c6147db58f69cb934c548ad272bb7f7ce352" }, "downloads": -1, "filename": "calmjs-3.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fbbba058e87f246033f23dff19225cce", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 199256, "upload_time": "2018-01-10T06:37:52", "url": "https://files.pythonhosted.org/packages/62/0f/822ce820f200301e94003180b306b603a695def671fd96cf2e4548f76a89/calmjs-3.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7469f24449f592da6e676a6e906f58a9", "sha256": "80487b660f90d5bb9cbada5805c7a163fc4f8be4c1a7f0dc68e0bd14ba04f4a6" }, "downloads": -1, "filename": "calmjs-3.0.0.zip", "has_sig": false, "md5_digest": "7469f24449f592da6e676a6e906f58a9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 219952, "upload_time": "2018-01-10T06:37:54", "url": "https://files.pythonhosted.org/packages/c4/39/6f92a44e8c61dab79b14a56e897a3781467f66b3929c5b1bd48a78e9611a/calmjs-3.0.0.zip" } ], "3.1.0": [ { "comment_text": "", "digests": { "md5": "768aa22c1afdec6e8754d21cbad9c092", "sha256": "bb1a344a4e9656698298d093fb6c4bdce5cfb9380cd64b5c4fa7d85fd4b0a7c3" }, "downloads": -1, "filename": "calmjs-3.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "768aa22c1afdec6e8754d21cbad9c092", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 191084, "upload_time": "2018-04-30T04:30:10", "url": "https://files.pythonhosted.org/packages/cc/66/5d559a62c18cf7773b015c108ba614b66cbf4b7181a3ff06c7916b887e11/calmjs-3.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "515bb25d43b6f193af053180bb52af59", "sha256": "db1a457127262fac211f07c615f20b244d58c59a4deeb516f09a8f9344b571b0" }, "downloads": -1, "filename": "calmjs-3.1.0.zip", "has_sig": false, "md5_digest": "515bb25d43b6f193af053180bb52af59", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 228131, "upload_time": "2018-04-30T04:30:12", "url": "https://files.pythonhosted.org/packages/eb/3d/f04a9185e1d67dc9a2e24afbc8d094005743a7b0274e7405768f7c9a0167/calmjs-3.1.0.zip" } ], "3.2.1": [ { "comment_text": "", "digests": { "md5": "049d1705660d8902747261bdd43441fe", "sha256": "791deede9537b13c7c080229754073371512c49638eabbb2a37af249dd395dad" }, "downloads": -1, "filename": "calmjs-3.2.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "049d1705660d8902747261bdd43441fe", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 191566, "upload_time": "2018-05-16T07:23:29", "url": "https://files.pythonhosted.org/packages/fc/e6/3a73bc12448f144f273352114b75137335f14804f718936c644248d12dc6/calmjs-3.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c5b7797b0eef08efefb5d9d4b2bc1fcb", "sha256": "f23b5873c1c7ae3291d9090859b8a2c5e166a6c27fb3e4ed2398bc7aadf68dcd" }, "downloads": -1, "filename": "calmjs-3.2.1.zip", "has_sig": false, "md5_digest": "c5b7797b0eef08efefb5d9d4b2bc1fcb", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 229045, "upload_time": "2018-05-16T07:23:30", "url": "https://files.pythonhosted.org/packages/99/ab/6853652514f945cd8c7514c43763307c5d996b09fb351d1198bc35644e3e/calmjs-3.2.1.zip" } ], "3.3.0": [ { "comment_text": "", "digests": { "md5": "62469c523df93a20f3e5f25408a54cb6", "sha256": "54e94ed3ff1772616b085e9e7f1d4a9a16002b521728f6b2454f51cdb40719f0" }, "downloads": -1, "filename": "calmjs-3.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "62469c523df93a20f3e5f25408a54cb6", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 202289, "upload_time": "2018-07-23T07:25:18", "url": "https://files.pythonhosted.org/packages/6e/3b/ce2d0e83810f6baa62a0c444b18e9a23d3c7dcb41cbf9c6d24ff2f1985a3/calmjs-3.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5b73feb1a19136e5631c722e27905445", "sha256": "d5498bdfa55505c32520fb9f39b55d4c36a7c8ddd71aa1a35a1e0c6678823b74" }, "downloads": -1, "filename": "calmjs-3.3.0.zip", "has_sig": false, "md5_digest": "5b73feb1a19136e5631c722e27905445", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 242687, "upload_time": "2018-07-23T07:25:20", "url": "https://files.pythonhosted.org/packages/28/38/89ac3284901ceffd90ea6cc35970cf2a02301415066ab4e2840f28681972/calmjs-3.3.0.zip" } ], "3.3.1": [ { "comment_text": "", "digests": { "md5": "4d85d61ab7ed7a53cc54c34810132038", "sha256": "84eb2295725090ca6e8b31693a0be5605a44dee54878a4006acf828421c58fd9" }, "downloads": -1, "filename": "calmjs-3.3.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4d85d61ab7ed7a53cc54c34810132038", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 203165, "upload_time": "2018-08-20T07:37:21", "url": "https://files.pythonhosted.org/packages/87/0c/f98f3d2d98ad7672d60e886c86aaa28f892ca01b15988529092c4d13122e/calmjs-3.3.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ff8eac2267b8a15c3a002529a0438fe7", "sha256": "3212a260dd485f01e31fa77d8ea0ed50ca00f5b90807b781c82e0e5acbbf29ce" }, "downloads": -1, "filename": "calmjs-3.3.1.zip", "has_sig": false, "md5_digest": "ff8eac2267b8a15c3a002529a0438fe7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 245262, "upload_time": "2018-08-20T07:37:23", "url": "https://files.pythonhosted.org/packages/0d/5a/1c00f93e91580a1d19c4a22d7eac24912d13a40125a9b7d25a999672b099/calmjs-3.3.1.zip" } ], "3.4.0": [ { "comment_text": "", "digests": { "md5": "e7cf31acc0f148d835487f855a91c915", "sha256": "52e03d789a2740f5f9e34523514192f74078edd8d0bdb7b25718e0631bd1d3a1" }, "downloads": -1, "filename": "calmjs-3.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e7cf31acc0f148d835487f855a91c915", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 210086, "upload_time": "2019-05-22T01:48:21", "url": "https://files.pythonhosted.org/packages/26/a5/f464372a8122c9ac696697f985f7bc763651e6e5d98e7f0faf8e513a2d63/calmjs-3.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0aa9341cd8c3969c62d5f8575356675b", "sha256": "9b96c78dc20cad6e83c16376a2ed65e3d03ffe668b0aad34db6cb9124bfc2c10" }, "downloads": -1, "filename": "calmjs-3.4.0.zip", "has_sig": false, "md5_digest": "0aa9341cd8c3969c62d5f8575356675b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 253501, "upload_time": "2019-05-22T01:48:24", "url": "https://files.pythonhosted.org/packages/f6/fd/15943f0b34cb2a10ca016d0a047fe2384667a0856ed02aa46c76b481bad5/calmjs-3.4.0.zip" } ], "3.4.1": [ { "comment_text": "", "digests": { "md5": "170e9d0d2fcca83161239aeefdba2989", "sha256": "970d327a8af4736f7e0310809c93a2b911dd778953948881a1bda0f35a068c9e" }, "downloads": -1, "filename": "calmjs-3.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "170e9d0d2fcca83161239aeefdba2989", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 210441, "upload_time": "2019-05-23T06:39:53", "url": "https://files.pythonhosted.org/packages/32/79/1e9a4798dabf260905721233d230683f14b1f08ad759469db30b8cc6d094/calmjs-3.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "199d00a900a3f08108d86a1d7af1b9bc", "sha256": "43072b5bcbcf927c8a340f7e099e7a03b24776224f7e82f875613ab1503f5b1d" }, "downloads": -1, "filename": "calmjs-3.4.1.zip", "has_sig": false, "md5_digest": "199d00a900a3f08108d86a1d7af1b9bc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 254134, "upload_time": "2019-05-23T06:39:56", "url": "https://files.pythonhosted.org/packages/59/8e/25fb4adbb2f7df1ebd7d8ba4e7a5339e88c0f7581f46242922cb1d34ef12/calmjs-3.4.1.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "170e9d0d2fcca83161239aeefdba2989", "sha256": "970d327a8af4736f7e0310809c93a2b911dd778953948881a1bda0f35a068c9e" }, "downloads": -1, "filename": "calmjs-3.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "170e9d0d2fcca83161239aeefdba2989", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 210441, "upload_time": "2019-05-23T06:39:53", "url": "https://files.pythonhosted.org/packages/32/79/1e9a4798dabf260905721233d230683f14b1f08ad759469db30b8cc6d094/calmjs-3.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "199d00a900a3f08108d86a1d7af1b9bc", "sha256": "43072b5bcbcf927c8a340f7e099e7a03b24776224f7e82f875613ab1503f5b1d" }, "downloads": -1, "filename": "calmjs-3.4.1.zip", "has_sig": false, "md5_digest": "199d00a900a3f08108d86a1d7af1b9bc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*", "size": 254134, "upload_time": "2019-05-23T06:39:56", "url": "https://files.pythonhosted.org/packages/59/8e/25fb4adbb2f7df1ebd7d8ba4e7a5339e88c0f7581f46242922cb1d34ef12/calmjs-3.4.1.zip" } ] }