diff --git a/.hg/git-mapfile b/.hg/git-mapfile
new file mode 100644
index 0000000..d6ebbfe
--- /dev/null
+++ b/.hg/git-mapfile
@@ -0,0 +1,103 @@
+9f81d3d888f8938d9859cc86d50aa57bb4b43727 00e9d51b3a770521b0cd6db9e25ef6e46dae9ef5
+d970f80e9cbc724a872ec648ea6fd04e25e2b591 02903639eb1ddda839004e8ef7ddfd439e65cd8d
+3a2b9ede11ea4f600caf038ef1a651c30fd9de75 0872b1c70d8d4e52089037b89bf932dcf618fa5f
+7b201e93964b2d423b71b6253ea59258faa9dd11 0a4f4bc4c76402641c2a454409896a3f16ab4429
+58e0f6d292b5fcfb81784b277b988fd457f45ae2 0a5404288af5aa008b3bc24b5a452a87fc63b329
+7c8d84499bf59b04fc3835ac579a353bc761efa5 0a85f62245363e4f7cb9df40905e91f63319af3e
+93df73bc6e08e712231a06e9fd6527ebc127a0a8 0bd93594becc10d430ba3cc8511f0db095a7f8e8
+c763df9aae5e719d3e6ad0e513ccc43bba6c90db 0c5daa56803458881798430a95cc88c73e2d0582
+36d76bd7d1f4eab571dd6562082d9d811f632a1b 1566ef0425d207227914f7755ac7bb0111f3ca75
+a9603398b0d2ca38e072d86fa8486909340c059a 15e83afdb35ea072843a6352c2e09b78b8658778
+bedb355037c1b9ee12a208c4d3f5a00a7e0abb57 164ac40c3cbf0cf245780eadbd11aa9c4e74ac92
+2c51f6f642beddf66ed8dbb169c4ad2e8f8f2b0b 17798d5e593ccdfbf13eb28516580b8a37220d4f
+87ac002c1da2090889020454af05a536cf5af212 1c91942c5fd22698a35a92ec19dfa104059307a9
+99764065bf2b1b212df86bf469b081cdde14b1a6 1f01dd72f0cfe1fdc0d5ed2eb6cce3c557867803
+eceacc6a32e9850be50cdec5f7e4a2142bc4060e 2286a334f42df5ec77e459c82f648afac98182e1
+3ba825b7de325104491c5bb9c03f5f1632d63718 2400506af5974fab6a57447d0764b09a5922d1c4
+18f5a3e5635436c053a71ee1d959140574edf249 25eb17f1e4f2c46b0ed5c4d255bcad5b7b4c9561
+0667afdf2bd68334621a91d526bc1197ab0c05e9 2e4e5af5f0e5c2fc822ddea5fd63660811271400
+76ad9914e41d8ac4b576623fdea5c4a0434bda12 2e911d9ed37684e83dc50d45829e31ee6b351374
+409ec9239dfb98012ad4cd1f3a70db99902b162b 331c914a717951fe6a0ef4b6714e5e5d3d2e5fc6
+29035e73a2d553ac2e287afdb91cb4deda1b7f68 34343bdde6832c506f1dded7b89c25a5ad563d86
+f1f6daef8ba5c997814507a313c3d3ebaae217aa 3d49a8ecae5eb4f636d061267e1a6c999997f32e
+78a0329c3968973590444d9b6dfbc9fdc565e6c2 3e6b61a743710ec8c053e29be28f818131f3690a
+94510e3b1c7b962516bcacca86765a4c4f5c43b6 41815783a97d9dbdf3b05a2b6733b0dcabdc3218
+53a6a4dc0ec13f6a1761d21b431d9ab1c8fec37b 424d31918d8c63786662c99d054f10b456e8a1b2
+29d51acd660bda3cfc7054f7c8b5a0142d7f5e21 42fbf6b460e9f60466d3c77fd8a1c8d37707f477
+f3bffdb1912e74622f1fcb125e9cdf4982576c56 448664201b8dc77089639aca0a741fda29259a2d
+5a5b29e3b818b2e02b063b10a68b7e2f6d6af8f3 459434b3875d2d824ad91e47f09c2fd119277756
+8fe8821689d22fe6c58b4a1132f316af1c211edd 46ee8a83ba2464cea3f3ef8e3a24e43122cc08de
+6e6780ec27276c78954913794494c8d5360a9cd5 4781cf71911b11f214692d82cb89cac30096b3ee
+da462ed5c987412f7f171dd915e328ff9a7b4175 484a0c89c24d520d15245f669393862315b7b3b2
+57734a7ee0a17deace829039239cca9d52291603 4967887a5196a650a16dc29dc54bf1d093ad85bd
+404e0296d649f0a63042c19322182d9c86da81a4 50ef545b102d7757a96857fe51ce555564780052
+9c0cf948f4850c3b14ada481616b13f041e1849e 5286ae3976341a5ab6f83039a8c6ad2ce14e8d2a
+08bb9cf76d970f1f88187685561e9578bacbc809 5374c323354f060ba51308e26115eee0847af396
+a45bea1c7c2a8f9a79fe1cd1f0585fde8ac28750 57eb510624fb6b05133b680232c5e821864e9005
+2de8b5a11d9cabc20dc97eaf4577136ad5491102 58b9c4f1309b45c64f14c6d6ea5da25d5c34a4b0
+24589019b444b64e1229a5df4935f72c860cf678 590bb83e48e0194ac5e6e4a12db65348b63adf92
+d0f1c7bd84bbd35c6ae538f04e15e66ebc4a11c5 5f81070c7837d55f36644f77f8dbcb203cd219b7
+2833cdeb90c22eee31de1c54281dd040b18d828d 611450df9c78b9ead2bfa63480cca192dab96f57
+6ad0aa3e46e8d83e1382a0c60700c6b7de61d057 612e2c2e35aede0aae070d9d651be8004f4be543
+998d8c42988ea6c070af58e59f0c49c29084c97a 624820983a6c5c8058125500f5a026b06ec55a1f
+56f819128ec0151a34f6bbdc9a6349bab95cc2d8 6264a18cf45de9c5245f298d4f7fb1f453e15af2
+c8e781c7d39f96a15decf83927705f663391927d 62733c122962ad783188b2d4e3a79f19093fd17c
+b17158624edd118ffc97ea6d93017755d26bf95e 62d74835a1e7045002bb7d85b600c5857a5235ad
+cb5c592b7da851df68c6bf90965c9afec44ce019 63367a1d7d5d26c04bab5e4a3821d47b14a16456
+1f0714788a8785c54a2555b79ef9b8f9e162fa23 6611f4ebe6609a7bd10cb537a76b5f04e474c573
+508f1b15bc3f4c465958dd1056f6802980133244 668a3e5341e35274eda6be8c69814297d2cae4f5
+176961037f5813e414decc8c5ce7eff7c2d59c86 6b512982b7f8ba3b5e191c7ef16772ba72cabd7d
+426c8b96b4a8185102e40c74545c75f233da053a 6f6d0e796655faa43b6c3833a652ae0108a35211
+5c46c493646aae9fc5c50fd925b821e1cbf0f9a1 6fbf08054b215eb65bcee5e57f974fd3ea96c58a
+6e9a9c2deb324583e45250228bbd667b40d81fbb 6fff894b201cccfd7257a685561e94f8c00407d5
+967a7f6bf06ab1cdddc4c1b1b744c3bb90e715d2 7388b6cc134f406394a52a7f85fb83a675d49a3c
+6eb988547172d651e4b227c7f12c7e573710e5d4 7438c2bfd13b169720b9a2cc8157d471977a3a0b
+76ca9ee20d8ec835a947bc99e831dea8e7920661 76ce61b51e9d9aa67d652fbd75d9d03080c18212
+3acff83f93a0bb4b4cdd7acf77e0f382e8c5efdf 7c7d375fa75185b74552276f075aefabc90cd747
+e940456e217be8ba5419b3c1d3ec94a3adb2f944 7cfcfb573eab5f67afafc32680ae1e3b4e9203a7
+de791ee4334e8a97b0647cf86f612d45c599a087 8321c71fd90cf35c016a039c9d868cacce4d873c
+ebdae1b5a90c21f662ca500819b25e58c39064c4 8388b99b74f00e195062025b2071cad2b4812fc0
+2723aa644cb1bffed04c425d1b9cb81d965fafdc 84e7f29f37da51b7a5fc2b4149caea4176e08368
+48d09d2d607b86fe23ab738eb623bffeee1af025 86a3cf2fc04df195701db3b8b15dd727c31b18f0
+fbc855583fa2990ec84165b960314df1fe951eb7 892401417051e57ea9cb214af4b73d1b9514f08e
+bacde7638ac574132dab6245f9314b528333e4fb 8c8932d785a4e96c32e9d18c6702042d9973a6df
+efe3a7ef653e9e1fb6511521af3b069b98ff2e8d 9093beff7c14e4b642552685bb27cc72a1f73227
+afdcd366be7a7b00bfe09312b59b9c6fa48b8582 95a6bbaa8c35874dcff8b94c38a91abd920740c6
+d1dfb199d6390b77f58a61ca6a0c0be1c4bf3ae9 96f48c4d974bac6c904020deffd02847d45811b6
+d5cf7c9f14d94c164185eaf81f00667b6a9fddcd 9742fa1537e23c654fca2b3e762cbda02d77a72d
+7777e02629d050bfec891d0f8bc90c2515537374 97b5e2e533b98ef79c4b8df4410d364f7029641f
+21b4c7e118111fea5ad6af774079c8cdd5cbaa8e 97dbeeccff9bce836aef67cd4db8d54a3ddeba1c
+1e4e911edb32967a9d20cef4625932175e8eb56c 9cef44d8c693072e1ce986c3a5e3a4a654746f9d
+133481a0baeb2427de00572b9100e67452973cf3 9dc0978b3f813d1ccb251dafe40e15038e1f0cda
+7427d1c91d75f959ef6e3025741eaa4ff8f97bd3 9e90046fda4240bb62192ef69968a69403b78bab
+273dbd4996348a258affcc39477bdeb2051f34d7 a54e2260976515e2b8ef7742a6d95c047ee32330
+061194419e3c0defb79a76c4b1fc85afdd3e36e7 a9ba5dc64fe2a08eb3a3cd3cbc5fedc9e85bde61
+a482db25d35c4a047a5a7fed018903ee17fcfcd2 aba85ac786e3f4ac2fa2fccc729a2f40170b8274
+b9fd0a00f8851912e959212279fd339a34ed2523 ae1e2de45db2bab2565577d0f158174038cbf1ea
+5f7443b31bbb1ea449cac69f03b106bc2808d88f b02e3a3a54ca7e1d530edc39bf2c5f82192f311a
+cb53a871305169cae8e5238501d4eb60e97c3110 b17bec971b0403aa751231b4880ba9c839d28872
+f0c0ee7548c5cfdf86f240dfd9213429667b08f6 b7a487551e09b680bae1ed519f79dfb544b4f2af
+063aaf569315880a394ba08d88c6b3460ff48e50 b8289db46a9711177dda330aca0ae9bb3063371f
+5b5bee1def0f693d35aaf964e59d2598934f1644 b9c26193e09eb45c097946d324a69e697434df29
+29ecec8dc5592688e229dae26bf340129ab5e2e7 ba585817769b4109cd572ca781a7c0273db1dec7
+22ca48440f742b08f738323225b188bca39b5cc7 bc82193a022060f8fa10409d044148591fd2547b
+65cfacff473c9ee8afdfaaa6f39e5f3e3f19e1f6 c068d376f254a456040b80bc9a18b36da20c15ac
+aa555ff2c2e9a4e468a7ac7d73ee8a1468a6f0b5 c3f8ddd9ad97a82ff4747ede8a18ec92bc6c98dd
+b97b6e65b383271936891ef60477436d3f8fe0b1 c48dabcc9088dd1338ddd150b9b190358cef723d
+4f571e7e7bf5e31df9adaf6b082638fad777d8f1 c65df7ee258cf5bd880cd7bcf8b22da510634361
+610fbe3215b3caed88a1b334d85fe88ff6595425 cfba49842e492ae72de2d84df7ca24637d8c886f
+020801e6efae585bab78546794e7af5023c4383d d960d1afbe3777ce42ced97b0b5c4656909bd1e7
+e85534ff10c6a1fcd5101ba39c80bc08c48a3bd6 da226d1fb7d0feee63a233b3174490a35c8a6456
+47de7d7bb3edd71776105088ffbf25451d73f769 dbcb700e0e12086be601e3c1756ebb098d689edf
+9734ff637e3e04abfd2d142799aac7da07519bc9 dcb7b652ad54f3915ebe6e0acb01288db61f1cc2
+3aba2bb58401255da419ca1da5b68b9f91a00ba9 ddb0c0b81de262005f7682d6d0f52c89918819c1
+3625decc9530d62b9e21dee5a5461d3451fd78b0 e505ee2cf8a5767c299276e8a813896734011a0a
+91817e3a3495ea432ef41108f51a4bf08259202a e59bed086ec8a6dfb29771bf09e8d77da6140c1a
+5b60cec7d897dfc9e50781b104eb1e1fc94e246f f04c6af254136439d7e56e21bdf805bed6eaf199
+62a095e441920b597b914ef2d11eb5598f21ca8f f077738507b9b24fa5c8ecd023f714043d2a1a76
+d38de428ccea7f5dc83d8018953e73162570fe3d f0ed2d880ba024ceacce7e69e768fb1782bc6c24
+1673e9edb9529b91b7d86fd3055e8ac745d2d9c4 f44bd54125a26204d5153960a5d861ad2a84d21b
+aca6cecf027a0ab3732651ec22f682836c1f5526 f4f1529b887d39de93ab263f90a58de7ca294d8c
+947de7b4ecac1a86b0f6170ef59610716835e214 fa2d1ae584502a8d7a940c847efaebf2aef26a35
+1c95a23b6c37e1e4606c6084a21f8c54670ab2a0 fc0a61e120205de9fcf98a1c10ed823720b04e87
+cbcd6ed0b8096d4e8d21e88be2e63a6cf28e775f fcc90295e2afe1fda4baeb50558f6628ce50cd65
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 6fc78a6..0000000
--- a/.hgignore
+++ /dev/null
@@ -1,29 +0,0 @@
-~$
-\.diff$
-\.orig$
-
-\.pyc$
-__pycache__/
-__version__\.py
-
-\.cache/
-\.pytest_cache/
-
-^\.ipynb
-^\.tox/
-^\.env/
-^\.coverage
-
-^output\.xml
-^log\.html
-^report\.html
-
-\.egg$
-\.egg-info/
-^\.eggs/
-
-^build/
-^dist/
-
-^\.venv/
-^\.conda/
diff --git a/.hgtags b/.hgtags
deleted file mode 100644
index 40e1164..0000000
--- a/.hgtags
+++ /dev/null
@@ -1,8 +0,0 @@
-f4f1529b887d39de93ab263f90a58de7ca294d8c 0.1.0
-bc82193a022060f8fa10409d044148591fd2547b 0.1.0.post0
-7438c2bfd13b169720b9a2cc8157d471977a3a0b 0.2.0
-611450df9c78b9ead2bfa63480cca192dab96f57 0.3.0
-cfba49842e492ae72de2d84df7ca24637d8c886f 0.3.0.post0
-484a0c89c24d520d15245f669393862315b7b3b2 0.3.1
-dcb7b652ad54f3915ebe6e0acb01288db61f1cc2 0.4.0
-164ac40c3cbf0cf245780eadbd11aa9c4e74ac92 0.4.0
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c7c7e9a..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-sudo: false
-git:
- depth: false
-
-language: python
-python:
- - '2.7'
- - '3.5'
- - '3.6'
- - pypy
-
-install:
- - python -m pip install -U pip setuptools six wheel
- - python -m pip install -U -e .
- - python -m pip install -U -r requirements.test.txt
- - python -m pip install -U tox tox-travis
-
-script:
- - python -m pytest -vv --doctest-modules nodely test --cov nodely --cov test --cov-report term-missing --cov-fail-under 100
- - python -m robot test
- - python -m tox -r -v
-
- - python -m pip install zetup[all]
- - python -m zetup install
- # - python -m zetup pytest
- - python -m zetup sdist
- - python -m zetup tox
-
-deploy:
- provider: pypi
- user: userzimmermann
- password:
- secure: mQ7VZcdtXVvDK4tiSd491O+z3WV1svcLFjsh5lY8VCAWWovsQjzD4Eq6FdByZ2CYR4HJSPVbo7gg5HS+HvXMUMYIJrlwFTc80dnoHQvpQ6U9Ne2aN0iOsKu7JVG1z1NbgnNMu8RE/w6CQuxkTjVszdjMgElvlKMMX+F/W3sPBTzeIF4B5QpUXiea7sXTDTIDLRhBA4rG+q8U75IdtlSouC6pZAbKgBkJ40SMjK4VXVoT5H/3disc2zNN88ZZ0uKXNcCoeLpfHvO3c+/u99OY3tGfY7DafvyqvzoSxW2RKxH4gqnq61wtsELSoP1cn2AqxE5reLTobHQ4b4bPLM6hKc94KRiT+epf9H9X2/WFSSbjqEXhCnhMtmuqxqWmUu4illvuhg1LTE9hNkI3WYdpppParBRloYAl9ycL8VLB5fSkQ1M5L7ZVNYfidMO9/3a8shgLzRLWFlfPIyq2/XELK1N+c8k5GTiW8g5y+xLaet7u0BGCw6y14c8D4TtgYbnQLn2iJMsrMUcr/613GpPrMwjVodeIZb29ZBr5p0U0ME9DzMkCZ49Yj210RMPwEanw5KF2pv11jdoMCCN6e34bl3q5X4d8OrNYBjNRtnEO32CVM1WGkPAO6yKLu8BMWnRujJDHUNslaDB5PgPwG2kgdMD4+SYhKFPumYIEul+2LtU=
- on:
- python: '2.7'
diff --git a/CHANGES.md b/CHANGES.md
deleted file mode 100644
index b423226..0000000
--- a/CHANGES.md
+++ /dev/null
@@ -1,56 +0,0 @@
-### 0.4.0
-
-> 2019-08-19
-
-* Use `zetup.toplevel` wrapper for `nodely` package, and `zetup.module`
- wrapper for `nodely.bin`
-* Use `whichcraft` to determine absolute path of real `npm` executable for
- `nodely.install` and `nodely.uninstall` functions
-* Change `path.py` requirement from `~= 11.5` to `>= 11.5` for Python 3
-* Drop support for Python 3.4, and add support for 3.7
-
-### 0.3.1
-
-> 2019-07-29
-
-* Restrict requirement `path.py` to `~= 11.5`
-
-### 0.3.0.post0
-
-> 2019-07-29
-
-* Update `CHANGES` for __0.3.0__ release
-
-### 0.3.0
-
-> 2019-07-28
-
-* Add `.check_call` and `.check_output` methods to `nodely.bin.Command`,
- the class of the Pythonic `nodely.bin['...']` instances for running
- installed Node.js tools
-* Make `nodely.bin.Command.__call__` wrap `.check_output` instead of `.call`
- and take variable `*cmdargs` parameters instead of a single positional
- `cmdargs` sequence parameter
-* Define `nodely.NodeCommandError` based on `subprocess.CalledProcessError`.
- It adds the working directory to the basic exception message and is raised
- from `nodely.bin.Command.check_call` and `.check_output`
-
-### 0.2.0
-
-> 2017-09-12
-
-* Provide new setup keyword `require_node_modules`
-
-### 0.1.0.post0
-
-> 2017-08-27
-
-* Updated `CHANGES` for __0.1.0__ release
-
-### 0.1.0
-
-> 2017-08-27
-
-* `nodely` package with `install`, `uninstall`, `which`, `Popen`, and `call`
- functions
-* `nodely.bin` proxy to `node_modules/.bin/` directory in Python environment
diff --git a/COPYING b/COPYING
deleted file mode 100644
index 94a9ed0..0000000
--- a/COPYING
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
diff --git a/COPYING.LESSER b/COPYING.LESSER
deleted file mode 100644
index 65c5ca8..0000000
--- a/COPYING.LESSER
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/README.ipynb b/README.ipynb
deleted file mode 100644
index d33c822..0000000
--- a/README.ipynb
+++ /dev/null
@@ -1,441 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# nodely >>> putMORE Node.js into Python"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "[](\n",
- " https://gnu.org/licenses/lgpl.html)\n",
- "[](\n",
- " https://python.org)\n",
- "[](\n",
- " https://pypi.python.org/pypi/nodely)\n",
- "[](\n",
- " https://pypi.python.org/pypi/nodely)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "[](\n",
- " https://travis-ci.org/zimmermanncode/nodely)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "* [**Embed**](#Embed-node_modules/-in-Python-environments)\n",
- " **`node_modules/` in Python environments**\n",
- "* [**`require`**](#require_node_modules-in-setup.py)**`_node_modules`\n",
- " in setup.py** \n",
- "* [**Run**](#Run-installed-Node.js-tools-from-Python)\n",
- " **installed Node.js tools from Python**"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Setup"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Use [pip](http://pip-installer.org) to install the latest [release](\n",
- " https://pypi.python.org/pypi/nodely) from [PyPI](https://pypi.python.org):\n",
- "\n",
- "> `pip install nodely`\n",
- "\n",
- "And don't forget to install [Node.js](https://nodejs.org) ;)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Embed `node_modules/` in Python environments"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import nodely"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Many great tools are written with JavaScript in [Node.js](https://nodejs.org).\n",
- "It makes sense to use them in Python instead of reinventing the wheel.\n",
- "`nodely` provides an API for managing local `node_modules/` in Python environments\n",
- "and running the installed Node.js tools from Python"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "If the root directory of the current Python environment is:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'C:\\\\Users\\\\Zimmermann\\\\Miniconda3\\\\envs\\\\nodely'"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import sys\n",
- "\n",
- "sys.prefix"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Then `nodely` will create:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Path('C:\\\\Users\\\\Zimmermann\\\\Miniconda3\\\\envs\\\\nodely\\\\node_modules')"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "nodely.NODE_MODULES_DIR"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "_Please don't modify the above constant, except you exactly know what you are doing ;)_"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's say you want to use the [CoffeeScript](http://coffeescript.org) compiler...\n",
- "Just install the Node.js package:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "nodely.install('coffee-script')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "It provides the `coffee` executable. If you want to know its absolute path:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Path('C:\\\\Users\\\\Zimmermann\\\\Miniconda3\\\\envs\\\\nodely\\\\node_modules\\\\.bin\\\\coffee.CMD')"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "nodely.which('coffee')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "And if you want to run it, for example with the `--version` flag:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "nodely.call('coffee', ['--version'])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For the case that you want to get rid of the package again,\n",
- "just `nodely.uninstall('coffee-script')` it"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### `require_node_modules` in setup.py"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Instead of installing Node.js packages during runtime,\n",
- "you can also define them as dependencies of your Python package:"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "```python\n",
- "from setuptools import setup\n",
- "\n",
- "setup(\n",
- " ...\n",
- " setup_requires=['nodely', ...],\n",
- " require_node_modules=['coffee-script', ...],\n",
- " ...\n",
- ")\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "So they get implicitly installed during the installation of the Python package,\n",
- "just like the Python dependencies defined in `install_requires`"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Run installed Node.js tools from Python"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The `nodely.call` function additionally supports `subprocess.call` options:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from subprocess import DEVNULL\n",
- "\n",
- "nodely.call('coffee', ['--version'], stdout=DEVNULL)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "And instead of a simple `nodely.call`,\n",
- "you can also create a process instance,\n",
- "and give any `subprocess.Popen` options to it:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from subprocess import PIPE\n",
- "\n",
- "process = nodely.Popen('coffee', ['--version'], stdout=PIPE,\n",
- " universal_newlines=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'1.12.7'"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "process.communicate()[0].split()[-1]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "A more object-oriented approach is provided by:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import nodely.bin"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "It lets you introspect all installed executables with interactive auto-completion\n",
- "and creates `nodely.bin.Command` instances:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "coffee = nodely.bin.coffee"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`nodely.bin['coffee']` returns the same.\n",
- "And that `nodely.bin.Command` instance provides its own `.call` and a `.Popen` methods,\n",
- "and can also be called directly instead of using its `.call` method:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "coffee(['--version'])"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.6.2"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/README.md b/README.md
deleted file mode 100644
index bef26ae..0000000
--- a/README.md
+++ /dev/null
@@ -1,245 +0,0 @@
-
-
-# nodely >>> putMORE Node.js into Python
-
-
-
-[](
- https://gnu.org/licenses/lgpl.html)
-[](
- https://python.org)
-[](
- https://pypi.python.org/pypi/nodely)
-[](
- https://pypi.python.org/pypi/nodely)
-
-
-
-[](
- https://travis-ci.org/zimmermanncode/nodely)
-
-
-
-* [**Embed**](#Embed-node_modules/-in-Python-environments)
- **`node_modules/` in Python environments**
-* [**`require`**](#require_node_modules-in-setup.py)**`_node_modules`
- in setup.py**
-* [**Run**](#Run-installed-Node.js-tools-from-Python)
- **installed Node.js tools from Python**
-
-
-
-### Setup
-
-
-
-Use [pip](http://pip-installer.org) to install the latest [release](
- https://pypi.python.org/pypi/nodely) from [PyPI](https://pypi.python.org):
-
-> `pip install nodely`
-
-And don't forget to install [Node.js](https://nodejs.org) ;)
-
-
-
-### Embed `node_modules/` in Python environments
-
-
-
-
-```python
->>> import nodely
-```
-
-
-Many great tools are written with JavaScript in [Node.js](https://nodejs.org).
-It makes sense to use them in Python instead of reinventing the wheel.
-`nodely` provides an API for managing local `node_modules/` in Python environments
-and running the installed Node.js tools from Python
-
-
-
-If the root directory of the current Python environment is:
-
-
-
-
-```python
->>> import sys
->>>
->>> sys.prefix
-'C:\\Users\\Zimmermann\\Miniconda3\\envs\\nodely'
-```
-
-
-
-Then `nodely` will create:
-
-
-
-
-```python
->>> nodely.NODE_MODULES_DIR
-Path('C:\\Users\\Zimmermann\\Miniconda3\\envs\\nodely\\node_modules')
-```
-
-
-
-_Please don't modify the above constant, except you exactly know what you are doing ;)_
-
-
-
-Let's say you want to use the [CoffeeScript](http://coffeescript.org) compiler...
-Just install the Node.js package:
-
-
-
-
-```python
->>> nodely.install('coffee-script')
-```
-
-```
-npm http GET https://registry.npmjs.org/coffee-script
-npm http 304 https://registry.npmjs.org/coffee-script
-coffee-script@1.12.7 node_modules\coffee-script
-```
-
-
-It provides the `coffee` executable. If you want to know its absolute path:
-
-
-
-
-```python
->>> nodely.which('coffee')
-Path('C:\\Users\\Zimmermann\\Miniconda3\\envs\\nodely\\node_modules\\.bin\\coffee.CMD')
-```
-
-
-
-And if you want to run it, for example with the `--version` flag:
-
-
-
-
-```python
->>> nodely.call('coffee', ['--version'])
-0
-```
-
-```
-CoffeeScript version 1.12.7
-```
-
-
-
-For the case that you want to get rid of the package again,
-just `nodely.uninstall('coffee-script')` it
-
-
-
-### `require_node_modules` in setup.py
-
-
-
-Instead of installing Node.js packages during runtime,
-you can also define them as dependencies of your Python package:
-
-
-
-```python
-from setuptools import setup
-
-setup(
- ...
- setup_requires=['nodely', ...],
- require_node_modules=['coffee-script', ...],
- ...
-)
-```
-
-
-
-So they get implicitly installed during the installation of the Python package,
-just like the Python dependencies defined in `install_requires`
-
-
-
-### Run installed Node.js tools from Python
-
-
-
-The `nodely.call` function additionally supports `subprocess.call` options:
-
-
-
-
-```python
->>> from subprocess import DEVNULL
->>>
->>> nodely.call('coffee', ['--version'], stdout=DEVNULL)
-0
-```
-
-
-
-And instead of a simple `nodely.call`,
-you can also create a process instance,
-and give any `subprocess.Popen` options to it:
-
-
-
-
-```python
->>> from subprocess import PIPE
->>>
->>> process = nodely.Popen('coffee', ['--version'], stdout=PIPE,
-... universal_newlines=True)
-```
-
-
-
-```python
->>> process.communicate()[0].split()[-1]
-'1.12.7'
-```
-
-
-
-A more object-oriented approach is provided by:
-
-
-
-
-```python
->>> import nodely.bin
-```
-
-
-It lets you introspect all installed executables with interactive auto-completion
-and creates `nodely.bin.Command` instances:
-
-
-
-
-```python
->>> coffee = nodely.bin.coffee
-```
-
-
-`nodely.bin['coffee']` returns the same.
-And that `nodely.bin.Command` instance provides its own `.call` and a `.Popen` methods,
-and can also be called directly instead of using its `.call` method:
-
-
-
-
-```python
->>> coffee(['--version'])
-0
-```
-
-```
-CoffeeScript version 1.12.7
-```
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index cfcf488..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-environment:
- matrix:
- - PY: C:\Python27\python.exe
- - PY: C:\Python27-x64\python.exe
-
- - PY: C:\Python35\python.exe
- - PY: C:\Python35-x64\python.exe
-
- - PY: C:\Python36\python.exe
- - PY: C:\Python36-x64\python.exe
-
- - PY: C:\Python37\python.exe
- - PY: C:\Python37-x64\python.exe
-
-build: off
-
-install:
- - cmd: |
- %PY% -m pip install -U pip setuptools six wheel
- %PY% -m pip install -U -e .
- %PY% -m pip install -U -r requirements.test.txt
- rem %PY% -m pip install -U tox
-
-test_script:
- - cmd: |
- %PY% -m pytest -vv --doctest-modules nodely test --cov nodely --cov test --cov-report term-missing --cov-fail-under 100
- rem %PY% -m tox -r -v
-
- - cmd: |
- %PY% -m pip uninstall --yes nodely
- %PY% -m pip install zetup[all]
- %PY% -m zetup install
- %PY% -m robot test
-
- - cmd: |
- rem %PY% -m zetup pytest
- %PY% -m zetup sdist
- rem %PY% -m zetup tox
diff --git a/nodely/__init__.py b/nodely/__init__.py
deleted file mode 100644
index 9a23802..0000000
--- a/nodely/__init__.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# nodely >>> putMORE Node.js into Python
-#
-# Copyright (C) 2017 Stefan Zimmermann
-#
-# nodely is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# nodely is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with nodely. If not, see .
-
-"""
-nodely
-
-putMORE Node.js into Python
-"""
-
-import json
-import os
-import sys
-
-from path import Path
-from pkg_resources import get_distribution
-import whichcraft
-import zetup
-
-from .error import NodeCommandError
-
-# HACK: Fix inconsistently hard-coded whichcraft.__version__
-whichcraft.__version__ = get_distribution('whichcraft').version
-
-zetup.toplevel(__name__, [
- 'NodeCommandError',
- 'Popen',
- 'call',
- 'install',
- 'uninstall',
- 'which',
-])
-
-
-#: The absolute path to the local ``node_modules/`` sub-directory.
-#
-# Which is located under the current Python environment root, and which is
-# used for installing Node.js packages into
-NODE_MODULES_DIR = (Path(sys.prefix) / 'node_modules').mkdir_p()
-
-# create a dummy package.json in python environment root for making npm
-# install packages to node_modules/ sub-directory defined above
-(Path(sys.prefix) / 'package.json').write_text(json.dumps({
- 'name': "python-nodely",
- 'description': "putMORE Node.js into Python",
- 'repository': "https://github.com/zimmermanncode/nodely",
-}))
-
-# and make sure that the node_modules/.bin/ dir always exists
-(NODE_MODULES_DIR / '.bin').mkdir_p()
-
-
-#: The absolute path to the Node.js ``npm`` executable.
-NPM = Path(whichcraft.which('npm')).realpath()
-
-
-def install(package):
- """
- Install given Node.js `package`.
-
- Into ``node_modules/`` of current Python environment
- """
- command = [NPM, 'install', package]
- with Path(sys.prefix):
- status = zetup.call(command)
- if status:
- raise NodeCommandError(command, status, os.getcwd())
-
-
-def uninstall(package):
- """
- Uninstall given Node.js `package`.
-
- From ``node_modules/`` of current Python environment
- """
- command = [NPM, 'uninstall', package]
- with Path(sys.prefix):
- status = zetup.call(command)
- if status: # pragma: no cover
- raise NodeCommandError(command, status, os.getcwd())
-
-
-def which(executable):
- """
- Find `executable` in ``node_modules/.bin/`` of current Python environment.
-
- :return: Absolute ``path.Path`` instance or ``None``
- """
- path = whichcraft.which(executable, path=NODE_MODULES_DIR / '.bin')
- if path is not None:
- return Path(path)
-
-
-def Popen(executable, args=None, **kwargs):
- """
- Create a subprocess for given Node.js `executable`.
-
- :param args:
- Optional sequence of command argument strings
- :param options:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``
- """
- import nodely.bin
-
- command = nodely.bin[ # pylint: disable=unsubscriptable-object
- executable]
- return command.Popen(args, **kwargs)
-
-
-def call(executable, args=None, **kwargs):
- """
- Call given Node.js `executable`.
-
- :param args:
- Optional sequence of command argument strings
- :param kwargs:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``
- """
- import nodely.bin
-
- command = nodely.bin[ # pylint: disable=unsubscriptable-object
- executable]
- return command.call(args, **kwargs)
diff --git a/nodely/bin.py b/nodely/bin.py
deleted file mode 100644
index b0b7480..0000000
--- a/nodely/bin.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# nodely >>> putMORE Node.js into Python
-#
-# Copyright (C) 2017 Stefan Zimmermann
-#
-# nodely is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# nodely is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with nodely. If not, see .
-
-"""
-nodely.bin
-
-Command proxy to the ``node_modules/.bin/`` directory
-"""
-
-from subprocess import CalledProcessError, PIPE
-from types import ModuleType
-import os
-import platform
-import sys
-
-from path import Path
-import zetup
-
-from nodely import NODE_MODULES_DIR
-
-from .error import NodeCommandError
-
-zetup.module(
- __name__, ['Command'],
- __getitem__=lambda cmdname: __getitem__(cmdname),
- __getattr__=lambda name: __getattr__(name),
- __dir__=lambda: __dir__())
-
-
-#: Running on Windows?
-WIN = platform.system() == 'Windows'
-
-
-def __getitem__(cmdname):
- """
- Get a :class:`nodely.bin.Command` instance for given `cmdname`.
-
- :raises OSError: if executable can not be found
- """
- return Command(cmdname)
-
-
-def __getattr__(name):
- """
- Get a :class:`nodely.bin.Command` instance for given command `name`.
-
- :raises OSError: if executable cannot be found
- """
- try:
- return __getitem__(name)
-
- except (IOError, OSError) as exc:
- raise AttributeError(str(exc))
-
-
-def __dir__():
- cmdnames = (f.basename() for f in (NODE_MODULES_DIR / '.bin').files())
- if WIN: # pragma: no cover
- cmdnames = (cmd for cmd in cmdnames if cmd.ext.lower() != '.cmd')
- return list(cmdnames)
-
-
-class Command(zetup.object, Path):
- """
- A Node.js executable from current Python environment.
-
- Residing in ``node_modules/.bin/``
- """
-
- def __new__(cls, name):
- """
- Check existance and store absolute path in ``path.Path`` base.
-
- :param name:
- The basename of the executable in ``node_modules/.bin``
- :raises OSError:
- if executable cannot be found
- """
- if WIN: # pragma: no cover
- name += '.cmd'
- cmd = Path.__new__(cls, NODE_MODULES_DIR / '.bin' / name)
- cmd.atime # HACK: raises OSError if not existing
- return cmd
-
- def __init__(self, name):
- """:meth:`.__new__` does all the work :)."""
- pass
-
- @property
- def name(self):
- """Get the name of this Node.js command."""
- name = Path(self).basename()
- if WIN: # pragma: no cover
- # remove .cmd file extension
- name = name.splitext( # pylint: disable=no-value-for-parameter
- )[0]
- return str(name)
-
- def Popen(self, cmdargs=None, **options):
- """
- Create a ``subprocess`` for this Node.js command.
-
- :param cmdargs:
- Optional sequence of command argument strings.
- :param options:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``.
- """
- command = [str(self)]
- if cmdargs is not None:
- command += cmdargs
- return zetup.Popen(command, **options)
-
- def call(self, cmdargs=None, **options):
- """
- Call this Node.js command.
-
- :param cmdargs:
- Optional sequence of command argument strings.
- :param options:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``.
- """
- command = [str(self)]
- if cmdargs is not None:
- command += cmdargs
- return zetup.call(command, **options)
-
- def check_call(self, cmdargs=None, **options):
- """
- Call this Node.js command and check its return code.
-
- :param cmdargs:
- Optional sequence of command argument strings.
- :param options:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``.
-
- :raises subprocess.CalledProcessError:
- When return code is not zero.
- """
- command = [str(self)]
- if cmdargs is not None:
- command += cmdargs
-
- returncode = zetup.call(command, **options)
- if returncode:
- raise NodeCommandError(returncode, command, os.getcwd())
-
- def check_output(self, cmdargs=None, **options):
- """
- Call this Node.js command, check return code, and return its stdout.
-
- :param cmdargs:
- Optional sequence of command argument strings.
- :param options:
- General options for ``zetup.call``, including all options for
- ``subprocess.call``.
-
- :raises subprocess.CalledProcessError:
- When return code is not zero.
- """
- command = [str(self)]
- if cmdargs is not None:
- command += cmdargs
-
- process = zetup.Popen(command, stdout=PIPE, **options)
- out, _ = process.communicate()
- if process.returncode:
- raise NodeCommandError(process.returncode, command, os.getcwd())
-
- return out
-
- def __call__(self, *cmdargs, **kwargs):
- """
- Alternative to :meth:`.check_output`.
-
- Takes `cmdargs` as varargs instead of a sequence parameter
- """
- return self.check_output(cmdargs, **kwargs)
-
- def __repr__(self):
- return "{}[{!r}]".format(__name__, self.name)
diff --git a/nodely/error.py b/nodely/error.py
deleted file mode 100644
index 3fbb480..0000000
--- a/nodely/error.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""nodely exceptions."""
-
-from subprocess import CalledProcessError
-
-import zetup
-
-import nodely
-
-__all__ = ('NodeCommandError', )
-
-
-class NodeCommandError(CalledProcessError, zetup.object):
- """A Node.js command returned non-zero exit code"""
-
- __package__ = nodely
-
- def __init__(self, returncode, cmd, cwd):
- super(NodeCommandError, self).__init__(
- returncode=returncode, cmd=cmd)
- self.cwd = cwd
- self.args += (cwd, )
-
- def __str__(self):
- return "{} in working directory {!r}".format(
- super(NodeCommandError, self).__str__().rstrip("."), self.cwd)
diff --git a/nodely/setup_keywords.py b/nodely/setup_keywords.py
deleted file mode 100644
index caa833e..0000000
--- a/nodely/setup_keywords.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# nodely >>> putMORE Node.js into Python
-#
-# Copyright (C) 2017 Stefan Zimmermann
-#
-# nodely is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# nodely is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with nodely. If not, see .
-
-"""
-nodely entry points for ``distutils.setup_keywords``.
-
-Adding ``require_node_modules`` to ``setup()``::
-
- from setuptools import setup
-
- setup(
- ...
- setup_requires=['nodely', ...],
- require_node_modules=['coffee-script', ...],
- ...
- )
-"""
-
-from moretools import isstring
-
-import nodely
-
-__all__ = ('require_node_modules', )
-
-
-def require_node_modules(dist, keyword='require_node_modules',
- jsmodules=None):
- """
- Install required `jsmodules` during a Python package ``setup()``.
- """
- assert keyword == 'require_node_modules'
- if jsmodules is None:
- return
-
- if isstring(jsmodules):
- jsmodules = filter(
- None, (mod.strip() for mod in jsmodules.split('\n')))
- for jsmod in jsmodules:
- nodely.install(jsmod)
diff --git a/requirements.setup.txt b/requirements.setup.txt
deleted file mode 100644
index 98bfaff..0000000
--- a/requirements.setup.txt
+++ /dev/null
@@ -1 +0,0 @@
-zetup >= 0.2.63
diff --git a/requirements.test.txt b/requirements.test.txt
deleted file mode 100644
index 34a288d..0000000
--- a/requirements.test.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pytest >= 4.6.2
-pytest-cov >= 2.6.0
-robotframework >= 3.1.2
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 94818bd..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-zetup >= 0.2.63
-moretools >= 0.1.12
-#py2 path.py ~= 11.5.0 #import path
-#py3 path.py >= 11.5.0 #import path
-whichcraft >= 0.6.0
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 8a9525b..0000000
--- a/setup.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""Setup for Python ``nodely`` package distribution."""
-
-from __future__ import print_function
-
-from setuptools import setup
-
-
-dist = None
-try:
- dist = setup(
- setup_requires=open("requirements.setup.txt").read(),
-
- use_zetup=True,
-
- entry_points={'distutils.setup_keywords': [
- "require_node_modules="
- "nodely.setup_keywords:require_node_modules",
- ]},
- )
-
-finally:
- if dist is not None and hasattr(dist, 'zetup_made'):
- dist.zetup_made.clean()
diff --git a/test/conftest.py b/test/conftest.py
deleted file mode 100644
index df754bc..0000000
--- a/test/conftest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import re
-
-import pytest
-from path import Path
-
-import nodely
-
-
-TEST_DIR = (
- Path(__file__) # pylint: disable=no-value-for-parameter
- .realpath().dirname())
-
-exec((TEST_DIR / 'variables.py').text())
-
-
-@pytest.fixture
-def node_package():
- return NODE_PACKAGE # pylint: disable=undefined-variable
-
-
-@pytest.fixture
-def install_node_package(node_package):
- nodely.install(node_package)
-
-
-@pytest.fixture
-def node_package_command():
- return 'coffee'
-
-
-@pytest.fixture
-def node_package_command_args():
- return ['--version']
-
-
-@pytest.fixture
-def node_package_command_output_regex():
- return re.compile(r"^CoffeeScript version [0-9.]+$")
diff --git a/test/setup.py b/test/setup.py
deleted file mode 100644
index 74f3dba..0000000
--- a/test/setup.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Setup for ``nodely-test``, a test package using ``nodely`` entry points."""
-
-import os # pragma: no cover
-import sys # pragma: no cover
-
-from setuptools import setup # pragma: no cover
-
-
-TEST_DIR = os.path.dirname( # pragma: no cover
- os.path.realpath(__file__))
-
-with open(
- os.path.join(TEST_DIR, 'variables.py')
-) as varfile: # pragma: no cover
- exec(varfile.read())
-
-
-setup( # pragma: no cover
- name='nodely-test',
- description="Test puttingMORE Node.js into Python",
-
- author="Stefan Zimmermann",
- author_email="user@zimmermann.co",
- url="https://github.com/zimmermanncode/nodely",
-
- license='LGPLv3',
-
- setup_requires=['setuptools_scm', 'nodely'],
-
- use_scm_version={
- 'root': '..',
- 'local_scheme': lambda _: '',
- },
- require_node_modules=[
- NODE_PACKAGE, # pylint: disable=undefined-variable
- ],
-)
diff --git a/test/setup_keywords.robot b/test/setup_keywords.robot
deleted file mode 100644
index 3551ecb..0000000
--- a/test/setup_keywords.robot
+++ /dev/null
@@ -1,25 +0,0 @@
-*** Settings ***
-
-Library OperatingSystem
-Library Process
-
-Variables ./variables.py
-
-
-*** Test Cases ***
-
-Require Node Modules
- ${python} = Evaluate sys.executable modules=sys
- ${node package dir} = Evaluate
- ... nodely.NODE_MODULES_DIR / '${NODE_PACKAGE}'
- ... modules=nodely
-
- Evaluate
- ... nodely.uninstall('${NODE_PACKAGE}')
- ... modules=nodely
- Directory Should Not Exist ${node package dir}
-
- Run Process
- ... ${python} setup.py develop
- ... cwd=${CURDIR}
- Directory Should Exist ${node package dir}
diff --git a/test/test_nodely.py b/test/test_nodely.py
deleted file mode 100644
index a262ce3..0000000
--- a/test/test_nodely.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from subprocess import PIPE
-import platform
-import re
-import sys
-
-from path import Path
-import pytest
-
-import nodely
-
-
-WIN = platform.system() == 'Windows'
-
-
-def test_NODE_MODULES_DIR():
- assert nodely.NODE_MODULES_DIR == Path(sys.prefix) / 'node_modules'
- assert nodely.NODE_MODULES_DIR.isdir()
-
-
-def test_install(node_package):
- node_package_dir = nodely.NODE_MODULES_DIR / node_package
- nodely.install(node_package)
- assert node_package_dir.isdir()
-
- nodely.uninstall(node_package)
- assert not node_package_dir.exists()
-
- nodely.install(node_package)
- assert node_package_dir.isdir()
-
-
-def test_install_non_existent():
- with pytest.raises(nodely.NodeCommandError):
- nodely.install('non-existent')
-
-
-def test_which(node_package, node_package_command):
- nodely.install(node_package)
- path = Path(nodely.NODE_MODULES_DIR / '.bin' / node_package_command)
- if WIN: # pragma: no cover
- path += '.cmd'
- assert nodely.which(node_package_command).normcase() == path.normcase()
- assert nodely.which('non-existent') is None
-
-
-def test_Popen(
- node_package_command, node_package_command_args,
- node_package_command_output_regex):
- process = nodely.Popen(
- node_package_command, node_package_command_args,
- stdout=PIPE, stderr=PIPE, universal_newlines=True)
-
- out, err = process.communicate()
- assert node_package_command_output_regex.match(out.strip())
- assert not err
-
-
-def test_call(
- capfd, node_package_command, node_package_command_args,
- node_package_command_output_regex):
- assert nodely.call(node_package_command, node_package_command_args) is 0
-
- out, err = capfd.readouterr()
- assert node_package_command_output_regex.match(out.strip())
- assert not err
diff --git a/test/test_nodely_bin.py b/test/test_nodely_bin.py
deleted file mode 100644
index f44e57b..0000000
--- a/test/test_nodely_bin.py
+++ /dev/null
@@ -1,188 +0,0 @@
-"""Test :mod:`nodely.bin`."""
-
-import os
-import platform
-import re
-from subprocess import PIPE, STDOUT
-
-import pytest
-from path import Path
-
-import nodely.bin
-from nodely import NodeCommandError
-from nodely.bin import Command
-
-
-WIN = platform.system() == 'Windows'
-
-
-def test_NODE_MODULES_DIR():
- assert nodely.bin.NODE_MODULES_DIR is nodely.NODE_MODULES_DIR
-
-
-@pytest.mark.usefixtures('install_node_package')
-class TestModule(object):
- """Test module features of :mod:`nodely.bin`."""
-
- def test__getitem__(self, node_package_command):
- command = nodely.bin[ # pylint: disable=unsubscriptable-object
- node_package_command]
- assert type(command) is Command
- assert Path(command).normcase() \
- == nodely.which(node_package_command).normcase()
-
- def test__getitem__non_existent(self):
- with pytest.raises((IOError, OSError)):
- nodely.bin[ # pylint: disable=unsubscriptable-object
- 'non-existent']
-
- def test__getattr__(self, node_package_command):
- command = getattr(nodely.bin, node_package_command)
- assert type(command) is Command
- assert Path(command).normcase() \
- == nodely.which(node_package_command).normcase()
-
- def test__getattr__non_existent(self):
- with pytest.raises(AttributeError, match=(
- r"^{} has no attribute 'non_existent' \(.+\)$"
- .format(re.escape(repr(nodely.bin))))):
-
- getattr(nodely.bin, 'non_existent')
-
- def test__getattr__non_existent__special__(self):
- with pytest.raises(AttributeError, match=(
- r"^{} has no attribute '__non_existent__'$"
- .format(re.escape(repr(nodely.bin))))):
-
- getattr(nodely.bin, '__non_existent__')
-
- def test__dir__(self):
- cmdnames = (
- f.basename()
- for f in (nodely.bin.NODE_MODULES_DIR / '.bin').files())
- if WIN: # pragma: no cover
- cmdnames = (cmd for cmd in cmdnames if cmd.ext.lower() != '.cmd')
- assert set(cmdnames).issubset(dir(nodely.bin))
-
-
-@pytest.mark.usefixtures('install_node_package')
-class TestCommand(object):
- """Test :class:`nodely.bin.Command`."""
-
- def test__new__(self, node_package_command):
- command = Command(node_package_command)
- assert Path(command).normcase() \
- == nodely.which(node_package_command).normcase()
-
- def test__new__non_existent(self):
- with pytest.raises((IOError, OSError)):
- Command('non_existent')
-
- def test_name(self, node_package_command):
- assert Command.name is not Path.name
- assert Command(node_package_command).name == node_package_command
-
- def test_Popen(
- self, node_package_command, node_package_command_args,
- node_package_command_output_regex):
- command = Command(node_package_command)
- process = command.Popen(
- node_package_command_args, stdout=PIPE, stderr=PIPE,
- universal_newlines=True)
-
- out, err = process.communicate()
- assert process.returncode is 0
- assert node_package_command_output_regex.match(out.strip())
- assert not err
-
- def test_Popen_non_zero_returncode(self, node_package_command):
- command = Command(node_package_command)
- process = command.Popen(
- '--non-existent', stdout=PIPE, stderr=PIPE,
- universal_newlines=True)
-
- out, err = process.communicate()
- assert process.returncode is not 0
- assert not out and err
-
- def test_call(
- self, capfd, node_package_command, node_package_command_args,
- node_package_command_output_regex):
- command = Command(node_package_command)
- assert command.call(node_package_command_args) is 0
-
- out, err = capfd.readouterr()
- assert node_package_command_output_regex.match(out.strip())
- assert not err
-
- def test_call_non_zero_returncode(self, capfd, node_package_command,):
- command = Command(node_package_command)
- assert command.call(['--non-existent']) is not 0
-
- out, err = capfd.readouterr()
- assert not out and err
-
- def test_check_call_raises(self, capfd, node_package_command):
- command = Command(node_package_command)
- with pytest.raises(NodeCommandError, match=(
- r"^Command '\[[^,]+, '--non-existent'\]' "
- r"returned non-zero exit status -?\d+ "
- r"in working directory {}$"
- .format(re.escape(repr(os.getcwd()))))):
-
- command.check_call(['--non-existent'])
-
- out, err = capfd.readouterr()
- assert not out and err
-
- def test_check_output(
- self, capfd, node_package_command, node_package_command_args,
- node_package_command_output_regex):
- command = Command(node_package_command)
- assert node_package_command_output_regex.match(
- command.check_output(
- node_package_command_args, universal_newlines=True))
-
- out, err = capfd.readouterr()
- assert not out and not err
-
- def test_check_output_raises(self, capfd, node_package_command):
- command = Command(node_package_command)
- with pytest.raises(NodeCommandError, match=(
- r"^Command '\[[^,]+, '--non-existent'\]' "
- r"returned non-zero exit status -?\d+ "
- r"in working directory {}$"
- .format(re.escape(repr(os.getcwd()))))):
-
- command.check_output(['--non-existent'], stderr=STDOUT)
-
- out, err = capfd.readouterr()
- assert not out and not err
-
- def test__call__(
- self, capfd, node_package_command, node_package_command_args,
- node_package_command_output_regex):
- command = Command(node_package_command)
- assert node_package_command_output_regex.match(
- command(*node_package_command_args, universal_newlines=True))
-
- out, err = capfd.readouterr()
- assert not out and not err
-
- def test__call__raises(self, capfd, node_package_command):
- command = Command(node_package_command)
- with pytest.raises(NodeCommandError, match=(
- r"^Command '\[[^,]+, '--non-existent', '--and-invalid'\]' "
- r"returned non-zero exit status -?\d+ "
- r"in working directory {}$"
- .format(re.escape(repr(os.getcwd()))))):
-
- command('--non-existent', '--and-invalid', stderr=STDOUT)
-
- out, err = capfd.readouterr()
- assert not out and not err
-
- def test__repr__(self, node_package_command):
- assert (
- repr(Command(node_package_command)) ==
- "nodely.bin['{}']".format(node_package_command))
diff --git a/test/test_setup_keywords.py b/test/test_setup_keywords.py
deleted file mode 100644
index 5b0e4d2..0000000
--- a/test/test_setup_keywords.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import os
-import sys
-
-import pytest
-import zetup
-
-from nodely.setup_keywords import require_node_modules
-import nodely
-
-
-def test_require_node_modules(node_package):
- node_package_dir = nodely.NODE_MODULES_DIR / node_package
- nodely.uninstall(node_package)
- assert not node_package_dir.exists()
-
- # HACK: Python 3.5 on Travis CI strangely reports missing coverage
- require_node_modules(dist=None, jsmodules=[ # pragma: no cover
- node_package,
- ])
- assert node_package_dir.isdir()
-
-
-def test_require_node_modules_from_string(node_package):
- node_package_dir = nodely.NODE_MODULES_DIR / node_package
- nodely.uninstall(node_package)
- assert not node_package_dir.exists()
-
- require_node_modules(dist=None, jsmodules="""
- {}
- """.format(node_package))
- assert node_package_dir.isdir()
-
-
-def test_require_node_modules_with_wrong_keyword():
- with pytest.raises(AssertionError):
- require_node_modules(dist=None, keyword='wrong')
-
-
-def test_require_node_modules_without_jsmodules(node_package):
- nodely.uninstall(node_package)
- node_modules_content = nodely.NODE_MODULES_DIR.listdir()
- require_node_modules(dist=None)
- assert node_modules_content == nodely.NODE_MODULES_DIR.listdir()
-
-
-# def test_setup(node_package):
-# node_package_dir = nodely.NODE_MODULES_DIR / node_package
-# nodely.uninstall(node_package)
-# assert not node_package_dir.exists()
-# zetup.call(
-# [sys.executable, 'setup.py', 'develop'],
-# cwd=os.path.dirname(os.path.realpath(__file__)))
-# assert node_package_dir.isdir()
diff --git a/test/variables.py b/test/variables.py
deleted file mode 100644
index b6ef591..0000000
--- a/test/variables.py
+++ /dev/null
@@ -1 +0,0 @@
-NODE_PACKAGE = 'coffee-script'
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 0796ed5..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[tox]
-envlist = py27,py35,py36,py37,pypy
-
-[testenv]
-deps =
- -rrequirements.test.txt
-
-commands =
- python -m pytest -vv --doctest-modules nodely test --cov nodely --cov test --cov-report term-missing --cov-fail-under 100
- python -m robot test
diff --git a/zetup.ini b/zetup.ini
deleted file mode 100644
index d522ec8..0000000
--- a/zetup.ini
+++ /dev/null
@@ -1,34 +0,0 @@
-[nodely]
-
-description =
- putMORE Node.js into Python
-
-author = Stefan Zimmermann
-url = https://github.com/zimmermanncode/nodely
-
-license = LGPLv3
-
-python = 2.7 3.5 3.6 3.7
-
-no make =
- setup.py
- tox.ini
-
-classifiers =
- Development Status :: 3 - Alpha
- Intended Audience :: Developers
- License :: OSI Approved
- :: GNU Library or Lesser General Public License (LGPL)
- Operating System :: OS Independent
- Topic :: Software Development
- Topic :: Utilities
-
-keywords =
- nodely nodejs node npm npmjs
- nodejspackages nodejspackage nodejsmodules nodejsmodule
- nodepackages nodepackage nodemodules nodemodule
- npmpackages npmpackage npmmodules npmmodule
- packages package nodemodules modules module bin
- javascript js ecmascript ecma es
- install uninstall which subprocess popen call
- more tools tool