Exemple #1
0
    def test_spawn(self):
        tmpdir = self.mkdtemp()

        # creating something executable
        # through the shell that returns 1
        if os.name == 'posix':
            exe = os.path.join(tmpdir, 'foo.sh')
            self.write_file(exe, '#!/bin/sh\nexit 1')
            os.chmod(exe, 0777)
        else:
            exe = os.path.join(tmpdir, 'foo.bat')
            self.write_file(exe, 'exit 1')

        os.chmod(exe, 0777)
        self.assertRaises(DistutilsExecError, spawn, [exe])

        # now something that works
        if os.name == 'posix':
            exe = os.path.join(tmpdir, 'foo.sh')
            self.write_file(exe, '#!/bin/sh\nexit 0')
            os.chmod(exe, 0777)
        else:
            exe = os.path.join(tmpdir, 'foo.bat')
            self.write_file(exe, 'exit 0')

        os.chmod(exe, 0777)
        spawn([exe])  # should work without any error
 def spawn(self, cmd):
     spawn(cmd, dry_run=self.dry_run)
Exemple #3
0
    def upload_file(self, command, pyversion, filename):
        # Makes sure the repository URL is compliant
        schema, netloc, url, params, query, fragments = \
            urlparse.urlparse(self.repository)
        if params or query or fragments:
            raise AssertionError("Incompatible url %s" % self.repository)

        if schema not in ('http', 'https'):
            raise AssertionError("unsupported schema " + schema)

        # Sign if requested
        if self.sign:
            gpg_args = ["gpg", "--detach-sign", "-a", filename]
            if self.identity:
                gpg_args[2:2] = ["--local-user", self.identity]
            spawn(gpg_args,
                  dry_run=self.dry_run)

        # Fill in the data - send all the metadata in case we need to
        # register a new release
        content = open(filename,'rb').read()

        data = metadata_to_dict(self.distribution.metadata)

        # extra upload infos
        data[':action'] = 'file_upload'
        data['protcol_version'] = '1'
        data['content'] = [os.path.basename(filename), content]
        data['filetype'] = command
        data['pyversion'] = pyversion
        data['md5_digest'] = md5(content).hexdigest()

        comment = ''
        if command == 'bdist_dumb':
            comment = 'built for %s' % platform.platform(terse=1)
        data['comment'] = comment

        if self.sign:
            data['gpg_signature'] = [(os.path.basename(filename) + ".asc",
                                      open(filename+".asc").read())]

        # set up the authentication
        auth = "Basic " + standard_b64encode(self.username + ":" +
                                             self.password)

        # Build up the MIME payload for the POST data
        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
        sep_boundary = '\n--' + boundary
        end_boundary = sep_boundary + '--'
        body = StringIO()
        file_fields = ('content', 'gpg_signature')

        for key, values in data.items():
            # handle multiple entries for the same name
            if not isinstance(values, (tuple, list)):
                values = [values]

            content_dispo = 'Content-Disposition: form-data; name="%s"' % key

            if key in file_fields:
                filename_, content = values
                filename_ = ';filename="%s"' % filename_
                body.write(sep_boundary)
                body.write("\n")
                body.write(content_dispo)
                body.write(filename_)
                body.write("\n\n")
                body.write(content)
            else:
                for value in values:
                    body.write(sep_boundary)
                    body.write("\n")
                    body.write(content_dispo)
                    body.write("\n\n")
                    body.write(value)
                    if value and value[-1] == '\r':
                        # write an extra newline (lurve Macs)
                        body.write('\n')

        body.write(end_boundary)
        body.write("\n")
        body = body.getvalue()

        self.announce("Submitting %s to %s" % (filename, self.repository),
                      log.INFO)

        # build the Request
        headers = {'Content-type':
                        'multipart/form-data; boundary=%s' % boundary,
                   'Content-length': str(len(body)),
                   'Authorization': auth}

        request = Request(self.repository, data=body,
                          headers=headers)
        # send the data
        try:
            result = urlopen(request)
            status = result.code
            reason = result.msg
        except socket.error, e:
            self.announce(str(e), log.ERROR)
            return
Exemple #4
0
 def spawn(self, cmd, search_path=1, level=1):
     """Spawn an external command respecting dry-run flag."""
     from distutils2.util import spawn
     spawn(cmd, search_path, dry_run= self.dry_run)
Exemple #5
0
    def upload_file(self, command, pyversion, filename):
        # Makes sure the repository URL is compliant
        scheme, netloc, url, params, query, fragments = \
            urllib.parse.urlparse(self.repository)
        if params or query or fragments:
            raise AssertionError("Incompatible url %s" % self.repository)

        if scheme not in ('http', 'https'):
            raise AssertionError("unsupported scheme " + scheme)

        # Sign if requested
        if self.sign:
            gpg_args = ["gpg", "--detach-sign", "-a", filename]
            if self.identity:
                gpg_args[2:2] = ["--local-user", self.identity]
            spawn(gpg_args,
                  dry_run=self.dry_run)

        # Fill in the data - send all the metadata in case we need to
        # register a new release
        with open(filename, 'rb') as f:
            content = f.read()

        data = self.distribution.metadata.todict()

        # extra upload infos
        data[':action'] = 'file_upload'
        data['protcol_version'] = '1'
        data['content'] = (os.path.basename(filename), content)
        data['filetype'] = command
        data['pyversion'] = pyversion
        data['md5_digest'] = md5(content).hexdigest()

        if command == 'bdist_dumb':
            data['comment'] = 'built for %s' % platform.platform(terse=True)

        if self.sign:
            with open(filename + '.asc') as fp:
                sig = fp.read()
            data['gpg_signature'] = [
                (os.path.basename(filename) + ".asc", sig)]

        # set up the authentication
        # The exact encoding of the authentication string is debated.
        # Anyway PyPI only accepts ascii for both username or password.
        user_pass = (self.username + ":" + self.password).encode('ascii')
        auth = b"Basic " + standard_b64encode(user_pass)

        # Build up the MIME payload for the POST data
        files = []
        for key in ('content', 'gpg_signature'):
            if key in data:
                filename_, value = data.pop(key)
                files.append((key, filename_, value))

        content_type, body = encode_multipart(data.items(), files)

        logger.info("Submitting %s to %s", filename, self.repository)

        # build the Request
        headers = {'Content-type': content_type,
                   'Content-length': str(len(body)),
                   'Authorization': auth}

        request = Request(self.repository, body, headers)
        # send the data
        try:
            result = urlopen(request)
            status = result.code
            reason = result.msg
        except socket.error as e:
            logger.error(e)
            return
        except HTTPError as e:
            status = e.code
            reason = e.msg

        if status == 200:
            logger.info('Server response (%s): %s', status, reason)
        else:
            logger.error('Upload failed (%s): %s', status, reason)

        if self.show_response and logger.isEnabledFor(logging.INFO):
            sep = '-' * 75
            logger.info('%s\n%s\n%s', sep, result.read().decode(), sep)
Exemple #6
0
 def spawn(self, cmd):
     spawn(cmd, dry_run=self.dry_run)
Exemple #7
0
    def upload_file(self, command, pyversion, filename):
        # Makes sure the repository URL is compliant
        scheme, netloc, url, params, query, fragments = \
            urlparse.urlparse(self.repository)
        if params or query or fragments:
            raise AssertionError("Incompatible url %s" % self.repository)

        if scheme not in ('http', 'https'):
            raise AssertionError("unsupported scheme " + scheme)

        # Sign if requested
        if self.sign:
            gpg_args = ["gpg", "--detach-sign", "-a", filename]
            if self.identity:
                gpg_args[2:2] = ["--local-user", self.identity]
            spawn(gpg_args,
                  dry_run=self.dry_run)

        # Fill in the data - send all the metadata in case we need to
        # register a new release
        f = open(filename, 'rb')
        try:
            content = f.read()
        finally:
            f.close()

        data = self.distribution.metadata.todict()

        # extra upload infos
        data[':action'] = 'file_upload'
        data['protcol_version'] = '1'
        data['content'] = (os.path.basename(filename), content)
        data['filetype'] = command
        data['pyversion'] = pyversion
        data['md5_digest'] = md5(content).hexdigest()

        if command == 'bdist_dumb':
            data['comment'] = 'built for %s' % platform.platform(terse=True)

        if self.sign:
            fp = open(filename + '.asc')
            try:
                sig = fp.read()
            finally:
                fp.close()
            data['gpg_signature'] = [
                (os.path.basename(filename) + ".asc", sig)]

        # set up the authentication
        # The exact encoding of the authentication string is debated.
        # Anyway PyPI only accepts ascii for both username or password.
        user_pass = (self.username + ":" + self.password).encode('ascii')
        auth = "Basic " + standard_b64encode(user_pass)

        # Build up the MIME payload for the POST data
        files = []
        for key in ('content', 'gpg_signature'):
            if key in data:
                filename_, value = data.pop(key)
                files.append((key, filename_, value))

        content_type, body = encode_multipart(data.items(), files)

        logger.info("Submitting %s to %s", filename, self.repository)

        # build the Request
        headers = {'Content-type': content_type,
                   'Content-length': str(len(body)),
                   'Authorization': auth}

        request = Request(self.repository, body, headers)
        # send the data
        try:
            result = urlopen(request)
            status = result.code
            reason = result.msg
        except socket.error, e:
            logger.error(e)
            return
Exemple #8
0
 def spawn(self, cmd, search_path=True, level=1):
     """Spawn an external command respecting dry-run flag."""
     from distutils2.util import spawn
     spawn(cmd, search_path, dry_run=self.dry_run)