From 35b7168bc587b0771d51a1bb577407904f19c61b Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 10:22:31 -0400 Subject: [PATCH 1/7] Update .gitignore to include OS rules. --- .gitignore | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index a4dcc2d..7e843be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,56 @@ +# Custom Rules + +# Emacs Buffers +\#* + + +# Created by https://www.gitignore.io/api/linux,macos,python,windows +# Edit at https://www.gitignore.io/?templates=linux,macos,python,windows + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -8,7 +61,6 @@ __pycache__/ # Distribution / packaging .Python -env/ build/ develop-eggs/ dist/ @@ -20,9 +72,11 @@ lib64/ parts/ sdist/ var/ +wheels/ *.egg-info/ .installed.cfg *.egg +MANIFEST # PyInstaller # Usually these files are written by a python script from a template @@ -37,13 +91,15 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ +.nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml -*,cover +*.cover .hypothesis/ +.pytest_cache/ # Translations *.mo @@ -51,6 +107,15 @@ coverage.xml # Django stuff: *.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy # Sphinx documentation docs/_build/ @@ -58,8 +123,87 @@ docs/_build/ # PyBuilder target/ -# pyenv python configuration file +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv .python-version +# celery beat schedule file +celerybeat-schedule -\#* +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +### Python Patch ### +.venv/ + +### Python.VirtualEnv Stack ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/linux,macos,python,windows From 970902d70669892d1598b4b637d56076ca6388a8 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 10:27:57 -0400 Subject: [PATCH 2/7] Clean up setup.py. --- requirements_dev.txt | 6 +++--- setup.py | 33 ++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/requirements_dev.txt b/requirements_dev.txt index a0a8c54..1dbdb1b 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,4 +1,5 @@ -pip==8.1.2 +--index-url https://pypi.python.org/simple + bumpversion==0.5.3 wheel==0.29.0 watchdog==0.8.3 @@ -6,6 +7,5 @@ flake8==2.6.0 tox==2.3.1 coverage==4.1 Sphinx==1.4.8 -tinydb -snakemake +-e . diff --git a/setup.py b/setup.py index 922e462..892d620 100644 --- a/setup.py +++ b/setup.py @@ -1,47 +1,50 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from setuptools import setup +from setuptools import setup, find_packages + with open('README.rst') as readme_file: readme = readme_file.read() + with open('HISTORY.rst') as history_file: history = history_file.read() + requirements = [ 'Click>=6.0', - # TODO: put package requirements here + 'tinydb', + 'snakemake', ] + test_requirements = [ # TODO: put package test requirements here ] + setup( name='meta_ultra', version='0.1.0', - description="Cohesive pipelines for precision metagenomics", + description='Cohesive pipelines for precision metagenomics', long_description=readme + '\n\n' + history, - author="David C Danko", + author='David C Danko', author_email='dcd3001@med.cornell.edu', url='https://github.com/dcdanko/meta_ultra', - packages=[ - 'meta_ultra', - ], - package_dir={'meta_ultra': - 'meta_ultra'}, + packages=find_packages(exclude=['tests', 'scripts']), + include_package_data=True, + install_requires=requirements, + license='MIT', + zip_safe=False, + keywords='meta_ultra', entry_points={ 'console_scripts': [ 'mu=meta_ultra.cli:main' ] }, - include_package_data=True, - install_requires=requirements, - license="MIT license", - zip_safe=False, - keywords='meta_ultra', classifiers=[ + # As from http://pypi.python.org/pypi?%3Aaction=list_classifiers 'Development Status :: 2 - Pre-Alpha', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -55,5 +58,5 @@ 'Programming Language :: Python :: 3.5', ], test_suite='tests', - tests_require=test_requirements + tests_require=test_requirements, ) From f7e9c88bfeb9ce41a11866bc5b6f80ab284e00d8 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 10:31:23 -0400 Subject: [PATCH 3/7] Remove empty and backup files. --- .editorconfig.bak | 21 -- .github/ISSUE_TEMPLATE.md.bak | 15 - .gitignore.bak | 62 ---- .travis.yml.bak | 21 -- cli. | 0 confi | 0 meta_ultra/api/api | 0 meta_ultra/cli/.#cli_view.py | 1 - meta_ultra/cli/cli. | 0 meta_ultra/cli/cli_add.py.py | 0 meta_ultra/data | 0 meta_ultra/database/data | 0 meta_ultra/database/project | 0 setup. | 0 tests/test_mu.py.bak | 636 ---------------------------------- tests/test_mu_cli.py.bak | 181 ---------- 16 files changed, 937 deletions(-) delete mode 100644 .editorconfig.bak delete mode 100644 .github/ISSUE_TEMPLATE.md.bak delete mode 100644 .gitignore.bak delete mode 100644 .travis.yml.bak delete mode 100644 cli. delete mode 100644 confi delete mode 100644 meta_ultra/api/api delete mode 120000 meta_ultra/cli/.#cli_view.py delete mode 100644 meta_ultra/cli/cli. delete mode 100644 meta_ultra/cli/cli_add.py.py delete mode 100644 meta_ultra/data delete mode 100644 meta_ultra/database/data delete mode 100644 meta_ultra/database/project delete mode 100644 setup. delete mode 100644 tests/test_mu.py.bak delete mode 100644 tests/test_mu_cli.py.bak diff --git a/.editorconfig.bak b/.editorconfig.bak deleted file mode 100644 index d4a2c44..0000000 --- a/.editorconfig.bak +++ /dev/null @@ -1,21 +0,0 @@ -# http://editorconfig.org - -root = true - -[*] -indent_style = space -indent_size = 4 -trim_trailing_whitespace = true -insert_final_newline = true -charset = utf-8 -end_of_line = lf - -[*.bat] -indent_style = tab -end_of_line = crlf - -[LICENSE] -insert_final_newline = false - -[Makefile] -indent_style = tab diff --git a/.github/ISSUE_TEMPLATE.md.bak b/.github/ISSUE_TEMPLATE.md.bak deleted file mode 100644 index 6956e9f..0000000 --- a/.github/ISSUE_TEMPLATE.md.bak +++ /dev/null @@ -1,15 +0,0 @@ -* Precision Metagenomics Pipeline version: -* Python version: -* Operating System: - -### Description - -Describe what you were trying to get done. -Tell us what happened, what went wrong, and what you expected to happen. - -### What I Did - -``` -Paste the command(s) you ran and the output. -If there was a crash, please include the traceback here. -``` diff --git a/.gitignore.bak b/.gitignore.bak deleted file mode 100644 index 71e6852..0000000 --- a/.gitignore.bak +++ /dev/null @@ -1,62 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# pyenv python configuration file -.python-version diff --git a/.travis.yml.bak b/.travis.yml.bak deleted file mode 100644 index 1ed52ed..0000000 --- a/.travis.yml.bak +++ /dev/null @@ -1,21 +0,0 @@ -# Config file for automatic testing at travis-ci.org -# This file will be regenerated if you run travis_pypi_setup.py - -language: python -python: 3.5 - -env: - - TOXENV=py35 - - TOXENV=py34 - - TOXENV=py33 - - TOXENV=py27 - - TOXENV=py26 - - TOXENV=pypy - -# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -U tox - -# command to run tests, e.g. python setup.py test -script: tox -e ${TOXENV} - - diff --git a/cli. b/cli. deleted file mode 100644 index e69de29..0000000 diff --git a/confi b/confi deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/api/api b/meta_ultra/api/api deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/cli/.#cli_view.py b/meta_ultra/cli/.#cli_view.py deleted file mode 120000 index cc18716..0000000 --- a/meta_ultra/cli/.#cli_view.py +++ /dev/null @@ -1 +0,0 @@ -dcd3001@hippocampus.pbtech.48557:1491843991 \ No newline at end of file diff --git a/meta_ultra/cli/cli. b/meta_ultra/cli/cli. deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/cli/cli_add.py.py b/meta_ultra/cli/cli_add.py.py deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/data b/meta_ultra/data deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/database/data b/meta_ultra/database/data deleted file mode 100644 index e69de29..0000000 diff --git a/meta_ultra/database/project b/meta_ultra/database/project deleted file mode 100644 index e69de29..0000000 diff --git a/setup. b/setup. deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_mu.py.bak b/tests/test_mu.py.bak deleted file mode 100644 index 5b28170..0000000 --- a/tests/test_mu.py.bak +++ /dev/null @@ -1,636 +0,0 @@ -#!/usr/bin/env python - -import os -import tempfile -import sys -import tempfile -import unittest -from contextlib import contextmanager -from click.testing import CliRunner -from meta_ultra import api -from meta_ultra import config -from meta_ultra.data_type import DataType -from meta_ultra.database import RecordExistsError, InvalidRecordStateError -from shutil import rmtree - -def changeToTempDir(): - tdir = tempfile.mkdtemp() - os.chdir(tdir) - return tdir - -class Test_api(unittest.TestCase): - def setUp(self): - self.tdir = changeToTempDir() - - def tearDown(self): - rmtree(self.tdir) - - def test_init(self): - api.init() - assert config.mu_dir in os.listdir(self.tdir) - - # projects - - def test_add_project(self): - api.init() - api.saveProject('test_project', None) - - def tests_double_add_project_fails(self): - api.init() - api.saveProject('test_project_', None) - self.assertRaises(RecordExistsError, api.saveProject, 'test_project_', None) - - def test_get_project(self): - api.init() - api.saveProject('test_project', None) - self.assertEquals('test_project', api.getProject('test_project').name) - - def test_remove_project(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_project') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_project') - api.removeProject('test_project') - self.assertIs(None, api.getProject('test_project')) - self.assertIs(None, api.getSample('test_sample')) - self.assertEquals(None, api.getDataRec('test_SEDSD')) - self.assertEquals(None, api.getResult('test_result')) - - - def test_atomic_remove_project(self): - api.init() - api.saveProject('test_project', None) - api.removeProject('test_project', atomic=True) - self.assertIs(None, api.getProject('test_project')) - - def test_query_projects_all(self): - pass - - def test_query_projects_names(self): - pass - - # confs - - def test_add_conf(self): - api.init() - api.saveConf('test_conf', {}) - - def tests_double_add_conf_fails(self): - api.init() - api.saveConf('test_conf', {}) - self.assertRaises(RecordExistsError, api.saveConf, 'test_conf', {}) - - - def test_get_conf(self): - api.init() - api.saveConf('test_conf', {}) - self.assertEquals('test_conf', api.getConf('test_conf').name) - - def test_remove_conf(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_project') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_project') - api.removeConf('test_conf') - self.assertEquals(None, api.getConf('test_conf')) - self.assertEquals(None, api.getResult('test_result')) - - - def test_atomic_remove_conf(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_project') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_project') - api.removeConf('test_conf', atomic=True) - self.assertEquals(None, api.getConf('test_conf')) - self.assertEquals('test_result', api.getResult('test_result').name) - - - def test_query_confs_all(self): - pass - - def test_query_confs_names(self): - pass - - - - # experiments - - def test_add_experiment(self): - api.init() - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveExperiment('test_exp_', DataType.DNA_SEQ_PAIRED_END, None) - - def test_double_add_experiment_fails(self): - api.init() - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - self.assertRaises(RecordExistsError, api.saveExperiment, 'test_exp', DataType.DNA_SEQ_PAIRED_END, None) - - def test_get_experiment(self): - api.init() - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - self.assertEquals('test_exp', api.getExperiment('test_exp').name) - - def test_remove_experiment(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_project') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_project') - api.removeExperiment('test_exp') - self.assertIs(None, api.getSample('test_exp')) - self.assertEquals(None, api.getDataRec('test_SEDSD')) - self.assertEquals(None, api.getResult('test_result')) - - - def test_atomic_remove_experiment(self): - api.init() - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.removeExperiment('test_exp', atomic=True) - self.assertIs(None, api.getExperiment('test_exp')) - - def test_query_exps_all(self): - api.init() - api.saveExperiment('test_exp_1', 'DNA_SEQ_SINGLE_END', None) - api.saveExperiment('test_exp_2', 'DNA_SEQ_SINGLE_END', None) - expNames = [el.name for el in api.getExperiments()] - self.assertIn('test_exp_1', expNames) - self.assertIn('test_exp_2', expNames) - - - def test_query_exps_names(self): - api.init() - api.saveExperiment('test_exp_1', 'DNA_SEQ_SINGLE_END', None) - api.saveExperiment('test_exp_2', 'DNA_SEQ_SINGLE_END', None) - expNames = [el.name for el in api.getExperiments(names=['test_exp_2'])] - self.assertNotIn('test_exp_1', expNames) - self.assertIn('test_exp_2', expNames) - - - - def test_query_exps_data_types(self): - api.init() - api.saveExperiment('test_exp_1', 'DNA_SEQ_PAIRED_END', None) - api.saveExperiment('test_exp_2', 'DNA_SEQ_SINGLE_END', None) - expNames = [el.name for el in api.getExperiments(dataTypes=[DataType.DNA_SEQ_SINGLE_END])] - self.assertNotIn('test_exp_1', expNames) - self.assertIn('test_exp_2', expNames) - - - - - # samples - - def test_add_sample(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - - def test_add_sample_fails_without_project(self): - api.init() - self.assertRaises(InvalidRecordStateError, api.saveSample, 'test_sample', 'PHONE_SAMPLE', 'test_project', None) - - def test_double_add_sample_fails(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - self.assertRaises(RecordExistsError, api.saveSample, 'test_sample', 'PHONE_SAMPLE', 'test_project', None) - - def test_get_sample(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - self.assertEquals('test_sample', api.getSample('test_sample').name) - - def test_remove_project_creates_sample_error_state(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.removeProject('test_project', atomic=True) - self.assertFalse(api.getSample('test_sample').validStatus()) - - def test_remove_sample(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_project') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_project') - api.removeSample('test_sample') - self.assertIs(None, api.getSample('test_sample')) - self.assertEquals(None, api.getDataRec('test_SEDSD')) - self.assertEquals(None, api.getResult('test_result')) - - - def test_atomic_remove_sample(self, atomic=True): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_project', None) - api.removeSample('test_sample', atomic=True) - self.assertIs(None, api.getSample('test_sample')) - - def test_query_samples_all(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample_1','PHONE_SAMPLE', 'test_project', None) - api.saveSample('test_sample_2','PHONE_SAMPLE', 'test_project', None) - sNames = [el.name for el in api.getSamples()] - self.assertIn('test_sample_1', sNames) - self.assertIn('test_sample_2', sNames) - - - def test_query_samples_names(self): - api.init() - api.saveProject('test_project', None) - api.saveSample('test_sample_1', 'PHONE_SAMPLE', 'test_project', None) - api.saveSample('test_sample_2', 'PHONE_SAMPLE', 'test_project', None) - sNames = [el.name for el in api.getSamples(names='test_sample_1')] - self.assertIn('test_sample_1', sNames) - self.assertNotIn('test_sample_2', sNames) - - - def test_query_samples_sample_types(self): - pass - - def test_query_samples_projects(self): - api.init() - api.saveProject('test_project_1', None) - api.saveProject('test_project_2', None) - api.saveSample('test_sample_1', 'PHONE_SAMPLE', 'test_project_1', None) - api.saveSample('test_sample_2', 'PHONE_SAMPLE', 'test_project_2', None) - sNames = [el.name for el in api.getSamples(projects=['test_project_1'])] - self.assertIn('test_sample_1', sNames) - self.assertNotIn('test_sample_2', sNames) - - # data records - - def test_add_SEDSD(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - def test_add_PEDSD(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_PAIRED_END', None) - api.savePairedEndDNASeqData('test_PEDSD', - 'test_1.fastq.gz', - 'test_2.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - - def test_add_data_rec_fails_without_project(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.removeProject('test_proj', atomic=True) - self.assertRaises(InvalidRecordStateError, - api.saveSingleEndDNASeqData, - 'test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - - def test_add_data_rec_fails_without_sample(self): - api.init() - api.saveProject('test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - self.assertRaises(InvalidRecordStateError, - api.saveSingleEndDNASeqData, - 'test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - def test_add_data_rec_fails_without_exp(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - self.assertRaises(InvalidRecordStateError, - api.savePairedEndDNASeqData, - 'test_PEDSD', - 'test_1.fastq.gz', - 'test_2.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - - - def test_double_add_data_rec_fails(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - self.assertRaises( RecordExistsError, - api.saveSingleEndDNASeqData, - 'test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - - def test_get_data_rec(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - self.assertEquals('test_SEDSD', api.getDataRec('test_SEDSD').name) - - def test_remove_project_creates_data_error_state(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.removeProject('test_proj', atomic=True) - self.assertFalse(api.getDataRec('test_SEDSD').validStatus()) - - - def test_remove_sample_creates_data_error_state(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.removeSample('test_sample', atomic=True) - self.assertRaises(InvalidRecordStateError, api.getDataRec, 'test_SEDSD') - - - def test_remove_exp_creates_data_error_state(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.removeExperiment('test_exp', atomic=True) - self.assertFalse(api.getDataRec('test_SEDSD').validStatus()) - - - def test_remove_data_rec(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.saveConf('test_conf', {}) - api.saveResult('test_result', [], 'test_SEDSD', 'test_conf', 'test_sample', 'test_exp', 'test_proj') - api.removeData('test_SEDSD') - self.assertEquals(None, api.getDataRec('test_SEDSD')) - self.assertEquals(None, api.getResult('test_result')) - - - def test_atomic_remove_data_rec(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.removeData('test_SEDSD', atomic=True) - self.assertEquals(None, api.getDataRec('test_SEDSD')) - - def test_query_data_recs_all(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.saveSingleEndDNASeqData('test_SEDSD_2', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - names = [el.name for el in api.getData()] - self.assertIn('test_SEDSD_1', names) - self.assertIn('test_SEDSD_2', names) - - - def test_query_data_recs_names(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.saveSingleEndDNASeqData('test_SEDSD_2', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - names = [el.name for el in api.getData(names=['test_SEDSD_1'])] - self.assertIn('test_SEDSD_1', names) - self.assertNotIn('test_SEDSD_2', names) - - - def test_query_data_recs_data_types(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - api.saveExperiment('test_exp_2', 'DNA_SEQ_PAIRED_END', None) - api.savePairedEndDNASeqData('test_PEDSD', - 'test_1.fastq.gz', - 'test_2.fastq.gz', - 100, - 'test_sample', - 'test_exp_2', - 'test_proj') - names = [el.name for el in api.getData(dataTypes=[DataType.DNA_SEQ_SINGLE_END])] - self.assertIn('test_SEDSD_1', names) - self.assertNotIn('test_PEDSD', names) - - - def test_query_data_recs_samples(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample_1', 'PHONE_SAMPLE', 'test_proj', None) - api.saveSample('test_sample_2', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample_1', - 'test_exp', - 'test_proj') - api.saveSingleEndDNASeqData('test_SEDSD_2', - 'test.fastq.gz', - 100, - 'test_sample_2', - 'test_exp', - 'test_proj') - names = [el.name for el in api.getData(samples=['test_sample_2'])] - self.assertNotIn('test_SEDSD_1', names) - self.assertIn('test_SEDSD_2', names) - - - def test_query_data_recs_exps(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'PHONE_SAMPLE', 'test_proj', None) - api.saveExperiment('test_exp_1', 'DNA_SEQ_SINGLE_END', None) - api.saveExperiment('test_exp_2', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp_1', - 'test_proj') - api.saveSingleEndDNASeqData('test_SEDSD_2', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp_2', - 'test_proj') - names = [el.name for el in api.getData(experiments=['test_exp_1'])] - self.assertIn('test_SEDSD_1', names) - self.assertNotIn('test_SEDSD_2', names) - - - def test_query_data_recs_projects(self): - api.init() - api.saveProject('test_proj_1', None) - api.saveProject('test_proj_2', None) - api.saveSample('test_sample_1', 'PHONE_SAMPLE', 'test_proj_1', None) - api.saveSample('test_sample_2', 'PHONE_SAMPLE', 'test_proj_2', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD_1', - 'test.fastq.gz', - 100, - 'test_sample_1', - 'test_exp', - 'test_proj_1') - api.saveSingleEndDNASeqData('test_SEDSD_2', - 'test.fastq.gz', - 100, - 'test_sample_2', - 'test_exp', - 'test_proj_2') - names = [el.name for el in api.getData(projects=['test_proj_1'])] - self.assertIn('test_SEDSD_1', names) - self.assertNotIn('test_SEDSD_2', names) - - - # misc - - def test_get_data_types(self): - pass - - def test_get_sample_types(self): - pass - - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_mu_cli.py.bak b/tests/test_mu_cli.py.bak deleted file mode 100644 index 0e4e432..0000000 --- a/tests/test_mu_cli.py.bak +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/env python - -import os -import tempfile -import sys -import tempfile -import unittest -from contextlib import contextmanager -from click.testing import CliRunner -from meta_ultra import api -import meta_ultra.cli as cli -from meta_ultra import config -from meta_ultra.data_type import DataType -from meta_ultra.database import RecordExistsError, InvalidRecordStateError -from shutil import rmtree - -def changeToTempDir(): - tdir = tempfile.mkdtemp() - os.chdir(tdir) - return tdir - -class Test_cli(unittest.TestCase): - def setUp(self): - self.tdir = changeToTempDir() - - def tearDown(self): - rmtree(self.tdir) - - def test_cli_init(self): - result = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertIn(config.mu_dir, os.listdir(self.tdir)) - - # projects - - def test_cli_add_project(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - self.assertEquals('test_project', api.getProject('test_project').name, msg=result1.output) - - def test_cli_view_project(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - result2 = CliRunner().invoke(cli.main, ['view', 'projects', 'test_project']) - self.assertEquals(0, result2.exit_code, msg=result2.output) - self.assertIn('test_project', result2.output, msg=result2.output) - - def test_cli_remove_project(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - result2 = CliRunner().invoke(cli.main, ['remove', 'projects', 'test_project', '--no-check']) - self.assertEquals(0, result2.exit_code, msg=result2.output) - result3 = CliRunner().invoke(cli.main, ['view', 'projects', 'test_project']) - self.assertEquals(0, result3.exit_code, msg=result3.output) - self.assertNotIn('test_project', result3.output, msg=result3.output) - - - # samples - - def test_cli_add_sample(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - result2 = CliRunner().invoke(cli.main, ['add', 'sample', '-n', 'test_sample', '-p', 'test_project']) - self.assertEquals(0, result2.exit_code, msg=result2.output) - self.assertEquals('test_sample', api.getSample('test_sample').name) - - - def test_cli_view_sample(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - result2 = CliRunner().invoke(cli.main, ['add', 'sample', '-n', 'test_sample', '-p', 'test_project']) - self.assertEquals(0, result2.exit_code, msg=result2.output) - result3 = CliRunner().invoke(cli.main, ['view', 'samples', 'test_sample']) - self.assertEquals(0, result3.exit_code, msg=result3.output) - self.assertIn('test_sample', result3.output) - - - def test_cli_remove_sample(self): - result0 = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result0.exit_code, msg=result0.output) - result1 = CliRunner().invoke(cli.main, ['add', 'project', '-n', 'test_project']) - self.assertEquals(0, result1.exit_code, msg=result1.output) - result2 = CliRunner().invoke(cli.main, ['add', 'sample', '-n', 'test_sample', '-p', 'test_project']) - self.assertEquals(0, result2.exit_code, msg=result2.output) - result3 = CliRunner().invoke(cli.main, ['view', 'samples', 'test_sample']) - self.assertEquals(0, result3.exit_code, msg=result3.output) - result4 = CliRunner().invoke(cli.main, ['remove', 'samples','test_sample', '--no-check']) - self.assertEquals(0, result4.exit_code, msg=result4.output) - self.assertNotIn('test_sample', result4.output, msg=result4.output) - - # data records - - def test_cli_view_data_rec(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - - result = CliRunner().invoke(cli.main, ['view', 'data', 'test_SEDSD']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertIn('test_SEDSD', result.output) - - def test_cli_remove_data_rec(self): - api.init() - api.saveProject('test_proj', None) - api.saveSample('test_sample', 'test_proj', None) - api.saveExperiment('test_exp', 'DNA_SEQ_SINGLE_END', None) - api.saveSingleEndDNASeqData('test_SEDSD', - 'test.fastq.gz', - 100, - 'test_sample', - 'test_exp', - 'test_proj') - self.assertEquals('test_SEDSD', api.getDataRec('test_SEDSD').name) - result = CliRunner().invoke(cli.main, ['view', 'data', 'test_SEDSD']) - self.assertEquals(0, result.exit_code, msg=result.output) - result = CliRunner().invoke(cli.main, ['remove', 'data', 'test_SEDSD', '--no-check']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertNotIn('test_SEDSD', result.output) - - # misc - - def test_cli_view_data_types(self): - pass - - def test_cli_view_sample_types(self): - pass - - - -if __name__ == '__main__': - unittest.main() - - - # experiments -''' - def test_cli_add_experiment(self): - result = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result.exit_code, msg=result.output) - result = CliRunner().invoke(cli.main, ['add', 'experiments', '-n', 'test_exp']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertEquals('test_exp', api.getExperiment('test_exp').name) - - - def test_cli_view_experiment(self): - result = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result.exit_code) - result = CliRunner().invoke(cli.main, ['add', 'experiment','-n', 'test_exp']) - self.assertEquals(0, result.exit_code) - result = CliRunner().invoke(cli.main, ['view', 'experiments', 'test_exp']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertIn('test_exp', result.output, msg=result.output) - self.assertEquals('test_exp', api.getExperiment('test_exp').name) - - def test_cli_remove_experiment(self): - result = CliRunner().invoke(cli.main, ['init']) - self.assertEquals(0, result.exit_code, msg=result.output) - result = CliRunner().invoke(cli.main, ['add', 'experiment', '-n', 'test_exp']) - self.assertEquals(0, result.exit_code, msg=result.output) - result = CliRunner().invoke(cli.main, ['remove', 'experiment', '-n', 'test_exp']) - self.assertEquals(0, result.exit_code, msg=result.output) - result = CliRunner().invoke(cli.main, ['view', 'experiments', 'test_exp']) - self.assertEquals(0, result.exit_code, msg=result.output) - self.assertNotIn('test_exp', result.output) -''' From 02e65a566904a20edddc3181565a071ac934bf7b Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 10:54:08 -0400 Subject: [PATCH 4/7] Centralize version source. --- meta_ultra/__init__.py | 5 ----- meta_ultra/cli/cli.py | 10 ++++++++++ meta_ultra/version.py | 5 +++++ setup.py | 16 +++++++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 meta_ultra/version.py diff --git a/meta_ultra/__init__.py b/meta_ultra/__init__.py index f5fc9b1..ba42e31 100644 --- a/meta_ultra/__init__.py +++ b/meta_ultra/__init__.py @@ -1,10 +1,5 @@ # -*- coding: utf-8 -*- -__author__ = """David C Danko""" -__email__ = 'dcd3001@med.cornell.edu' -__version__ = '0.1.0' - - import meta_ultra.api as api from meta_ultra.sample_type import SampleType from meta_ultra.data_type import DataType diff --git a/meta_ultra/cli/cli.py b/meta_ultra/cli/cli.py index ea196b2..102704b 100644 --- a/meta_ultra/cli/cli.py +++ b/meta_ultra/cli/cli.py @@ -1,7 +1,17 @@ +import os import click + import meta_ultra.api as api + +version = {} +version_path = os.path.join(os.path.dirname(__file__), '../version.py') +with open(version_path) as version_file: + exec(version_file.read(), version) + + @click.group() +@click.version_option(version['__version__']) def main(): pass diff --git a/meta_ultra/version.py b/meta_ultra/version.py new file mode 100644 index 0000000..4a5ebc2 --- /dev/null +++ b/meta_ultra/version.py @@ -0,0 +1,5 @@ +"""Single source for package version.""" + +__version__ = '0.1.0' +__author__ = 'David C Danko' +__email__ = 'dcd3001@med.cornell.edu' diff --git a/setup.py b/setup.py index 892d620..6565193 100644 --- a/setup.py +++ b/setup.py @@ -4,6 +4,11 @@ from setuptools import setup, find_packages +version = {} +with open('meta_ultra/version.py') as version_file: + exec(version_file.read(), version) + + with open('README.rst') as readme_file: readme = readme_file.read() @@ -14,8 +19,9 @@ requirements = [ 'Click>=6.0', - 'tinydb', - 'snakemake', + 'tinydb==3.11.1', + 'snakemake==5.3.0', + 'py_archy==1.0.2', ] @@ -26,11 +32,11 @@ setup( name='meta_ultra', - version='0.1.0', + version=version['__version__'], description='Cohesive pipelines for precision metagenomics', long_description=readme + '\n\n' + history, - author='David C Danko', - author_email='dcd3001@med.cornell.edu', + author=version['__author__'], + author_email=version['__email__'], url='https://github.com/dcdanko/meta_ultra', packages=find_packages(exclude=['tests', 'scripts']), include_package_data=True, From 612df49231a8fd756577d3916db233708c5c9f85 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 10:54:26 -0400 Subject: [PATCH 5/7] Remove trailing empty lines. --- meta_ultra/api/api.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/meta_ultra/api/api.py b/meta_ultra/api/api.py index cf07640..4ed1fde 100644 --- a/meta_ultra/api/api.py +++ b/meta_ultra/api/api.py @@ -182,8 +182,3 @@ def syncOverwrite(remoteName, projects=[], resultsOnly=False, resultType=None): yield True, result, response else: yield False, result, response - - - - - From 57a39a61bab3383d35d65d091bca010702dffb77 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 11:03:15 -0400 Subject: [PATCH 6/7] Fix metagenscope-api dependency. --- requirements_dev.txt | 1 + setup.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/requirements_dev.txt b/requirements_dev.txt index 1dbdb1b..60eae3f 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -8,4 +8,5 @@ tox==2.3.1 coverage==4.1 Sphinx==1.4.8 +--process-dependency-links -e . diff --git a/setup.py b/setup.py index 6565193..3817d9e 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,11 @@ 'tinydb==3.11.1', 'snakemake==5.3.0', 'py_archy==1.0.2', + 'metagenscope_api==0.1.0', +] + +dependency_links = [ + 'git+https://github.com/dcdanko/MetaGenScopeAPI.git#egg=metagenscope_api-0.1.0', ] @@ -41,6 +46,7 @@ packages=find_packages(exclude=['tests', 'scripts']), include_package_data=True, install_requires=requirements, + dependency_links=dependency_links, license='MIT', zip_safe=False, keywords='meta_ultra', From ef825eef241731f8460eb3f0bdbd2e3c5af03cd1 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 2 Nov 2018 11:09:22 -0400 Subject: [PATCH 7/7] Add CircleCI config. --- .circleci/config.yml | 85 ++++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 21 ----------- requirements_dev.txt | 1 + setup.py | 23 +++++++++++- 4 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 .travis.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..5bdcbd1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,85 @@ +version: 2 + +jobs: + test: + docker: + - image: themattrix/tox + + steps: + - run: + name: Install Git + command: apt-get update; apt-get install -y git ssh + + - checkout + + - run: + name: Run tox + command: tox + + publish: + docker: + - image: circleci/python:3.6 + + steps: + - checkout + + - restore_cache: + key: v1-dependency-cache-{{ checksum "setup.py" }}-{{ checksum "requirements.txt" }} + + - run: + name: Install requirements + command: | + python3 -m venv venv + . venv/bin/activate + pip install -r requirements.txt + + - save_cache: + key: v1-dependency-cache-{{ checksum "setup.py" }}-{{ checksum "requirements.txt" }} + paths: + - "venv" + + - run: + name: Verify git tag vs. version + command: | + python3 -m venv venv + . venv/bin/activate + python setup.py verify + + - run: + name: Init .pypirc + command: | + echo -e "[pypi]" >> ~/.pypirc + echo -e "username = $PYPI_USERNAME" >> ~/.pypirc + echo -e "password = $PYPI_PASSWORD" >> ~/.pypirc + + - run: + name: Create packages + command: | + python setup.py sdist + python setup.py bdist_wheel + + - run: + name: Upload to pypi + command: | + . venv/bin/activate + twine upload dist/* + + +workflows: + version: 2 + + cli_cd: + jobs: + - test: + filters: # required since `publish` has tag filters AND requires `test` + tags: + only: /.*/ + - publish: + context: pypi + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + requires: + - test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1ed52ed..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Config file for automatic testing at travis-ci.org -# This file will be regenerated if you run travis_pypi_setup.py - -language: python -python: 3.5 - -env: - - TOXENV=py35 - - TOXENV=py34 - - TOXENV=py33 - - TOXENV=py27 - - TOXENV=py26 - - TOXENV=pypy - -# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -U tox - -# command to run tests, e.g. python setup.py test -script: tox -e ${TOXENV} - - diff --git a/requirements_dev.txt b/requirements_dev.txt index 60eae3f..dd279e5 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -7,6 +7,7 @@ flake8==2.6.0 tox==2.3.1 coverage==4.1 Sphinx==1.4.8 +twine==1.12.1 --process-dependency-links -e . diff --git a/setup.py b/setup.py index 3817d9e..fec969b 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import os +import sys + from setuptools import setup, find_packages +from setuptools.command.install import install version = {} @@ -35,6 +39,20 @@ ] +class VerifyVersionCommand(install): + """Custom command to verify that the git tag matches our version.""" + + description = 'Verify that the git tag matches our version.' + + def run(self): + tag = os.getenv('CIRCLE_TAG') + + if tag != 'v{0}'.format(__version__): + info = 'Git tag: {0} does not match the version of this app: {1}' + info = info.format(tag, __version__) + sys.exit(info) + + setup( name='meta_ultra', version=version['__version__'], @@ -42,7 +60,7 @@ long_description=readme + '\n\n' + history, author=version['__author__'], author_email=version['__email__'], - url='https://github.com/dcdanko/meta_ultra', + url='https://github.com/dcdanko/MetaUltra', packages=find_packages(exclude=['tests', 'scripts']), include_package_data=True, install_requires=requirements, @@ -71,4 +89,7 @@ ], test_suite='tests', tests_require=test_requirements, + cmdclass={ + 'verify': VerifyVersionCommand, + }, )