massedit


Namemassedit JSON
Version 0.70.0 PyPI version JSON
download
home_pagehttp://github.com/elmotec/massedit
SummaryEdit multiple files using Python text processing modules
upload_time2023-09-11 02:59:59
maintainer
docs_urlNone
authorelmotec
requires_python>=3.5
licenseMIT
keywords sed editor stream python edit mass
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: https://img.shields.io/pypi/v/massedit.svg
    :target: https://pypi.python.org/pypi/massedit/
    :alt: PyPi version

.. image:: https://img.shields.io/pypi/pyversions/massedit.svg
    :target: https://pypi.python.org/pypi/massedit/
    :alt: Python compatibility

.. image:: https://img.shields.io/github/workflow/status/elmotec/massedit/Python%20application
    :target: https://github.com/elmotec/massedit/actions?query=workflow%3A%22Python+application%22
    :alt: GitHub Workflow Python application

.. image:: https://img.shields.io/appveyor/ci/elmotec/massedit.svg?label=AppVeyor
    :target: https://ci.appveyor.com/project/elmotec/massedit
    :alt: AppVeyor status

.. image:: https://img.shields.io/pypi/dm/massedit.svg
    :alt: PyPi
    :target: https://pypi.python.org/pypi/massedit

.. image:: https://img.shields.io/librariesio/release/pypi/massedit.svg?label=libraries.io
    :alt: Libraries.io dependency status for latest release
    :target: https://libraries.io/pypi/massedit

.. image:: https://coveralls.io/repos/elmotec/massedit/badge.svg
    :target: https://coveralls.io/r/elmotec/massedit
    :alt: Coverage

.. image:: https://img.shields.io/codacy/grade/474b0af6853a4c5f8f9214d3220571f9.svg
    :target: https://www.codacy.com/app/elmotec/massedit/dashboard
    :alt: Codacy


========
massedit
========

*formerly known as Python Mass Editor*

Implements a python mass editor to process text files using Python
code. The modification(s) is (are) shown on stdout as a diff output. One
can then modify the target file(s) in place with the -w/--write option.
This is very similar to 2to3 tool that ships with Python 3.


+--------------------------------------------------------------------------+
| **WARNING**: A word of caution about the usage of ``eval()``             |
+--------------------------------------------------------------------------+
| This tool is useful as far as it goes but it does rely on the python     |
| ``eval()`` function and does not check the code being executed.          |
| **It is a major security risk** and one should not use this tool in a    |
| production environment.                                                  |
|                                                                          |
| See `Ned Batchelder's article`_ for a thorough discussion of the dangers |
| linked to ``eval()`` and ways to circumvent them. Note that None of the  |
| counter-measure suggested in the article are implemented at this time.   |
+--------------------------------------------------------------------------+

Usage
-----

You probably will need to know the basics of the `Python re module`_ (regular
expressions).

::

    usage: massedit.py [-h] [-V] [-w] [-v] [-e EXPRESSIONS] [-f FUNCTIONS]
                       [-x EXECUTABLES] [-s START_DIRS] [-m MAX_DEPTH] [-o FILE]
                       [-g FILE] [--encoding ENCODING] [--newline NEWLINE]
                       [file pattern [file pattern ...]]

    Python mass editor

    positional arguments:
      file pattern          shell-like file name patterns to process or - to read
                            from stdin.

    optional arguments:
      -h, --help            show this help message and exit
      -V, --version         show program's version number and exit
      -w, --write           modify target file(s) in place. Shows diff otherwise.
      -v, --verbose         increases log verbosity (can be specified multiple
                            times)
      -e EXPRESSIONS, --expression EXPRESSIONS
                            Python expressions applied to target files. Use the
                            line variable to reference the current line.
      -f FUNCTIONS, --function FUNCTIONS
                            Python function to apply to target file. Takes file
                            content as input and yield lines. Specify function as
                            [module]:?<function name>.
      -x EXECUTABLES, --executable EXECUTABLES
                            Python executable to apply to target file.
      -s START_DIRS, --start START_DIRS
                            Directory(ies) from which to look for targets.
      -m MAX_DEPTH, --max-depth-level MAX_DEPTH
                            Maximum depth when walking subdirectories.
      -o FILE, --output FILE
                            redirect output to a file
      -g FILE, --generate FILE
                            generate stub file suitable for -f option
      --encoding ENCODING   Encoding of input and output files
      --newline NEWLINE     Newline character for output files

    Examples:
    # Simple string substitution (-e). Will show a diff. No changes applied.
    massedit.py -e "re.sub('failIf', 'assertFalse', line)" *.py

    # File level modifications (-f). Overwrites the files in place (-w).
    massedit.py -w -f fixer:fixit *.py

    # Will change all test*.py in subdirectories of tests.
    massedit.py -e "re.sub('failIf', 'assertFalse', line)" -s tests test*.py

    # Will transform virtual methods (almost) to MOCK_METHOD suitable for gmock (see https://github.com/google/googletest).
    massedit.py -e "re.sub(r'\s*virtual\s+([\w:<>,\s&*]+)\s+(\w+)(\([^\)]*\))\s*((\w+)*)(=\s*0)?;', 'MOCK_METHOD(\g<1>, \g<2>, \g<3>, (\g<4>, override));', line)" gmock_test.cpp


If massedit is installed as a package (from pypi for instance), one can interact with it as a command line tool:

::

  python -m massedit -e "re.sub('assertEquals', 'assertEqual', line)" test.py


Or as a library (command line option above to be passed as kewyord arguments):

::

  >>> import massedit
  >>> filenames = ['massedit.py']
  >>> massedit.edit_files(filenames, ["re.sub('Jerome', 'J.', line)"])


Lastly, there is a convenient ``massedit.bat`` wrapper for Windows included in
the distribution.


Installation
------------

Download ``massedit.py`` from ``http://github.com/elmotec/massedit`` or :

::

  pip install massedit


Poor man source-to-source manipulation
--------------------------------------

I find myself using massedit mostly for source to source modification of
large code bases like this:

First create a ``fixer.py`` python module with the function that will
process your source code. For instance, to add a header:

::

  def add_header(lines, file_name):
      yield '// This is my header'  # will be the first line of the file.
      for line in lines:
          yield line


Adds the location of ``fixer.py`` to your ``$PYTHONPATH``, then simply
call ``massedit.py`` like this:

::

  massedit.py -f fixer:add_header *.h


You can add the ``-s .`` option to process all the ``.h`` files reccursively.


Plans
-----

- Add support for 3rd party tool (e.g. `autopep8`_) to process the files.
- Add support for a file of expressions as an argument to allow multiple
  modification at once.
- Find a satisfactory way (ie. easy to use) to handle multiline regex as the
  current version works on a line by line basis.


Rationale
---------

- I have a hard time practicing more than a few dialects of regular
  expressions.
- I need something portable to Windows without being bothered by eol.
- I believe Python is the ideal tool to build something more powerful than
  simple regex based substitutions.


Background
----------

I have been using runsed and checksed (from Unix Power Tools) for years and
did not find a good substitute under Windows until I came across Graham
Fawcett python recipe 437932_ on ActiveState. It inspired me to write the
massedit.

The core was fleshed up a little, and here we are. If you find it useful and
enhance it please, do not forget to submit patches. Thanks!

If you are more interested in awk-like tool, you probably will find pyp_ a
better alternative.


License
-------

Licensed under the term of `MIT License`_. See attached file LICENSE.txt.


Changes
-------

See CHANGELOG.md for changes later than 0.69.0

0.69.0 (2020-12-22)
  Updated infrastructure files to setup.cfg/pyproject.toml instead of
  setup.py.  Also moved CI to github workflows from travis and added
  regression tests for Python 2.7.

0.68.6 (2019-12-02)
  Added support for Python 3.8, stdin input via - argument. Documented
  regex to turn base classes into googlemock MOCK_METHOD.

0.68.5 (2019-04-13)
  Added --newline option to force newline output. Thanks @ALFNeT!

0.68.4 (2017-10-24)
  Fixed bug that would cause changes to be missed when the -w option is
  ommited. Thanks @tgoodlet!

0.68.3 (2017-09-20)
  Added --generate option to quickly generate a fixer.py template file
  to be modified to be used with -f fixer.fixit option. Added official
  support for Python 3.6

0.68.1 (2016-06-04)
  Fixed encoding issues when processing non-ascii files.
  Added --encoding option to force the value of the encoding if need be.
  Listed support for Python 3.5

0.67.1 (2015-06-28)
  Documentation fixes.

0.67 (2015-06-23)
  Added file_name argument to processing functions.
  Fixed incorrect closing of sys.stdout/stderr.
  Improved diagnostic when the processing function does not take 2 arguments.
  Swapped -v and -V option to be consistent with Python.
  Pylint fixes.
  Added support for Python 3.4.
  Dropped support for Python 3.2.

0.66 (2013-07-14)
  Fixed lost executable bit with -f option (thanks myint).

0.65 (2013-07-12)
  Added -f option to execute code in a separate file/module. Added Travis continuous integration (thanks myint). Fixed python 2.7 support (thanks myint).

0.64 (2013-06-01)
  Fixed setup.py so that massedit installs as a script. Fixed eol issues (thanks myint).

0.63 (2013-05-27)
  Renamed to massedit. Previous version are still known as Python-Mass-Editor.

0.62 (2013-04-11)
  Fixed bug that caused an EditorError to be raised when the result of the
  expression is an empty string.

0.61 (2012-07-06)
  Added massedit.edit_files function to ease usage as library instead of as
  a command line tool (suggested by Maxim Veksler).

0.60 (2012-07-04)
  Treats arguments as patterns rather than files to ease processing of
  multiple files in multiple subdirectories.  Added -s (start directory)
  and -m (max depth) options.

0.52 (2012-06-05)
  Upgraded for python 3. Still compatible with python 2.7.

0.51 (2012-05)
  Initial release (Beta).


Contributor acknowledgement
---------------------------

https://github.com/myint, 
https://github.com/tgoodlet, 
https://github.com/ALFNeT



.. _437932: http://code.activestate.com/recipes/437932-pyline-a-grep-like-sed-like-command-line-tool/
.. _Python re module: http://docs.python.org/library/re.html
.. _Pyp: http://code.google.com/p/pyp/
.. _MIT License: http://en.wikipedia.org/wiki/MIT_License
.. _autopep8: http://pypi.python.org/pypi/autopep8
.. _Ned Batchelder's article: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

            

Raw data

            {
    "_id": null,
    "home_page": "http://github.com/elmotec/massedit",
    "name": "massedit",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.5",
    "maintainer_email": "",
    "keywords": "sed,editor,stream,python,edit,mass",
    "author": "elmotec",
    "author_email": "elmotec <elmotec@gmx.com>",
    "download_url": "https://files.pythonhosted.org/packages/d0/05/707be7b14604d56f3d3d9ad852a8607d10f12b840f017fb02ae60b42fd6f/massedit-0.70.0.tar.gz",
    "platform": null,
    "description": ".. image:: https://img.shields.io/pypi/v/massedit.svg\n    :target: https://pypi.python.org/pypi/massedit/\n    :alt: PyPi version\n\n.. image:: https://img.shields.io/pypi/pyversions/massedit.svg\n    :target: https://pypi.python.org/pypi/massedit/\n    :alt: Python compatibility\n\n.. image:: https://img.shields.io/github/workflow/status/elmotec/massedit/Python%20application\n    :target: https://github.com/elmotec/massedit/actions?query=workflow%3A%22Python+application%22\n    :alt: GitHub Workflow Python application\n\n.. image:: https://img.shields.io/appveyor/ci/elmotec/massedit.svg?label=AppVeyor\n    :target: https://ci.appveyor.com/project/elmotec/massedit\n    :alt: AppVeyor status\n\n.. image:: https://img.shields.io/pypi/dm/massedit.svg\n    :alt: PyPi\n    :target: https://pypi.python.org/pypi/massedit\n\n.. image:: https://img.shields.io/librariesio/release/pypi/massedit.svg?label=libraries.io\n    :alt: Libraries.io dependency status for latest release\n    :target: https://libraries.io/pypi/massedit\n\n.. image:: https://coveralls.io/repos/elmotec/massedit/badge.svg\n    :target: https://coveralls.io/r/elmotec/massedit\n    :alt: Coverage\n\n.. image:: https://img.shields.io/codacy/grade/474b0af6853a4c5f8f9214d3220571f9.svg\n    :target: https://www.codacy.com/app/elmotec/massedit/dashboard\n    :alt: Codacy\n\n\n========\nmassedit\n========\n\n*formerly known as Python Mass Editor*\n\nImplements a python mass editor to process text files using Python\ncode. The modification(s) is (are) shown on stdout as a diff output. One\ncan then modify the target file(s) in place with the -w/--write option.\nThis is very similar to 2to3 tool that ships with Python 3.\n\n\n+--------------------------------------------------------------------------+\n| **WARNING**: A word of caution about the usage of ``eval()``             |\n+--------------------------------------------------------------------------+\n| This tool is useful as far as it goes but it does rely on the python     |\n| ``eval()`` function and does not check the code being executed.          |\n| **It is a major security risk** and one should not use this tool in a    |\n| production environment.                                                  |\n|                                                                          |\n| See `Ned Batchelder's article`_ for a thorough discussion of the dangers |\n| linked to ``eval()`` and ways to circumvent them. Note that None of the  |\n| counter-measure suggested in the article are implemented at this time.   |\n+--------------------------------------------------------------------------+\n\nUsage\n-----\n\nYou probably will need to know the basics of the `Python re module`_ (regular\nexpressions).\n\n::\n\n    usage: massedit.py [-h] [-V] [-w] [-v] [-e EXPRESSIONS] [-f FUNCTIONS]\n                       [-x EXECUTABLES] [-s START_DIRS] [-m MAX_DEPTH] [-o FILE]\n                       [-g FILE] [--encoding ENCODING] [--newline NEWLINE]\n                       [file pattern [file pattern ...]]\n\n    Python mass editor\n\n    positional arguments:\n      file pattern          shell-like file name patterns to process or - to read\n                            from stdin.\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      -V, --version         show program's version number and exit\n      -w, --write           modify target file(s) in place. Shows diff otherwise.\n      -v, --verbose         increases log verbosity (can be specified multiple\n                            times)\n      -e EXPRESSIONS, --expression EXPRESSIONS\n                            Python expressions applied to target files. Use the\n                            line variable to reference the current line.\n      -f FUNCTIONS, --function FUNCTIONS\n                            Python function to apply to target file. Takes file\n                            content as input and yield lines. Specify function as\n                            [module]:?<function name>.\n      -x EXECUTABLES, --executable EXECUTABLES\n                            Python executable to apply to target file.\n      -s START_DIRS, --start START_DIRS\n                            Directory(ies) from which to look for targets.\n      -m MAX_DEPTH, --max-depth-level MAX_DEPTH\n                            Maximum depth when walking subdirectories.\n      -o FILE, --output FILE\n                            redirect output to a file\n      -g FILE, --generate FILE\n                            generate stub file suitable for -f option\n      --encoding ENCODING   Encoding of input and output files\n      --newline NEWLINE     Newline character for output files\n\n    Examples:\n    # Simple string substitution (-e). Will show a diff. No changes applied.\n    massedit.py -e \"re.sub('failIf', 'assertFalse', line)\" *.py\n\n    # File level modifications (-f). Overwrites the files in place (-w).\n    massedit.py -w -f fixer:fixit *.py\n\n    # Will change all test*.py in subdirectories of tests.\n    massedit.py -e \"re.sub('failIf', 'assertFalse', line)\" -s tests test*.py\n\n    # Will transform virtual methods (almost) to MOCK_METHOD suitable for gmock (see https://github.com/google/googletest).\n    massedit.py -e \"re.sub(r'\\s*virtual\\s+([\\w:<>,\\s&*]+)\\s+(\\w+)(\\([^\\)]*\\))\\s*((\\w+)*)(=\\s*0)?;', 'MOCK_METHOD(\\g<1>, \\g<2>, \\g<3>, (\\g<4>, override));', line)\" gmock_test.cpp\n\n\nIf massedit is installed as a package (from pypi for instance), one can interact with it as a command line tool:\n\n::\n\n  python -m massedit -e \"re.sub('assertEquals', 'assertEqual', line)\" test.py\n\n\nOr as a library (command line option above to be passed as kewyord arguments):\n\n::\n\n  >>> import massedit\n  >>> filenames = ['massedit.py']\n  >>> massedit.edit_files(filenames, [\"re.sub('Jerome', 'J.', line)\"])\n\n\nLastly, there is a convenient ``massedit.bat`` wrapper for Windows included in\nthe distribution.\n\n\nInstallation\n------------\n\nDownload ``massedit.py`` from ``http://github.com/elmotec/massedit`` or :\n\n::\n\n  pip install massedit\n\n\nPoor man source-to-source manipulation\n--------------------------------------\n\nI find myself using massedit mostly for source to source modification of\nlarge code bases like this:\n\nFirst create a ``fixer.py`` python module with the function that will\nprocess your source code. For instance, to add a header:\n\n::\n\n  def add_header(lines, file_name):\n      yield '// This is my header'  # will be the first line of the file.\n      for line in lines:\n          yield line\n\n\nAdds the location of ``fixer.py`` to your ``$PYTHONPATH``, then simply\ncall ``massedit.py`` like this:\n\n::\n\n  massedit.py -f fixer:add_header *.h\n\n\nYou can add the ``-s .`` option to process all the ``.h`` files reccursively.\n\n\nPlans\n-----\n\n- Add support for 3rd party tool (e.g. `autopep8`_) to process the files.\n- Add support for a file of expressions as an argument to allow multiple\n  modification at once.\n- Find a satisfactory way (ie. easy to use) to handle multiline regex as the\n  current version works on a line by line basis.\n\n\nRationale\n---------\n\n- I have a hard time practicing more than a few dialects of regular\n  expressions.\n- I need something portable to Windows without being bothered by eol.\n- I believe Python is the ideal tool to build something more powerful than\n  simple regex based substitutions.\n\n\nBackground\n----------\n\nI have been using runsed and checksed (from Unix Power Tools) for years and\ndid not find a good substitute under Windows until I came across Graham\nFawcett python recipe 437932_ on ActiveState. It inspired me to write the\nmassedit.\n\nThe core was fleshed up a little, and here we are. If you find it useful and\nenhance it please, do not forget to submit patches. Thanks!\n\nIf you are more interested in awk-like tool, you probably will find pyp_ a\nbetter alternative.\n\n\nLicense\n-------\n\nLicensed under the term of `MIT License`_. See attached file LICENSE.txt.\n\n\nChanges\n-------\n\nSee CHANGELOG.md for changes later than 0.69.0\n\n0.69.0 (2020-12-22)\n  Updated infrastructure files to setup.cfg/pyproject.toml instead of\n  setup.py.  Also moved CI to github workflows from travis and added\n  regression tests for Python 2.7.\n\n0.68.6 (2019-12-02)\n  Added support for Python 3.8, stdin input via - argument. Documented\n  regex to turn base classes into googlemock MOCK_METHOD.\n\n0.68.5 (2019-04-13)\n  Added --newline option to force newline output. Thanks @ALFNeT!\n\n0.68.4 (2017-10-24)\n  Fixed bug that would cause changes to be missed when the -w option is\n  ommited. Thanks @tgoodlet!\n\n0.68.3 (2017-09-20)\n  Added --generate option to quickly generate a fixer.py template file\n  to be modified to be used with -f fixer.fixit option. Added official\n  support for Python 3.6\n\n0.68.1 (2016-06-04)\n  Fixed encoding issues when processing non-ascii files.\n  Added --encoding option to force the value of the encoding if need be.\n  Listed support for Python 3.5\n\n0.67.1 (2015-06-28)\n  Documentation fixes.\n\n0.67 (2015-06-23)\n  Added file_name argument to processing functions.\n  Fixed incorrect closing of sys.stdout/stderr.\n  Improved diagnostic when the processing function does not take 2 arguments.\n  Swapped -v and -V option to be consistent with Python.\n  Pylint fixes.\n  Added support for Python 3.4.\n  Dropped support for Python 3.2.\n\n0.66 (2013-07-14)\n  Fixed lost executable bit with -f option (thanks myint).\n\n0.65 (2013-07-12)\n  Added -f option to execute code in a separate file/module. Added Travis continuous integration (thanks myint). Fixed python 2.7 support (thanks myint).\n\n0.64 (2013-06-01)\n  Fixed setup.py so that massedit installs as a script. Fixed eol issues (thanks myint).\n\n0.63 (2013-05-27)\n  Renamed to massedit. Previous version are still known as Python-Mass-Editor.\n\n0.62 (2013-04-11)\n  Fixed bug that caused an EditorError to be raised when the result of the\n  expression is an empty string.\n\n0.61 (2012-07-06)\n  Added massedit.edit_files function to ease usage as library instead of as\n  a command line tool (suggested by Maxim Veksler).\n\n0.60 (2012-07-04)\n  Treats arguments as patterns rather than files to ease processing of\n  multiple files in multiple subdirectories.  Added -s (start directory)\n  and -m (max depth) options.\n\n0.52 (2012-06-05)\n  Upgraded for python 3. Still compatible with python 2.7.\n\n0.51 (2012-05)\n  Initial release (Beta).\n\n\nContributor acknowledgement\n---------------------------\n\nhttps://github.com/myint, \nhttps://github.com/tgoodlet, \nhttps://github.com/ALFNeT\n\n\n\n.. _437932: http://code.activestate.com/recipes/437932-pyline-a-grep-like-sed-like-command-line-tool/\n.. _Python re module: http://docs.python.org/library/re.html\n.. _Pyp: http://code.google.com/p/pyp/\n.. _MIT License: http://en.wikipedia.org/wiki/MIT_License\n.. _autopep8: http://pypi.python.org/pypi/autopep8\n.. _Ned Batchelder's article: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Edit multiple files using Python text processing modules",
    "version": "0.70.0",
    "project_urls": {
        "Homepage": "http://github.com/elmotec/massedit"
    },
    "split_keywords": [
        "sed",
        "editor",
        "stream",
        "python",
        "edit",
        "mass"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "98ba79337849b42edeb5a3283c0324c8f253cd8ef49346c7911ca23adc4f4a1d",
                "md5": "d7d987991e60113c3139d01def61450b",
                "sha256": "90d50894c90d67f4a508d3b9895a259c2ee5eb36fd6b60c5c5f38529d558c5fd"
            },
            "downloads": -1,
            "filename": "massedit-0.70.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d7d987991e60113c3139d01def61450b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.5",
            "size": 34080,
            "upload_time": "2023-09-11T03:09:28",
            "upload_time_iso_8601": "2023-09-11T03:09:28.765028Z",
            "url": "https://files.pythonhosted.org/packages/98/ba/79337849b42edeb5a3283c0324c8f253cd8ef49346c7911ca23adc4f4a1d/massedit-0.70.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d005707be7b14604d56f3d3d9ad852a8607d10f12b840f017fb02ae60b42fd6f",
                "md5": "b3c1b42978070bdce82f9c473218b138",
                "sha256": "658d932c08402c7e36b0ee1a380c8f34be9cf18dc3f8451a8854164e32b442b7"
            },
            "downloads": -1,
            "filename": "massedit-0.70.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b3c1b42978070bdce82f9c473218b138",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.5",
            "size": 20087,
            "upload_time": "2023-09-11T02:59:59",
            "upload_time_iso_8601": "2023-09-11T02:59:59.659102Z",
            "url": "https://files.pythonhosted.org/packages/d0/05/707be7b14604d56f3d3d9ad852a8607d10f12b840f017fb02ae60b42fd6f/massedit-0.70.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-09-11 02:59:59",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "elmotec",
    "github_project": "massedit",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "appveyor": true,
    "lcname": "massedit"
}
        
Elapsed time: 0.11611s