{ "info": { "author": "Austin Bingham", "author_email": "austin@sixty-north.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "|Python version| |Build Status|\n\n======\n spor\n======\n\nA system for anchoring metadata in external files to source code.\n\nspor lets you define metadata for elements of your source code. The\nmetadata is kept in a separate file from your source code, meaning that\nyou don't need to clutter your source file with extra information\nencoded into comments. To accomplish this while dealing with the fact\nthat source code changes over time, spor uses various \"anchoring\"\ntechniques to keep the metadata in sync with the source code (or let you\nknow when they become unmanageably out of sync).\n\nQuickstart\n==========\n\nBefore you can use spor to anchor metadata to files, you need to initialize a\nrepository with the ``init`` command::\n\n $ spor init\n\nThis is very similar in spirit to ``git init``. It creates a new directory in your\ncurrent directory called ``.spor``, and this is where spor will keep the\ninformation it needs.\n\nNow you can create anchors. Suppose you've got a file, ``example.py``, like\nthis:\n\n.. code-block:: python\n\n # example.py\n\n\n def func(x):\n return x * 2\n\nYou can anchor metadata to line 4 (the function definition) by specifying the starting offset and anchor width like this::\n\n $ echo \"{\\\"meta\\\": \\\"data\\\"}\" | spor add example.py 32 12 10\n\n.. pull-quote::\n\n You don't have to pipe the metadata into the ``add`` command. If you don't,\n spor will pop up an editor so that you can enter the metadata there.\n\nThe `10` at the end specifies the size of the \"context\" around the anchored code\nthat we use for updating anchors.\n\nThis will associate the dictionary ``{meta: data}`` with the code `return x * 2`. You can see\nthis metadata by using the ``list`` command::\n\n $ spor list example.py\n example.py:32 => {'meta': 'data'}\n\nThe metadata can be any valid JSON. spor doesn't look at the data at all, so\nit's entirely up to you to decide what goes there.\n\nMotivation\n==========\n\nMy main motivation for this tool comes from my work on the mutation\ntesting tool `Cosmic Ray `__.\nCR users need to be able to specify sections of their source code which\nshould not be mutated, or which should only be mutated in specific ways.\nRather than having them embed these processing directives in the source\ncode, I thought it would be cleaner and neater to let them do so with a\nseparate metadata file.\n\nFeatures\n========\n\nspor needs support for the following functionality:\n\n1. Add/edit/delete metadata to a specific range of text in a source file\n2. Query existing metadata\n3. Automatically update metadata when possible, or report errors when\n not\n4. Provide facilities facilities for \"updating\" metadata with new\n anchoring data\n\nThe design needs to be sensitive to both human users (i.e. since they\nmay need to manually work with the metadata from time to time) as well\nas programmatic users. I'm sure the design will evolve as we go, so I'm\ngoing to try to keep it simple and explicit at first.\n\nIdeally spor will work on any programming language (and, really, any\ntext document), though its initial target will be Python source code.\n\nDevelopment\n===========\n\nSpor is new and small enough that we do fun things like try out new tools.\nInstead of `setuptools` et al., we're using `poetry\n`__. So if you want to contribute to spor,\nthe first thing you need to do is to `install poetry\n`__.\n\nTo install the package, use::\n\n poetry install\n\nTests\n-----\n\nThe installation command above will install all of the test dependencies as\nwell. To run all of the tests, run |tox|_:\n\n.. code-block::\n\n tox\n\nTo run just the `pytests` unit tests, run::\n\n poetry run pytest tests/unittests\n\nTo run the `radish` tests, run::\n\n poetry run radish tests/e2e/features -b tests/e2e/radish\n\nNotes\n=====\n\nThe field of \"anchoring\" is not new, and there's some existing work we\nneed to pay attention to:\n\n- Bielikova, Maria. `\"Metadata Anchoring for Source Code: Robust Location Descriptor Definition, Building and Interpreting\" `__\n\n.. |Python version| image:: https://img.shields.io/badge/Python_version-3.4+-blue.svg\n :target: https://www.python.org/\n.. |Build Status| image:: https://travis-ci.org/abingham/spor.png?branch=master\n :target: https://travis-ci.org/abingham/spor\n.. |tox| replace:: ``tox``\n.. _tox: https://tox.readthedocs.io/en/latest/\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/abingham/spor", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "spor", "package_url": "https://pypi.org/project/spor/", "platform": "", "project_url": "https://pypi.org/project/spor/", "project_urls": { "Homepage": "https://github.com/abingham/spor", "Repository": "https://github.com/abingham/spor" }, "release_url": "https://pypi.org/project/spor/1.1.3/", "requires_dist": [ "docopt_subcommands (>=3.0,<4.0)", "exit_codes (>=1.1,<2.0)" ], "requires_python": ">=3.4", "summary": "A system for anchoring metadata in external files to source code", "version": "1.1.3" }, "last_serial": 4627744, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "2c42b446d14a3d3df1d6588b13aa488d", "sha256": "5abf56dd842ec4151a3c0a8ac41acd08096ed1b01f001c13c3b0cc55e4cd8cd3" }, "downloads": -1, "filename": "spor-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2c42b446d14a3d3df1d6588b13aa488d", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 13909, "upload_time": "2017-11-27T13:36:00", "url": "https://files.pythonhosted.org/packages/21/7b/bd2ca6bee249c1387a683d9222a74d1ea6eab83b13d1345fe198e4bd87a4/spor-0.1.0-py2.py3-none-any.whl" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "45d311df8624f47638abf5e387075a6f", "sha256": "d47dfd433e70fd745e26eac8a032a9ebaa9b5b0f02e5e05903d74d34d5ff2fd7" }, "downloads": -1, "filename": "spor-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "45d311df8624f47638abf5e387075a6f", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 13960, "upload_time": "2017-11-28T07:42:44", "url": "https://files.pythonhosted.org/packages/db/84/7fa9b67e9302b4c876346178dc32a501bcb88385aa08caa131f302878ff5/spor-1.0.0-py2.py3-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "4400412d9f1bee883b4772976e622300", "sha256": "1524227c6f98e2858447718ffb95fd850d808f7ee9ee1adc4d4eb95a8cb320ee" }, "downloads": -1, "filename": "spor-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "4400412d9f1bee883b4772976e622300", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 13936, "upload_time": "2018-03-04T15:38:32", "url": "https://files.pythonhosted.org/packages/c0/16/f22d49c6dad379adfbebad028a332a538e73591b21a387176dcc108e1e89/spor-1.0.1-py3-none-any.whl" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "b01fe2c9fd9a3d1263fdff199990f842", "sha256": "e1c4d1624150d73379ee5dccacba6fce116e4594f58d3e7e0316a126408320f8" }, "downloads": -1, "filename": "spor-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "b01fe2c9fd9a3d1263fdff199990f842", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 13928, "upload_time": "2018-03-05T14:53:39", "url": "https://files.pythonhosted.org/packages/5c/02/8ff022acc9b7c66c733f7795b4277ba64b7e9c2e6912ab41affc97018000/spor-1.0.2-py3-none-any.whl" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "11568ae7b7cbd128fe35b9c580fa5ed5", "sha256": "b3f5985d3e1ed0f94e5c363ee10c92b0791728c972bacf70a9a46c25625bcb54" }, "downloads": -1, "filename": "spor-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "11568ae7b7cbd128fe35b9c580fa5ed5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.4", "size": 36358, "upload_time": "2018-11-07T08:45:22", "url": "https://files.pythonhosted.org/packages/b9/b3/52cae6e41eccaa9e63c07b5345bc6676befed5d3a57677aa6ca5573d36e1/spor-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b2b8ce40497763b5f438370dbdd00a98", "sha256": "602a528e6a9ca4ddd8b35ffdaed66595524f9ebdc7bc3af73ec3b3bcd4dbeebb" }, "downloads": -1, "filename": "spor-1.1.0.tar.gz", "has_sig": false, "md5_digest": "b2b8ce40497763b5f438370dbdd00a98", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 14684, "upload_time": "2018-11-07T08:45:23", "url": "https://files.pythonhosted.org/packages/11/cc/48276c9af692be0608ca7071c2d5bf3aaca2f70beede1bcc56fdbf59d16f/spor-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "c1daae0987f23fb854936ab8c53c8d47", "sha256": "0a7e2a5bb65c51c066227e3696c64bd44c20d2dcd9646b6caf260040f7a9f951" }, "downloads": -1, "filename": "spor-1.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "c1daae0987f23fb854936ab8c53c8d47", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.4", "size": 36376, "upload_time": "2018-12-12T09:23:52", "url": "https://files.pythonhosted.org/packages/6a/7b/2e4a4bc0a60cc75c4694e65e89a5a207b5662889983a7424d5e1ed24b044/spor-1.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "829bdb593af54a99a4a98b3594a2f4b5", "sha256": "5804462c58ef94ddf158359439f4058b99988fd21c34621ff4c8f3bdb1d92b46" }, "downloads": -1, "filename": "spor-1.1.1.tar.gz", "has_sig": false, "md5_digest": "829bdb593af54a99a4a98b3594a2f4b5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 14671, "upload_time": "2018-12-12T09:23:53", "url": "https://files.pythonhosted.org/packages/01/82/118d35d6c8004a2e3017b4ae2a4e266ed19b3eeca0fcd6be0de80864dff2/spor-1.1.1.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "109c1db2da07aed9137c8d08701cfcac", "sha256": "55b8fe69be90cf39b0b847317c8ccc3b5f5d1241b8e2f28f3da9ca9517899497" }, "downloads": -1, "filename": "spor-1.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "109c1db2da07aed9137c8d08701cfcac", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.4", "size": 36310, "upload_time": "2018-12-12T11:33:11", "url": "https://files.pythonhosted.org/packages/98/f2/450dc8c4eccbffb5506e6ae8b1422d28aeed0953a855f937b3b5b9c5f652/spor-1.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4aa9e8b4fad8ec3c93622b1fdec4dffd", "sha256": "2184e084afe464ef0527663df10a901d3cf808f00c87831d7e5579c9f604d6b5" }, "downloads": -1, "filename": "spor-1.1.2.tar.gz", "has_sig": false, "md5_digest": "4aa9e8b4fad8ec3c93622b1fdec4dffd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 14672, "upload_time": "2018-12-12T11:33:12", "url": "https://files.pythonhosted.org/packages/b3/f2/3678daf3416ea2f60fd5b4bb428e430d7f4b0d384fe138c9727950a6f27a/spor-1.1.2.tar.gz" } ], "1.1.3": [ { "comment_text": "", "digests": { "md5": "41f8f2972c2a28e3b239a8ba9d9c32c3", "sha256": "61adb057b07023dc48ad8c94e69c1b74360b7087a254a25d10008fb3e68b5b67" }, "downloads": -1, "filename": "spor-1.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "41f8f2972c2a28e3b239a8ba9d9c32c3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.4", "size": 36332, "upload_time": "2018-12-22T13:11:06", "url": "https://files.pythonhosted.org/packages/9f/60/1144ef9ae304cef3b8dbed082a187f530e9c6d77c218e75f1e775170b557/spor-1.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "95e1cc718ffcb4d3d4b94b7da576cbf3", "sha256": "2537e45e1d3713bacdb49b98be6a1884799337efe04e199703b1b061b87605ff" }, "downloads": -1, "filename": "spor-1.1.3.tar.gz", "has_sig": false, "md5_digest": "95e1cc718ffcb4d3d4b94b7da576cbf3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 14628, "upload_time": "2018-12-22T13:11:08", "url": "https://files.pythonhosted.org/packages/25/e4/3ad704ce60e601e6f7818852ed1527a710204cfba99f000eea3fb5f4edbd/spor-1.1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "41f8f2972c2a28e3b239a8ba9d9c32c3", "sha256": "61adb057b07023dc48ad8c94e69c1b74360b7087a254a25d10008fb3e68b5b67" }, "downloads": -1, "filename": "spor-1.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "41f8f2972c2a28e3b239a8ba9d9c32c3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.4", "size": 36332, "upload_time": "2018-12-22T13:11:06", "url": "https://files.pythonhosted.org/packages/9f/60/1144ef9ae304cef3b8dbed082a187f530e9c6d77c218e75f1e775170b557/spor-1.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "95e1cc718ffcb4d3d4b94b7da576cbf3", "sha256": "2537e45e1d3713bacdb49b98be6a1884799337efe04e199703b1b061b87605ff" }, "downloads": -1, "filename": "spor-1.1.3.tar.gz", "has_sig": false, "md5_digest": "95e1cc718ffcb4d3d4b94b7da576cbf3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 14628, "upload_time": "2018-12-22T13:11:08", "url": "https://files.pythonhosted.org/packages/25/e4/3ad704ce60e601e6f7818852ed1527a710204cfba99f000eea3fb5f4edbd/spor-1.1.3.tar.gz" } ] }