This file is indexed.

/usr/lib/python3/dist-packages/bloom/config.py is in python3-bloom 0.6.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# Software License Agreement (BSD License)
#
# Copyright (c) 2013, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function

import os
import re
import shutil
import string
import yaml

from tempfile import mkdtemp

from bloom.git import branch_exists
from bloom.git import create_branch
from bloom.git import has_changes
from bloom.git import get_remotes
from bloom.git import get_root
from bloom.git import inbranch
from bloom.git import show
from bloom.git import track_branches

from bloom.logging import error
from bloom.logging import fmt
from bloom.logging import info
from bloom.logging import sanitize

from bloom.util import execute_command
from bloom.util import my_copytree
from bloom.util import get_distro_list_prompt

BLOOM_CONFIG_BRANCH = 'master'
PLACEHOLDER_FILE = 'CONTENT_MOVED_TO_{0}_BRANCH'.format(BLOOM_CONFIG_BRANCH.upper())

config_spec = {
    'name': {
        '<name>': 'Name of the repository (used in the archive name)',
        'upstream': 'Default value, leave this as upstream if you are unsure'
    },
    'vcs_uri': {
        '<uri>': '''\
Any valid URI. This variable can be templated, for example an svn url
can be templated as such: "https://svn.foo.com/foo/tags/foo-:{version}"
where the :{version} token will be replaced with the version for this release.\
'''
    },
    'vcs_type': {
        'git': 'Upstream URI is a git repository',
        'hg': 'Upstream URI is a hg repository',
        'svn': 'Upstream URI is a svn repository',
        'tar': 'Upstream URI is a tarball'
    },
    'version': {
        ':{auto}': '''\
This means the version will be guessed from the devel branch.
This means that the devel branch must be set, the devel branch must exist,
and there must be a valid package.xml in the upstream devel branch.''',
        ':{ask}': '''\
This means that the user will be prompted for the version each release.
This also means that the upstream devel will be ignored.''',
        '<version>': '''\
This will be the version used.
It must be updated for each new upstream version.'''
    },
    'release_tag': {
        ':{version}': '''\
This means that the release tag will match the :{version} tag.
This can be further templated, for example: "foo-:{version}" or "v:{version}"

This can describe any vcs reference. For git that means {tag, branch, hash},
for hg that means {tag, branch, hash}, for svn that means a revision number.
For tar this value doubles as the sub directory (if the repository is
in foo/ of the tar ball, putting foo here will cause the contents of
foo/ to be imported to upstream instead of foo itself).
''',
        ':{ask}': '''\
This means the user will be prompted for the release tag on each release.
''',
        ':{none}': '''\
For svn and tar only you can set the release tag to :{none}, so that
it is ignored.  For svn this means no revision number is used.
'''
    },
    'devel_branch': {
        '<vcs reference>': '''\
Branch in upstream repository on which to search for the version.
This is used only when version is set to ':{auto}'.
''',
    },
    'ros_distro': {
        '<ROS distro>': "This can be any valid ROS distro, e.g. %s" %
                        get_distro_list_prompt()
    },
    'patches': {
        '<path in bloom branch>': '''\
This can be any valid relative path in the bloom branch. The contents
of this folder will be overlaid onto the upstream branch after each
import-upstream.  Additionally, any package.xml files found in the
overlay will have the :{version} string replaced with the current
version being released.''',
        ':{none}': '''\
Use this if you want to disable overlaying of files.'''
    },
    'release_repo_url': {
        '<url>': '''\
(optional) Used when pushing to remote release repositories. This is only
needed when the release uri which is in the rosdistro file is not writable.
This is useful, for example, when a releaser would like to use a ssh url
to push rather than a https:// url.
''',
        ':{none}': '''\
This indicates that the default release url should be used.
'''
    }
}


class PromptEntry(object):
    def __init__(self, name, default=None, values=None, prompt='', spec=None):
        self.values = values
        self.name = name
        self.default = default
        self.prompt = prompt
        self.spec = spec

    def __setattr__(self, key, value):
        if key == 'default' and self.values:
            if value not in self.values:
                error(
                    "Invalid input '{0}' for '{1}', acceptable values: {2}."
                    .format(value, self.name, self.values),
                    exit=True
                )
        object.__setattr__(self, key, value)

    def __str__(self):
        msg = fmt('@_' + sanitize(self.name) + ':@|')
        if self.spec is not None:
            for key, val in self.spec.items():
                msg += '\n  ' + key
                for line in val.splitlines():
                    msg += '\n    ' + line
        else:
            msg += '\n  ' + self.prompt
        msg += '\n '
        if self.default is None:
            msg += fmt(" @![@{yf}None@|@!]@|: ")
        else:
            msg += fmt(" @!['@{yf}" + sanitize(self.default) + "@|@!']@|: ")
        return msg

DEFAULT_TEMPLATE = {
    'name': PromptEntry('Repository Name', spec=config_spec['name'], default='upstream'),
    'vcs_uri': PromptEntry('Upstream Repository URI', spec=config_spec['vcs_uri']),
    'vcs_type': PromptEntry(
        'Upstream VCS Type', default='git', spec=config_spec['vcs_type'],
        values=['git', 'hg', 'svn', 'tar']),
    'version': PromptEntry('Version', default=':{auto}', spec=config_spec['version']),
    'release_tag': PromptEntry('Release Tag', default=':{version}', spec=config_spec['release_tag']),
    'devel_branch': PromptEntry('Upstream Devel Branch', spec=config_spec['devel_branch']),
    'patches': PromptEntry('Patches Directory', spec=config_spec['patches']),
    'ros_distro': PromptEntry('ROS Distro', default='indigo', spec=config_spec['ros_distro']),
    'release_repo_url': PromptEntry('Release Repository Push URL', spec=config_spec['release_repo_url']),
    'release_inc': -1,
    'actions': [
        'bloom-export-upstream :{vcs_local_uri} :{vcs_type}'
        ' --tag :{release_tag} --display-uri :{vcs_uri}'
        ' --name :{name} --output-dir :{archive_dir_path}',
        'git-bloom-import-upstream :{archive_path} :{patches}'
        ' --release-version :{version} --replace',
        'git-bloom-generate -y rosrelease :{ros_distro}'
        ' --source upstream -i :{release_inc}',
        'git-bloom-generate -y rosdebian --prefix release/:{ros_distro}'
        ' :{ros_distro} -i :{release_inc} --os-name ubuntu',
        'git-bloom-generate -y rosdebian --prefix release/:{ros_distro}'
        ' :{ros_distro} -i :{release_inc} --os-name debian --os-not-required',
        'git-bloom-generate -y rosrpm --prefix release/:{ros_distro}'
        ' :{ros_distro} -i :{release_inc}'
    ]
}

CUSTOM_TEMPLATE = {
    'reference': ':{ask}',
    'patches': ':{name}'
}

config_template = {
    'third-party': CUSTOM_TEMPLATE,
    None: {}
}


def verify_track(track_name, track):
    upconvert_bloom_to_config_branch()
    for entry in DEFAULT_TEMPLATE:
        if entry not in track:
            error("Track '{0}' is missing configuration ".format(track_name) +
                  "'{0}', it may be out of date, please run 'git-bloom-config edit {1}'."
                  .format(entry, track_name), exit=True)


class ConfigTemplate(string.Template):
    delimiter = ':'


def template_str(line, settings):
    t = ConfigTemplate(line)
    return t.substitute(settings)


def write_tracks_dict_raw(tracks_dict, cmt_msg=None, directory=None):
    upconvert_bloom_to_config_branch()
    cmt_msg = cmt_msg if cmt_msg is not None else 'Modified tracks.yaml'
    with inbranch(BLOOM_CONFIG_BRANCH):
        with open('tracks.yaml', 'w') as f:
            f.write(yaml.safe_dump(tracks_dict, indent=2, default_flow_style=False))
        execute_command('git add tracks.yaml', cwd=directory)
        execute_command('git commit --allow-empty -m "{0}"'.format(cmt_msg),
                        cwd=directory)

version_regex = re.compile(r'^\d+\.\d+\.\d+$')


def validate_track_versions(tracks_dict):
    for track in tracks_dict['tracks'].values():
        if 'version' in track:
            if track['version'] in [':{ask}', ':{auto}']:
                continue
            if version_regex.match(track['version']) is None:
                raise ValueError(
                    "Invalid version '{0}', it must be formatted as 'MAJOR.MINOR.PATCH'"
                    .format(track['version']))


def get_tracks_dict_raw(directory=None):
    upconvert_bloom_to_config_branch()
    if not branch_exists(BLOOM_CONFIG_BRANCH):
        info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
        create_branch(BLOOM_CONFIG_BRANCH, orphaned=True, directory=directory)
    tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw(
            {'tracks': {}}, 'Initial tracks.yaml', directory=directory
        )
        tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml',
                           directory=directory)
    tracks_dict = yaml.load(tracks_yaml)
    validate_track_versions(tracks_dict)
    return tracks_dict

_has_checked_bloom_branch = False


def check_for_multiple_remotes():
    if get_root() is None:
        return
    remotes = get_remotes()
    if len(remotes) < 0:
        error("Current git repository has no remotes. "
              "If you are running bloom-release, please change directories.",
              exit=True)
    if len(remotes) > 1:
        error("Current git repository has multiple remotes. "
              "If you are running bloom-release, please change directories.",
              exit=True)


def upconvert_bloom_to_config_branch():
    global _has_checked_bloom_branch
    if _has_checked_bloom_branch:
        return
    # Assert that this repository does not have multiple remotes
    check_for_multiple_remotes()
    if get_root() is None:
        # Not a git repository
        return
    track_branches(['bloom', BLOOM_CONFIG_BRANCH])
    if show('bloom', PLACEHOLDER_FILE) is not None:
        return
    if show('bloom', 'bloom.conf') is not None:
        # Wait for the bloom.conf upconvert...
        return
    if not branch_exists('bloom'):
        return
    _has_checked_bloom_branch = True
    info("Moving configurations from deprecated 'bloom' branch "
         "to the '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
    tmp_dir = mkdtemp()
    git_root = get_root()
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch('bloom'):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            configs = os.path.join(tmp_dir, 'configs')
            my_copytree(git_root, configs, ignores)
            if [x for x in os.listdir(os.getcwd()) if x not in ignores]:
                execute_command('git rm -rf ./*')
            with open(PLACEHOLDER_FILE, 'w') as f:
                f.write("""\
This branch ('bloom') has been deprecated in favor of storing settings and overlay files in the master branch.

Please goto the master branch for anything which referenced the bloom branch.

You can delete this branch at your convenience.
""")
            execute_command('git add ' + PLACEHOLDER_FILE)
            if has_changes():
                execute_command('git commit -m "DEPRECATING BRANCH"')
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
            create_branch(BLOOM_CONFIG_BRANCH, orphaned=True)
        with inbranch(BLOOM_CONFIG_BRANCH):
            my_copytree(configs, git_root)
            execute_command('git add ./*')
            if has_changes():
                execute_command('git commit -m '
                                '"Moving configs from bloom branch"')
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)