diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..177af09 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +name: vdt.simpleaptrepo ci +on: [push] + +defaults: + run: + working-directory: ./src + +jobs: + run-linting: + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + with: + path: ./src + - name: Setup Python 3.6 + uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Install all dependencies + run: make install + - name: Run all linting + run: make lint + - name: Upload src dir as artefact + uses: actions/upload-artifact@v2 + with: + name: src + path: ./src + + run-tests: + needs: run-linting + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.5, 3.6, 3.7, 3.8, 3.9] + steps: + - name: Download src dir + uses: actions/download-artifact@v2 + with: + name: src + path: ./src + - name: Setup Python 3.x + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install all dependencies + run: make install-dev + - name: Run the unittests + run: make test + + run-docker: + needs: run-tests + runs-on: ubuntu-latest + defaults: + run: + working-directory: /usr/local/src + container: + image: maerteijn/simpeapt-test-image:latest + steps: + - name: Download src dir + uses: actions/download-artifact@v2 + with: + name: src + path: /usr/local/src + - name: Copy GPG keys to github home directory + run: cp -R /root/.gnupg ~ + - name: Create a test repo and install a signed package + run: bash ./docker/create-test-repo.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 292758c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: python -python: - - "2.7" - - "3.5" - - "3.6" - -services: - - docker - -install: - - make install - -script: - - make test - - docker-compose -f docker/docker-compose.yml up diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..369a437 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2021 Martijn Jacobs (maerteijn) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 41e77cb..9ea330b 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,28 @@ +.PHONY: clean nosetest install lint black test docker_test clean_release release_testpypi release clean: - find . -name '*.pyc' -delete find . -name '__pycache__' -delete find . -name '*.egg-info' -delete - + nosetest: nosetests -s --with-coverage --cover-erase --cover-package=vdt.simpleaptrepo --cover-xml --logging-level=INFO --with-doctest --verbosity=2 install: + pip install -e .[dev,lint] + +install-dev: pip install -e .[dev] -test: install nosetest +lint: + black --check vdt/ + pylint setup.py vdt/ + +black: + black --exclude "migrations/*" vdt/ + +test: nosetest + +docker_test: + docker run --rm -v $(PWD):/usr/local/src maerteijn/simpeapt-test-image ./docker/run-tests.sh clean_release: clean if [ -d "dist" ]; then rm dist/*; fi diff --git a/README.rst b/README.rst index 416cf22..cc0f877 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ vdt.simpleaptrepo ================= -Simple command line tool to create apt repositories. This will work on debian and ubuntu. +Simple command line tool to create apt repositories. This will work on debian and ubuntu. Requires `python>=3.5` .. image:: https://api.travis-ci.org/devopsconsulting/vdt.simpleaptrepo.svg?branch=master :target: https://travis-ci.org/devopsconsulting/vdt.simpleaptrepo @@ -58,7 +58,7 @@ You will see what you need to do now:: Configure your webservice to set the www-root to /www/ Add http:///myrepo/test / to your sources.list - + Add the key on the host where you want to install the packages. (This is only needed once per repository) wget -qO - http:///myrepo/test/keyfile | sudo apt-key add - @@ -71,7 +71,7 @@ Add some more if you like:: See that our repo is there:: simpleapt list-repos - + myrepo (gpgkey: 10FB8BDC) test staging diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 4829c54..0000000 --- a/TODO.txt +++ /dev/null @@ -1,4 +0,0 @@ -- test with python 3.5 -- add unittests -- add coverage.io -- add to travis diff --git a/docker/Dockerfile b/docker/Dockerfile index 27bcd27..9f0018e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,12 +1,10 @@ -FROM ubuntu -MAINTAINER Martijn Jacobs +FROM debian:10 +MAINTAINER Martijn Jacobs ENV DEBIAN_FRONTEND noninteractive # install the debian related packages for this tool + python pip -RUN apt-get update && apt-get install python-pip gnupg dpkg-sig apt-utils --yes +RUN apt-get update && apt-get install python3-pip gnupg dpkg-sig apt-utils --yes # Make sure you mounted the source coude in /usr/local/src -WORKDIR /usr/local/src/ - -ENTRYPOINT ["make", "test"] \ No newline at end of file +WORKDIR /usr/local/src/ \ No newline at end of file diff --git a/docker/build.sh b/docker/build-test-image.sh old mode 100644 new mode 100755 similarity index 72% rename from docker/build.sh rename to docker/build-test-image.sh index ea6e0a8..d7438df --- a/docker/build.sh +++ b/docker/build-test-image.sh @@ -4,7 +4,7 @@ docker build -t maerteijn/simpeapt-test-image . # run a interactive shell and you should generate a gpg key -echo "Please run /usr/bin/gpg --gen-key, then exit the container with ctrl+D" +echo "Please run /usr/bin/gpg --digest-algo SHA256 --gen-key, then exit the container with ctrl+D" docker run -it --name=simpleapt-test-image-generate-key maerteijn/simpeapt-test-image /bin/bash echo "Please remember the generated GPG key hash" @@ -13,4 +13,4 @@ docker commit simpleapt-test-image-generate-key maerteijn/simpeapt-test-image echo "Done!" echo "Now push the image with 'docker push maerteijn/simpeapt-test-image'" -echo "and delete the container afterwards: 'docker rm simpleapt-test-image-generate-key'" +echo "and delete the container afterwards: 'docker rm simpleapt-test-image-generate-key'" diff --git a/docker/create-test-repo.sh b/docker/create-test-repo.sh new file mode 100755 index 0000000..11680c4 --- /dev/null +++ b/docker/create-test-repo.sh @@ -0,0 +1,33 @@ +#!/bin/bash +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +# install simpleaptrepo +pip3 install -e . + +# do some cleanup +if [ -d "/repos/" ]; then + rm -Rf /repos/ +fi + +# create a repo directory +mkdir /repos + +# now we really create a repo here and add a package +# the gpg key is build into the docker image for testing purposes +simpleapt create-repo myrepo /repos --gpgkey B7C72A100F81017B +simpleapt add-component myrepo test +simpleapt list-repos +cp /usr/local/src/vdt/simpleaptrepo/tests/testdata/*.deb /repos/myrepo/test +simpleapt update-repo myrepo test +simpleapt update-repo myrepo test --skip-signed + +# add the created repo as a local source +echo "deb file:/repos/myrepo/test /" > /etc/apt/sources.list.d/local.list + +# add the GPG key as a valid key: +cat /repos/myrepo/test/keyfile | apt-key add - + +# update the apt repository and install the signed package +apt-get update +apt-get install --yes testpackage \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 7d35ad3..0000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - simpaltrepo-test: - image: maerteijn/simpeapt-test-image - volumes: - - ..:/usr/local/src - entrypoint: ./docker/entrypoint.sh diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh deleted file mode 100755 index 6478168..0000000 --- a/docker/entrypoint.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# runs the unittests -pip install pip --upgrade -make test -# do some cleanup -if [ -d "/repos/" ]; then - rm -Rf /repos/ -fi - -mkdir /repos -# # now we really create a repo here and add a package -# # the gpg key is build into the docker image for testing purposes -simpleapt create-repo myrepo /repos --gpgkey D2E0953C -simpleapt add-component myrepo test -simpleapt list-repos -cp /usr/local/src/vdt/simpleaptrepo/tests/testdata/*.deb /repos/myrepo/test -simpleapt update-repo myrepo test -simpleapt update-repo myrepo test --skip-signed diff --git a/docker/run-tests.sh b/docker/run-tests.sh new file mode 100755 index 0000000..82e9987 --- /dev/null +++ b/docker/run-tests.sh @@ -0,0 +1,8 @@ +#!/bin/bash +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +# runs the unittests +python3 -m pip install pip --upgrade +pip3 install -e .[dev] +make nosetest diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..906400a --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[pylint.MASTER] +jobs=4 + +[pylint.'MESSAGES CONTROL'] +disable = R,C,W5103 diff --git a/setup.py b/setup.py index 6db9f2a..3fff591 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -__version__ = "0.0.5" +__version__ = "1.0.0" setup( @@ -14,19 +14,18 @@ 'License :: OSI Approved :: BSD License', 'Operating System :: Unix', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', - + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', ], keywords='', author='Martijn Jacobs', - author_email='martijn@devopsconsulting.nl', + author_email='maerteijn@gmail.com', url='https://github.com/devopsconsulting/vdt.simpleaptrepo', - license='BSD', + license='MIT', # include all packages in the egg, except the test package. packages=find_packages( exclude=['ez_setup', 'examples', '*tests']), @@ -48,5 +47,7 @@ # mark test target to require extras. extras_require={ 'dev': ['nose', 'coverage', 'mock', 'twine'], + 'lint': ['black', 'pylint'], }, + python_requires='>=3.5', ) diff --git a/vdt/__init__.py b/vdt/__init__.py index de40ea7..5284146 100644 --- a/vdt/__init__.py +++ b/vdt/__init__.py @@ -1 +1 @@ -__import__('pkg_resources').declare_namespace(__name__) +__import__("pkg_resources").declare_namespace(__name__) diff --git a/vdt/simpleaptrepo/cli.py b/vdt/simpleaptrepo/cli.py index 063bcb4..a20d337 100644 --- a/vdt/simpleaptrepo/cli.py +++ b/vdt/simpleaptrepo/cli.py @@ -10,7 +10,7 @@ def cli(): pass -@cli.command(name='create-gpg-key') +@cli.command(name="create-gpg-key") def create_key(): """Creates a GPG key""" try: @@ -22,10 +22,10 @@ def create_key(): click.echo("Now add a repository with the 'create-repo' command") -@cli.command(name='create-repo') -@click.argument('name') -@click.argument('path', default=".") -@click.option('--gpgkey', help='The GPG key to sign the packages with') +@cli.command(name="create-repo") +@click.argument("name") +@click.argument("path", default=".") +@click.option("--gpgkey", help="The GPG key to sign the packages with") def create_repo(name, path, gpgkey=""): """Creates a repository""" try: @@ -37,9 +37,9 @@ def create_repo(name, path, gpgkey=""): click.echo("Now add a component with the 'add-component' command") -@cli.command(name='add-component') -@click.argument('name') -@click.argument('component', default="main") +@cli.command(name="add-component") +@click.argument("name") +@click.argument("component", default="main") def add_component(name, component): """Creates a component (ie, 'main', 'production')""" try: @@ -54,28 +54,25 @@ def add_component(name, component): click.echo("and run the 'update-repo' command") click.echo("") click.echo( - "After that, configure your webservice " - "to set the www-root to %s " % root) - click.echo( - "Add http:///%s/%s / to your sources.list" % ( - name, component)) + "After that, configure your webservice " "to set the www-root to %s " % root + ) + click.echo("Add http:///%s/%s / to your sources.list" % (name, component)) click.echo("") - click.echo( - "Add the key on the host where you want to install the packages.") + click.echo("Add the key on the host where you want to install the packages.") click.echo("(This is only needed once per repository)") click.echo( - "wget -qO - http:///%s/%s/keyfile | sudo apt-key add -" % ( - name, component)) + "wget -qO - http:///%s/%s/keyfile | sudo apt-key add -" + % (name, component) + ) -@cli.command(name='update-repo') -@click.argument('name') -@click.argument('component', default="main") -@click.option( - '--skip-signed', is_flag=True, help='Skip already signed packaged') +@cli.command(name="update-repo") +@click.argument("name") +@click.argument("component", default="main") +@click.option("--skip-signed", is_flag=True, help="Skip already signed packaged") def update_repo(name, component, skip_signed=False): """Updates a repo's component by scanning the debian packages - and add the index files. + and add the index files. """ try: repo_cfg = apt_repo.get_repo_config(name) @@ -83,19 +80,20 @@ def update_repo(name, component, skip_signed=False): except ValueError as e: raise click.BadParameter(str(e)) - gpgkey = repo_cfg.get('gpgkey', None) + gpgkey = repo_cfg.get("gpgkey", None) apt_repo.update_component( - component_path, gpgkey, skip_signed, output_command=click.echo) + component_path, gpgkey, skip_signed, output_command=click.echo + ) -@cli.command('list-repos') +@cli.command("list-repos") def list_repos(): """List currently configured repos""" repos = apt_repo.list_repos() for repo in repos: - click.echo(repo.get('name')) - for component in repo.get('components'): + click.echo(repo.get("name")) + for component in repo.get("components"): click.echo(" {0}".format(component)) @@ -105,5 +103,6 @@ def main(): else: click.echo("You are not on debian or ubuntu, aborting!") + if __name__ == "__main__": main() diff --git a/vdt/simpleaptrepo/config.py b/vdt/simpleaptrepo/config.py index 78e6b50..9a2f8ca 100644 --- a/vdt/simpleaptrepo/config.py +++ b/vdt/simpleaptrepo/config.py @@ -1,7 +1,4 @@ -try: - import ConfigParser # python 2 -except: - import configparser as ConfigParser # python 3 +import configparser as ConfigParser import os @@ -22,10 +19,10 @@ def add_repo_config(self, name, path, gpgkey=""): if not self.config.has_section(name): self.config.add_section(name) - self.config.set(name, 'path', path) + self.config.set(name, "path", path) if gpgkey: - self.config.set(name, 'gpgkey', gpgkey) + self.config.set(name, "gpgkey", gpgkey) self.save_config() diff --git a/vdt/simpleaptrepo/repo.py b/vdt/simpleaptrepo/repo.py index 6f29065..d6dc2bf 100644 --- a/vdt/simpleaptrepo/repo.py +++ b/vdt/simpleaptrepo/repo.py @@ -12,13 +12,15 @@ def create_gpg_key(output_command): try: output_command(subprocess.check_output(cmd, shell=True)) except subprocess.CalledProcessError as e: - raise ValueError(e) + raise ValueError from e def export_pubkey(path, gpgkey, output_command): - key_path = os.path.join(path, 'keyfile') - cmd = "/usr/bin/gpg --yes --output %s --armor --export %s" % ( - key_path, gpgkey) + key_path = os.path.join(path, "keyfile") + cmd = "/usr/bin/gpg --digest-algo SHA256 --yes --output %s --armor --export %s" % ( + key_path, + gpgkey, + ) subprocess.check_output(cmd, shell=True) output_command("Exported key %s to %s" % (gpgkey, key_path)) @@ -28,13 +30,14 @@ def sign_packages(path, gpgkey, skip_signed, output_command): for deb_file in glob(os.path.join(path, "*.deb")): try: output = subprocess.check_output( - "dpkg-sig --verify %s" % deb_file, shell=True) + "dpkg-sig --verify %s" % deb_file, shell=True + ) except subprocess.CalledProcessError as e: # this is pretty strange, as the command is returning an error code # but still could have run succesful output = e.output - if "_gpgbuilder" in output: + if b"_gpgbuilder" in output: if skip_signed: output_command("Skipped signing %s" % deb_file) @@ -43,47 +46,50 @@ def sign_packages(path, gpgkey, skip_signed, output_command): output_command("Package %s already signed!" % deb_file) output_command("Removing signature") - subprocess.check_output( - "ar -d %s _gpgbuilder" % deb_file, shell=True) + subprocess.check_output("ar -d %s _gpgbuilder" % deb_file, shell=True) # we should match the gpgbuilder output with a regex, but for now # we do this for a quickfix. The output can be _gpgbuilder or # _gpgbuilder0, probably _gpgbuilder1 etc too - subprocess.check_output( - "ar -d %s _gpgbuilder0" % deb_file, shell=True) + subprocess.check_output("ar -d %s _gpgbuilder0" % deb_file, shell=True) # sign again output_command("Signed package %s" % deb_file) subprocess.check_output( - "/usr/bin/dpkg-sig -k %s --sign builder %s" % ( - gpgkey, deb_file), shell=True) + "/usr/bin/dpkg-sig -k %s --sign builder %s" % (gpgkey, deb_file), shell=True + ) def create_package_index(path, output_command): output_command("Creates Packages") subprocess.check_output( - "/usr/bin/apt-ftparchive packages . > Packages", shell=True, cwd=path) + "/usr/bin/apt-ftparchive packages . > Packages", shell=True, cwd=path + ) output_command("Creates Packages.gz") - subprocess.check_output( - "/bin/gzip -c Packages > Packages.gz", shell=True, cwd=path) + subprocess.check_output("/bin/gzip -c Packages > Packages.gz", shell=True, cwd=path) def create_signed_releases_index(path, gpgkey, output_command): output_command("Create Release with key %s" % gpgkey) subprocess.check_output( - "/usr/bin/apt-ftparchive release . > Release", shell=True, cwd=path) + "/usr/bin/apt-ftparchive release . > Release", shell=True, cwd=path + ) output_command("Create InRelease with key %s" % gpgkey) subprocess.check_output( - "/usr/bin/gpg --yes -u 0x%s --clearsign -o InRelease Release" % ( - gpgkey), shell=True, cwd=path) + "/usr/bin/gpg --digest-algo SHA256 --yes -u 0x%s --clearsign -o InRelease Release" + % (gpgkey), + shell=True, + cwd=path, + ) output_command("Create Releases.gpg with key %s" % gpgkey) subprocess.check_output( - "/usr/bin/gpg --yes -u 0x%s -abs -o Release.gpg Release" % ( - gpgkey), shell=True, cwd=path) + "/usr/bin/gpg --yes -u 0x%s -abs -o Release.gpg Release" % (gpgkey), + shell=True, + cwd=path, + ) class SimpleAPTRepo(Config): - def add_repo(self, name, path, gpgkey=""): if not os.path.exists(path): raise ValueError("Path does not exists!") @@ -99,7 +105,7 @@ def add_repo(self, name, path, gpgkey=""): def add_component(self, name, component): repo_cfg = self.get_repo_config(name) - path = os.path.join(repo_cfg['path'], component) + path = os.path.join(repo_cfg["path"], component) if os.path.exists(path): raise ValueError("Directory %s already exists!" % path) os.mkdir(path) @@ -108,7 +114,7 @@ def add_component(self, name, component): def get_component_path(self, name, component): repo_cfg = self.get_repo_config(name) - path = os.path.join(repo_cfg.get('path'), component) + path = os.path.join(repo_cfg.get("path"), component) if not os.path.exists(path): raise ValueError("Component '%s' does not exist!" % component) return path @@ -118,16 +124,16 @@ def list_repos(self): for section in self.config.sections(): repo = {} repo_cfg = self.get_repo_config(section) - if repo_cfg.get('gpgkey'): - section = "%s (gpgkey: %s)" % (section, repo_cfg.get('gpgkey')) - repo['name'] = section - repo['components'] = os.listdir(repo_cfg.get('path')) + if repo_cfg.get("gpgkey"): + section = "%s (gpgkey: %s)" % (section, repo_cfg.get("gpgkey")) + repo["name"] = section + repo["components"] = os.listdir(repo_cfg.get("path")) result.append(repo) return result def update_component( - self, path, gpgkey=None, skip_signed=False, - output_command=write_to_stdout): + self, path, gpgkey=None, skip_signed=False, output_command=write_to_stdout + ): if gpgkey is not None: # export keyfile export_pubkey(path, gpgkey, output_command) diff --git a/vdt/simpleaptrepo/tests/test_cli.py b/vdt/simpleaptrepo/tests/test_cli.py index a12aa64..20339a3 100644 --- a/vdt/simpleaptrepo/tests/test_cli.py +++ b/vdt/simpleaptrepo/tests/test_cli.py @@ -1,7 +1,4 @@ -try: - import ConfigParser # python 2 -except: - import configparser as ConfigParser # python 3 +import configparser as ConfigParser import os import shutil @@ -29,8 +26,9 @@ """ CREATE_REPO_NO_PARAMS_OUTPUT = """Usage: create-repo [OPTIONS] NAME [PATH] +Try 'create-repo --help' for help. -Error: Missing argument "name". +Error: Missing argument 'NAME'. """ LIST_REPOS_OUTPUT = """my_repo (gpgkey: 123456) @@ -47,7 +45,6 @@ class TestCLI(unittest.TestCase): - def setUp(self): # patch the aptrepo instance to write the file to the current # directory, re-read the sections @@ -68,7 +65,7 @@ def tearDown(self): cli.apt_repo.config = ConfigParser.ConfigParser() - @mock.patch('subprocess.check_output', return_value="GPG OUTPUT") + @mock.patch("subprocess.check_output", return_value="GPG OUTPUT") def test_create_gpg_key(self, mock_subprocess): runner = CliRunner() result = runner.invoke(cli.create_key) @@ -80,7 +77,7 @@ def test_create_gpg_key(self, mock_subprocess): # click's output should be captured correctly self.assertEqual(result.output, GPG_KEY_OUTPUT) - @mock.patch('subprocess.check_output', side_effect=ValueError('GPG ERROR')) + @mock.patch("subprocess.check_output", side_effect=ValueError("GPG ERROR")) def test_create_gpg_key_exception(self, mock_subprocess): runner = CliRunner() result = runner.invoke(cli.create_key) @@ -96,8 +93,7 @@ def test_create_repo_and_component(self): runner = CliRunner() with runner.isolated_filesystem(): - result = runner.invoke( - cli.create_repo, ["my_repo", "--gpgkey", "123456"]) + result = runner.invoke(cli.create_repo, ["my_repo", "--gpgkey", "123456"]) # command should be run without error self.assertEqual(result.exit_code, 0) @@ -112,19 +108,19 @@ def test_create_repo_and_component(self): self.assertTrue(os.path.exists(cli.apt_repo.path)) # now create a component - result = runner.invoke( - cli.add_component, ["my_repo", "main"]) + result = runner.invoke(cli.add_component, ["my_repo", "main"]) # command should be run without error self.assertEqual(result.exit_code, 0) # click's output should be captured correctly self.assertTrue( - "Add http:///my_repo/main / to your sources.list" in result.output) # noqa + "Add http:///my_repo/main / to your sources.list" + in result.output + ) # noqa # adding the same component should raise an error - result = runner.invoke( - cli.add_component, ["my_repo", "main"]) + result = runner.invoke(cli.add_component, ["my_repo", "main"]) self.assertEqual(result.exit_code, 2) self.assertTrue("already exists!" in result.output) @@ -136,21 +132,21 @@ def test_create_repo_and_component(self): self.assertTrue(os.path.exists("another_repo")) # now create a component - result = runner.invoke( - cli.add_component, ["another_repo", "main"]) + result = runner.invoke(cli.add_component, ["another_repo", "main"]) # command should be run without error self.assertEqual(result.exit_code, 0) # click's output should be captured correctly self.assertTrue( - "Add http:///another_repo/main / to your sources.list" in result.output) # noqa + "Add http:///another_repo/main / to your sources.list" + in result.output + ) # noqa def test_create_repo_unkown_path(self): runner = CliRunner() with runner.isolated_filesystem(): - result = runner.invoke( - cli.create_repo, ["my_repo", "/unknown/path/"]) + result = runner.invoke(cli.create_repo, ["my_repo", "/unknown/path/"]) # there is an error as the path is unknown self.assertEqual(result.exit_code, 2) @@ -171,8 +167,7 @@ def test_list_repos(self): # create a repo and a component with runner.isolated_filesystem(): - result = runner.invoke( - cli.create_repo, ["my_repo", "--gpgkey", "123456"]) + result = runner.invoke(cli.create_repo, ["my_repo", "--gpgkey", "123456"]) self.assertEqual(result.exit_code, 0) result = runner.invoke(cli.add_component, ["my_repo", "main"]) self.assertEqual(result.exit_code, 0) @@ -182,28 +177,24 @@ def test_list_repos(self): self.assertEqual(result.exit_code, 0) self.assertEqual(result.output, LIST_REPOS_OUTPUT) - @mock.patch('subprocess.check_output', return_value="Mocked output") - def test_update_repo(self, mock_subprocess=None): + @mock.patch("subprocess.check_output", return_value="Mocked output") + def test_update_repo(self, mock_subprocess=None): # pylint: disable=W0613 runner = CliRunner() with runner.isolated_filesystem(): # create a repo and a component - result = runner.invoke( - cli.create_repo, ["my_repo", "--gpgkey", "123456"]) + result = runner.invoke(cli.create_repo, ["my_repo", "--gpgkey", "123456"]) self.assertEqual(result.exit_code, 0) result = runner.invoke(cli.add_component, ["my_repo", "main"]) self.assertEqual(result.exit_code, 0) # we mock everything, however, the runner still should say that # everything is created / updated - result = runner.invoke( - cli.update_repo, ["my_repo", "main"]) + result = runner.invoke(cli.update_repo, ["my_repo", "main"]) self.assertEqual(result.exit_code, 0) self.assertIn(UPDATE_REPO_OUTPUT, result.output) # Let's update an component which does not exist - result = runner.invoke( - cli.update_repo, ["my_repo", "i-am-not-there"]) + result = runner.invoke(cli.update_repo, ["my_repo", "i-am-not-there"]) self.assertEqual(result.exit_code, 2) - self.assertIn( - "Component 'i-am-not-there' does not exist!", result.output) + self.assertIn("Component 'i-am-not-there' does not exist!", result.output) diff --git a/vdt/simpleaptrepo/tests/test_config.py b/vdt/simpleaptrepo/tests/test_config.py index 8bd05cf..2bdc61f 100644 --- a/vdt/simpleaptrepo/tests/test_config.py +++ b/vdt/simpleaptrepo/tests/test_config.py @@ -5,7 +5,6 @@ class TestConfig(unittest.TestCase): - def setUp(self): config.HOME = os.getcwd() self.configfile = os.path.join(os.getcwd(), ".simpleapt.ini") @@ -26,7 +25,7 @@ def test_add_repo_config(self): config_obj.add_repo_config(name="test", path="/www", gpgkey="123456") # check the values of path and gpgkey - section = config_obj.config.items('test') + section = config_obj.config.items("test") self.assertEqual(section[0][1], "/www") self.assertEqual(section[1][1], "123456") @@ -36,8 +35,8 @@ def test_get_repo_config(self): # this should be fine cfg = config_obj.get_repo_config(name="test") - self.assertTrue('path' in cfg) - self.assertTrue('gpgkey' in cfg) + self.assertTrue("path" in cfg) + self.assertTrue("gpgkey" in cfg) # a unkown name should raise an exception self.assertRaises(ValueError, config_obj.get_repo_config, "unkown") diff --git a/vdt/simpleaptrepo/tests/test_utils.py b/vdt/simpleaptrepo/tests/test_utils.py index 59204b2..95d29bc 100644 --- a/vdt/simpleaptrepo/tests/test_utils.py +++ b/vdt/simpleaptrepo/tests/test_utils.py @@ -4,25 +4,24 @@ def mock_dist_osx(): - return ('Mac OSX', '10.10.5', 'Yosemity') + return "macOS-10.14.6-x86_64-i386-64bit" def mock_dist_ubuntu(): - return ('Ubuntu', '12.04', 'precise') + return "Linux-4.10.0-40-generic-x86_64-with-Ubuntu-16.04-xenial" def mock_dist_debian(): - return ('debian', '8.6', '') + return "Linux-4.10.0-40-generic-x86_64-with-Debian-10" class TestUtils(unittest.TestCase): - def test_platform_is_debian(self): - utils.platform.dist = mock_dist_osx + utils.platform.platform = mock_dist_osx self.assertFalse(utils.platform_is_debian()) - utils.platform.dist = mock_dist_ubuntu + utils.platform.platform = mock_dist_ubuntu self.assertTrue(utils.platform_is_debian()) - utils.platform.dist = mock_dist_debian + utils.platform.platform = mock_dist_debian self.assertTrue(utils.platform_is_debian()) diff --git a/vdt/simpleaptrepo/tests/testdata/python-vdt.simpleaptrepo_0.0.3_all.deb b/vdt/simpleaptrepo/tests/testdata/python-vdt.simpleaptrepo_0.0.3_all.deb deleted file mode 100644 index 0a5087d..0000000 Binary files a/vdt/simpleaptrepo/tests/testdata/python-vdt.simpleaptrepo_0.0.3_all.deb and /dev/null differ diff --git a/vdt/simpleaptrepo/tests/testdata/testpackage_1.0_amd64.deb b/vdt/simpleaptrepo/tests/testdata/testpackage_1.0_amd64.deb new file mode 100644 index 0000000..7d3de60 Binary files /dev/null and b/vdt/simpleaptrepo/tests/testdata/testpackage_1.0_amd64.deb differ diff --git a/vdt/simpleaptrepo/utils.py b/vdt/simpleaptrepo/utils.py index a7fce9c..5dd10d8 100644 --- a/vdt/simpleaptrepo/utils.py +++ b/vdt/simpleaptrepo/utils.py @@ -21,10 +21,10 @@ def repo_root(path): def write_to_stdout(message): - unbuffered_output = os.fdopen(sys.stdout.fileno(), 'w', 0) + unbuffered_output = os.fdopen(sys.stdout.fileno(), "w", 0) unbuffered_output.write("%s\n" % message) def platform_is_debian(): - current_platform = platform.dist()[0].lower() - return current_platform in ["ubuntu", "debian"] + current_platform = platform.platform().lower() + return "ubuntu" in current_platform or "debian" in current_platform