xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/distutils/config.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""distutils.pypirc
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerProvides the PyPIRCCommand class, the base class for the command classes
4*cda5da8dSAndroid Build Coastguard Workerthat uses .pypirc in the distutils.command package.
5*cda5da8dSAndroid Build Coastguard Worker"""
6*cda5da8dSAndroid Build Coastguard Workerimport os
7*cda5da8dSAndroid Build Coastguard Workerfrom configparser import RawConfigParser
8*cda5da8dSAndroid Build Coastguard Workerimport warnings
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Workerfrom distutils.cmd import Command
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard WorkerDEFAULT_PYPIRC = """\
13*cda5da8dSAndroid Build Coastguard Worker[distutils]
14*cda5da8dSAndroid Build Coastguard Workerindex-servers =
15*cda5da8dSAndroid Build Coastguard Worker    pypi
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard Worker[pypi]
18*cda5da8dSAndroid Build Coastguard Workerusername:%s
19*cda5da8dSAndroid Build Coastguard Workerpassword:%s
20*cda5da8dSAndroid Build Coastguard Worker"""
21*cda5da8dSAndroid Build Coastguard Worker
22*cda5da8dSAndroid Build Coastguard Workerclass PyPIRCCommand(Command):
23*cda5da8dSAndroid Build Coastguard Worker    """Base command that knows how to handle the .pypirc file
24*cda5da8dSAndroid Build Coastguard Worker    """
25*cda5da8dSAndroid Build Coastguard Worker    DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/'
26*cda5da8dSAndroid Build Coastguard Worker    DEFAULT_REALM = 'pypi'
27*cda5da8dSAndroid Build Coastguard Worker    repository = None
28*cda5da8dSAndroid Build Coastguard Worker    realm = None
29*cda5da8dSAndroid Build Coastguard Worker
30*cda5da8dSAndroid Build Coastguard Worker    user_options = [
31*cda5da8dSAndroid Build Coastguard Worker        ('repository=', 'r',
32*cda5da8dSAndroid Build Coastguard Worker         "url of repository [default: %s]" % \
33*cda5da8dSAndroid Build Coastguard Worker            DEFAULT_REPOSITORY),
34*cda5da8dSAndroid Build Coastguard Worker        ('show-response', None,
35*cda5da8dSAndroid Build Coastguard Worker         'display full response text from server')]
36*cda5da8dSAndroid Build Coastguard Worker
37*cda5da8dSAndroid Build Coastguard Worker    boolean_options = ['show-response']
38*cda5da8dSAndroid Build Coastguard Worker
39*cda5da8dSAndroid Build Coastguard Worker    def _get_rc_file(self):
40*cda5da8dSAndroid Build Coastguard Worker        """Returns rc file path."""
41*cda5da8dSAndroid Build Coastguard Worker        return os.path.join(os.path.expanduser('~'), '.pypirc')
42*cda5da8dSAndroid Build Coastguard Worker
43*cda5da8dSAndroid Build Coastguard Worker    def _store_pypirc(self, username, password):
44*cda5da8dSAndroid Build Coastguard Worker        """Creates a default .pypirc file."""
45*cda5da8dSAndroid Build Coastguard Worker        rc = self._get_rc_file()
46*cda5da8dSAndroid Build Coastguard Worker        with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f:
47*cda5da8dSAndroid Build Coastguard Worker            f.write(DEFAULT_PYPIRC % (username, password))
48*cda5da8dSAndroid Build Coastguard Worker
49*cda5da8dSAndroid Build Coastguard Worker    def _read_pypirc(self):
50*cda5da8dSAndroid Build Coastguard Worker        """Reads the .pypirc file."""
51*cda5da8dSAndroid Build Coastguard Worker        rc = self._get_rc_file()
52*cda5da8dSAndroid Build Coastguard Worker        if os.path.exists(rc):
53*cda5da8dSAndroid Build Coastguard Worker            self.announce('Using PyPI login from %s' % rc)
54*cda5da8dSAndroid Build Coastguard Worker            repository = self.repository or self.DEFAULT_REPOSITORY
55*cda5da8dSAndroid Build Coastguard Worker
56*cda5da8dSAndroid Build Coastguard Worker            config = RawConfigParser()
57*cda5da8dSAndroid Build Coastguard Worker            config.read(rc)
58*cda5da8dSAndroid Build Coastguard Worker            sections = config.sections()
59*cda5da8dSAndroid Build Coastguard Worker            if 'distutils' in sections:
60*cda5da8dSAndroid Build Coastguard Worker                # let's get the list of servers
61*cda5da8dSAndroid Build Coastguard Worker                index_servers = config.get('distutils', 'index-servers')
62*cda5da8dSAndroid Build Coastguard Worker                _servers = [server.strip() for server in
63*cda5da8dSAndroid Build Coastguard Worker                            index_servers.split('\n')
64*cda5da8dSAndroid Build Coastguard Worker                            if server.strip() != '']
65*cda5da8dSAndroid Build Coastguard Worker                if _servers == []:
66*cda5da8dSAndroid Build Coastguard Worker                    # nothing set, let's try to get the default pypi
67*cda5da8dSAndroid Build Coastguard Worker                    if 'pypi' in sections:
68*cda5da8dSAndroid Build Coastguard Worker                        _servers = ['pypi']
69*cda5da8dSAndroid Build Coastguard Worker                    else:
70*cda5da8dSAndroid Build Coastguard Worker                        # the file is not properly defined, returning
71*cda5da8dSAndroid Build Coastguard Worker                        # an empty dict
72*cda5da8dSAndroid Build Coastguard Worker                        return {}
73*cda5da8dSAndroid Build Coastguard Worker                for server in _servers:
74*cda5da8dSAndroid Build Coastguard Worker                    current = {'server': server}
75*cda5da8dSAndroid Build Coastguard Worker                    current['username'] = config.get(server, 'username')
76*cda5da8dSAndroid Build Coastguard Worker
77*cda5da8dSAndroid Build Coastguard Worker                    # optional params
78*cda5da8dSAndroid Build Coastguard Worker                    for key, default in (('repository',
79*cda5da8dSAndroid Build Coastguard Worker                                          self.DEFAULT_REPOSITORY),
80*cda5da8dSAndroid Build Coastguard Worker                                         ('realm', self.DEFAULT_REALM),
81*cda5da8dSAndroid Build Coastguard Worker                                         ('password', None)):
82*cda5da8dSAndroid Build Coastguard Worker                        if config.has_option(server, key):
83*cda5da8dSAndroid Build Coastguard Worker                            current[key] = config.get(server, key)
84*cda5da8dSAndroid Build Coastguard Worker                        else:
85*cda5da8dSAndroid Build Coastguard Worker                            current[key] = default
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Worker                    # work around people having "repository" for the "pypi"
88*cda5da8dSAndroid Build Coastguard Worker                    # section of their config set to the HTTP (rather than
89*cda5da8dSAndroid Build Coastguard Worker                    # HTTPS) URL
90*cda5da8dSAndroid Build Coastguard Worker                    if (server == 'pypi' and
91*cda5da8dSAndroid Build Coastguard Worker                        repository in (self.DEFAULT_REPOSITORY, 'pypi')):
92*cda5da8dSAndroid Build Coastguard Worker                        current['repository'] = self.DEFAULT_REPOSITORY
93*cda5da8dSAndroid Build Coastguard Worker                        return current
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker                    if (current['server'] == repository or
96*cda5da8dSAndroid Build Coastguard Worker                        current['repository'] == repository):
97*cda5da8dSAndroid Build Coastguard Worker                        return current
98*cda5da8dSAndroid Build Coastguard Worker            elif 'server-login' in sections:
99*cda5da8dSAndroid Build Coastguard Worker                # old format
100*cda5da8dSAndroid Build Coastguard Worker                server = 'server-login'
101*cda5da8dSAndroid Build Coastguard Worker                if config.has_option(server, 'repository'):
102*cda5da8dSAndroid Build Coastguard Worker                    repository = config.get(server, 'repository')
103*cda5da8dSAndroid Build Coastguard Worker                else:
104*cda5da8dSAndroid Build Coastguard Worker                    repository = self.DEFAULT_REPOSITORY
105*cda5da8dSAndroid Build Coastguard Worker                return {'username': config.get(server, 'username'),
106*cda5da8dSAndroid Build Coastguard Worker                        'password': config.get(server, 'password'),
107*cda5da8dSAndroid Build Coastguard Worker                        'repository': repository,
108*cda5da8dSAndroid Build Coastguard Worker                        'server': server,
109*cda5da8dSAndroid Build Coastguard Worker                        'realm': self.DEFAULT_REALM}
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard Worker        return {}
112*cda5da8dSAndroid Build Coastguard Worker
113*cda5da8dSAndroid Build Coastguard Worker    def _read_pypi_response(self, response):
114*cda5da8dSAndroid Build Coastguard Worker        """Read and decode a PyPI HTTP response."""
115*cda5da8dSAndroid Build Coastguard Worker        with warnings.catch_warnings():
116*cda5da8dSAndroid Build Coastguard Worker            warnings.simplefilter("ignore", DeprecationWarning)
117*cda5da8dSAndroid Build Coastguard Worker            import cgi
118*cda5da8dSAndroid Build Coastguard Worker        content_type = response.getheader('content-type', 'text/plain')
119*cda5da8dSAndroid Build Coastguard Worker        encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii')
120*cda5da8dSAndroid Build Coastguard Worker        return response.read().decode(encoding)
121*cda5da8dSAndroid Build Coastguard Worker
122*cda5da8dSAndroid Build Coastguard Worker    def initialize_options(self):
123*cda5da8dSAndroid Build Coastguard Worker        """Initialize options."""
124*cda5da8dSAndroid Build Coastguard Worker        self.repository = None
125*cda5da8dSAndroid Build Coastguard Worker        self.realm = None
126*cda5da8dSAndroid Build Coastguard Worker        self.show_response = 0
127*cda5da8dSAndroid Build Coastguard Worker
128*cda5da8dSAndroid Build Coastguard Worker    def finalize_options(self):
129*cda5da8dSAndroid Build Coastguard Worker        """Finalizes options."""
130*cda5da8dSAndroid Build Coastguard Worker        if self.repository is None:
131*cda5da8dSAndroid Build Coastguard Worker            self.repository = self.DEFAULT_REPOSITORY
132*cda5da8dSAndroid Build Coastguard Worker        if self.realm is None:
133*cda5da8dSAndroid Build Coastguard Worker            self.realm = self.DEFAULT_REALM
134