Ejemplo n.º 1
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description='Create wheels for all given project versions and upload them to the given index.')
    parser.add_argument('requirements',
                        help='requirements.txt style file specifying which project versions to package.')
    parser.add_argument('index', help='The index to upload the packaged software to.')
    parser.add_argument('--batch',
                        default=False,
                        action='store_true',
                        help='Batch mode. Do not prompt for credentials')
    parser.add_argument('--user',
                        default=os.environ.get('DEVPI_USER'),
                        help='The user to log in as.')
    parser.add_argument('--password',
                        default=os.environ.get('DEVPI_PASSWORD'),
                        help='Password of the user.')
    parser.add_argument('--blacklist', help='Packages matched by this requirements.txt style file will never be build.')
    parser.add_argument('--pure-index',
                        help='The index to use for pure packages. Any non-pure package will be uploaded '
                             'to the index given as positional argument. Packages already found in the '
                             'pure index will not be built, either.'
                        )
    parser.add_argument('--junit-xml',
                        help='Write information about the build success / failure to a JUnit-compatible XML file.')
    parser.add_argument('--run-id',
                        help='Add the given string to all entries in the XML output, allowing to distinguish output from multiple runs in a merged XML.')
    parser.add_argument('--dry-run', help='Build missing wheels, but do not modify the state of the devpi server.',
                        action='store_true')
    parser.add_argument('--client-cert', help='Client key to use to authenticate with the devpi server.', default=None)
    args = parser.parse_args(args=args)
    if not args.batch:
        if args.user is None:
            args.user = input('Username: '******'Password: ')

    packages = requirements.read_exact_versions(args.requirements)
    with wheeler.Builder() as builder, DevpiClient(args.index, args.user, args.password,
                                                   client_cert=args.client_cert) as devpi_client:
        if args.pure_index:
            with DevpiClient(args.pure_index, args.user, args.password,
                             client_cert=args.client_cert) as pure_index_client:
                processor = Processor(builder, devpi_client, args.blacklist, pure_index_client,
                                      junit_xml=args.junit_xml, dry_run=args.dry_run, run_id=args.run_id)
                processor.build_packages(packages)
        else:
            processor = Processor(builder, devpi_client, args.blacklist, junit_xml=args.junit_xml, dry_run=args.dry_run,
                                  run_id=args.run_id)
            processor.build_packages(packages)
Ejemplo n.º 2
0
def TestServer(users={}, indices={}, config={}, fail_on_output=['Traceback']):
    """
    Starts a devpi server to be used within tests.
    """
    with temporary_dir() as server_dir:

        server_options = {
            'port': 2414,
            'serverdir': server_dir}
        server_options.update(config)

        if 'serverdir' not in config:
            prefill_serverdir(server_options)

        with DevpiServer(server_options) as url:
            with DevpiClient(url, 'root', '') as client:

                for user, kwargs in iteritems(users):
                    client.create_user(user, **kwargs)

                for index, kwargs in iteritems(indices):
                    client.create_index(index, **kwargs)

                yield client

        _assert_no_logged_errors(fail_on_output, server_options['serverdir'] + '/.xproc/devpi-server/xprocess.log')
Ejemplo n.º 3
0
def TestServer(users={}, indices={}, config={}, fail_on_output=['Traceback']):
    """
    Starts a devpi server to be used within tests.
    """
    with temporary_dir() as server_dir:

        server_options = {
            'host': os.getenv('DEVPI_PLUMBER_SERVER_HOST', 'localhost'),
            'port': os.getenv('DEVPI_PLUMBER_SERVER_PORT', 2414),
            'serverdir': server_dir,
        }
        server_options.update(config)

        initialize_serverdir(server_options)

        with DevpiServer(server_options) as url:
            with DevpiClient(url, 'root', '') as client:

                for user, kwargs in iteritems(users):
                    client.create_user(user, **kwargs)

                for index, kwargs in iteritems(indices):
                    client.create_index(index, **kwargs)

                yield client

        _assert_no_logged_errors(fail_on_output,
                                 server_options['serverdir'] + '/server.log')
Ejemplo n.º 4
0
    def test_dry_run(self):
        """
        Test that a dry run produces the same ``junit.xml`` as a run without dry-run but does not modify the server
        state.
        """
        with TestServer(USERS, INDICES) as devpi:
            with DevpiClient(devpi.server_url + '/' + INDEX, USER,
                             PASSWORD) as client:
                client.upload(
                    'tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl'
                )

            tempdir = tempfile.mkdtemp()
            try:
                junit_filename = os.path.join(tempdir, 'junit.xml')
                main([
                    'tests/fixture/sample_junit.txt',
                    devpi.url + '/' + INDEX,
                    USER,
                    PASSWORD,
                    '--junit-xml',
                    junit_filename,
                    '--dry-run',
                ])

                self._assert_junit_xml_content(junit_filename)
            finally:
                shutil.rmtree(tempdir)

            self.assertFalse(
                package_version_exists(devpi, INDEX, 'progressbar', '2.2'))
Ejemplo n.º 5
0
def test_reports_junit_xml(devpi, tmpdir):
    with DevpiClient(devpi.server_url + '/' + INDEX,
                     USER,
                     PASSWORD) as client:
        client.upload('tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl')

    junit_filename = str(tmpdir.join('junit.xml'))
    main(['tests/fixture/sample_junit.txt', devpi.url + '/' + INDEX,
          '--user={}'.format(USER),
          '--password={}'.format(PASSWORD), '--junit-xml', junit_filename])

    _assert_junit_xml_content(junit_filename)
Ejemplo n.º 6
0
 def test_devpi_client(self):
     with TestServer() as test_server:
         with DevpiClient(test_server.server_url) as devpi:
             devpi.create_user("user",
                               password="******",
                               email="*****@*****.**")
             self.assertEqual(
                 200,
                 requests.get(devpi.server_url + "/user").status_code)
             self.assertIn("credentials valid",
                           devpi.login("user", "password"))
             self.assertEquals("user", devpi.user)
Ejemplo n.º 7
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description='A utility to batch-remove packages from a Devpi server.',
        epilog='The arguments --dev-only and --version-filter can be combined. In this case only packages passing both filters will be removed.',
    )
    parser.add_argument('server', help='The devpi server to operate on.')
    parser.add_argument('index_spec', metavar='user[/index]', help='The index from which to remove the packages. If only the user part is specified, all indices of that user will be cleaned.')
    parser.add_argument('package_specification', help='The specification of the package version(s) to remove.')
    parser.add_argument('--batch', help='Assume yes on confirmation questions.', action='store_true')
    parser.add_argument('--dev-only', help='Remove only development versions as specified by PEP 440.', action='store_true')
    parser.add_argument('--version-filter', metavar='REGEX', help='Remove only versions in which the given regular expression can be found.')
    parser.add_argument('--versions-to-keep', type=int, help='Number of versions to keep.')
    parser.add_argument('--force', help='Temporarily make indices volatile to enable package removal.', action='store_true')
    parser.add_argument('--password', help='The password with which to authenticate.')
    parser.add_argument('--login', help='The user name to user for authentication. Defaults to the user of the indices to operate on.')
    args = parser.parse_args(args=args)

    login_user = args.login if args.login else args.index_spec.split('/')[0]
    password = args.password
    if password is None:
        password = getpass.getpass()

    try:
        with DevpiClient(args.server, login_user, password) as client:
            packages_by_index = list_packages_by_index(
                client, args.index_spec, args.package_specification, args.dev_only, args.version_filter
            )

            for index, packages in packages_by_index.items():
                print('Packages to be deleted from {}: '.format(index))
                sorted_packages = sorted(packages)
                for package in sorted_packages:
                    print(' * {}'.format(package))

            if not args.batch:
                confirmation = input('Enter "yes" to confirm: ')
                if confirmation != 'yes':
                    print('Aborting...')
                    return

            for index, packages in packages_by_index.items():
                print('Cleaning {}…'.format(index))
                # if len(packages) > 1:
                #     # Make iteration over the packages display a progress bar
                #     packages = ProgressBar()(packages)
                remove_packages(client, index, packages, args.force, args.versions_to_keep)

    except DevpiClientError as client_error:
        print_(client_error, file=sys.stderr)
        sys.exit(1)
Ejemplo n.º 8
0
def test_run_id(devpi, tmpdir):
    RUN_ID = 'my_run_id'

    with DevpiClient(devpi.server_url + '/' + INDEX, USER, PASSWORD) as client:
        client.upload(
            'tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl'
        )

    junit_filename = str(tmpdir.join('junit.xml'))
    main([
        'tests/fixture/sample_junit.txt', devpi.url + '/' + INDEX, USER,
        PASSWORD, '--junit-xml', junit_filename, '--run-id', RUN_ID
    ])

    _assert_junit_xml_content(junit_filename, RUN_ID)
Ejemplo n.º 9
0
def test_not_built_if_on_pure(devpi):
    """
    Verify that packages are not built and re-uploaded if they are already on the pure index.
    """
    with DevpiClient(devpi.server_url + '/' + PURE_INDEX,
                     USER,
                     PASSWORD) as pure_client:
        pure_client.upload('tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl')

        with patch.object(
                wheeler.Builder, 'build', autospec=True, side_effect=Exception('Should not build!')
        ) as mock_build:
            main(['tests/fixture/sample_test_package.txt', devpi.url + '/' + INDEX,
                  '--user={}'.format(USER),
                  '--password={}'.format(PASSWORD), '--pure-index={}'.format(pure_client.url)])
            assert not mock_build.called
Ejemplo n.º 10
0
def test_handles_non_ascii_build_output(devpi, tmpdir, monkeypatch):
    monkeypatch.setenv('PIP_INDEX_URL', devpi.url + '/' + PURE_INDEX)

    with DevpiClient(devpi.server_url + '/' + PURE_INDEX,
                     USER,
                     PASSWORD) as client:
        client.upload('tests/fixture/non-ascii_package/dist/non-ascii-package-0.1.dev1.tar.gz')

    junit_filename = str(tmpdir.join('junit.xml'))

    # our main assertion is that the main does not fail
    main(['tests/fixture/sample_non-ascii.txt', devpi.url + '/' + INDEX,
          '--user={}'.format(USER),
          '--password={}'.format(PASSWORD), '--junit-xml', junit_filename])

    # check that the build failure shows up in the build output
    assert 'No non-ascii 4 you!' in open(junit_filename).read()
Ejemplo n.º 11
0
    def test_reports_junit_xml(self):
        with TestServer(USERS, INDICES) as devpi:

            with DevpiClient(devpi.server_url + '/' + INDEX, USER,
                             PASSWORD) as client:
                client.upload(
                    'tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl'
                )

            tempdir = tempfile.mkdtemp()
            try:
                junit_filename = os.path.join(tempdir, 'junit.xml')
                main([
                    'tests/fixture/sample_junit.txt', devpi.url + '/' + INDEX,
                    USER, PASSWORD, '--junit-xml', junit_filename
                ])

                self._assert_junit_xml_content(junit_filename)
            finally:
                shutil.rmtree(tempdir)
Ejemplo n.º 12
0
def test_dry_run(devpi, tmpdir):
    """
    Test that a dry run produces the same ``junit.xml`` as a run without dry-run but does not modify the server
    state.
    """
    with DevpiClient(devpi.server_url + '/' + INDEX,
                     USER, PASSWORD) as client:
        client.upload('tests/fixture/pure_package/dist/test_package-0.1.dev1-py2.py3-none-any.whl')

    junit_filename = str(tmpdir.join('junit.xml'))
    main([
        'tests/fixture/sample_junit.txt',
        devpi.url + '/' + INDEX,
        '--user={}'.format(USER),
        '--password={}'.format(PASSWORD),
        '--junit-xml', junit_filename,
        '--dry-run',
    ])

    _assert_junit_xml_content(junit_filename)

    assert not _package_version_exists(devpi, INDEX, 'progressbar', '2.2')
Ejemplo n.º 13
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description=
        'Create wheels for all given project versions and upload them to the given index.'
    )
    parser.add_argument(
        'requirements',
        help=
        'requirements.txt style file specifying which project versions to package.'
    )
    parser.add_argument('index',
                        help='The index to upload the packaged software to.')
    parser.add_argument('user', help='The user to log in as.')
    parser.add_argument('password', help='Password of the user.')
    parser.add_argument(
        '--blacklist',
        help=
        'Packages matched by this requirements.txt style file will never be build.'
    )
    parser.add_argument(
        '--pure-index',
        help=
        'The index to use for pure packages. Any non-pure package will be uploaded '
        'to the index given as positional argument. Packages already found in the '
        'pure index will not be built, either.')
    parser.add_argument(
        '--junit-xml',
        help=
        'Write information about the build success / failure to a JUnit-compatible XML file.'
    )
    parser.add_argument(
        '--dry-run',
        help=
        'Build missing wheels, but do not modify the state of the devpi server.',
        action='store_true')
    parser.add_argument(
        '--client-cert',
        help='Client key to use to authenticate with the devpi server.',
        default=None)

    args = parser.parse_args(args=args)

    packages = requirements.read(args.requirements)
    with wheeler.Builder() as builder, DevpiClient(
            args.index, args.user, args.password,
            client_cert=args.client_cert) as devpi_client:
        if args.pure_index:
            with DevpiClient(
                    args.pure_index,
                    args.user,
                    args.password,
                    client_cert=args.client_cert) as pure_index_client:
                processor = Processor(builder,
                                      devpi_client,
                                      args.blacklist,
                                      pure_index_client,
                                      junit_xml=args.junit_xml,
                                      dry_run=args.dry_run)
                processor.build_packages(packages)
        else:
            processor = Processor(builder,
                                  devpi_client,
                                  args.blacklist,
                                  junit_xml=args.junit_xml,
                                  dry_run=args.dry_run)
            processor.build_packages(packages)