This file is indexed.

/usr/lib/python3/dist-packages/bashate/messages.py is in python3-bashate 0.5.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
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import re
import textwrap


class _Message(object):
    """An individual bashate message.

    This should be accessed via the MESSAGES dict keyed by msg_id,
    e.g.

      from bashate.messages import MESSAGES
      print(MESSAGES['E123'].msg)

    :param msg_id: The unique message id (E...)
    :param msg_str: The short message string, as displayed in program
                     output
    :param long_msg: A longer more involved message, designed for
                     documentation
    """
    def __init__(self, msg_id, msg_str, long_msg, default):
        self.msg_id = msg_id
        self.msg_str = msg_str
        # clean-up from """ to a plain string
        if long_msg:
            self.long_msg = textwrap.dedent(long_msg)
            self.long_msg = self.long_msg.strip()
        else:
            self.long_msg = None
        self.default = default

    @property
    def msg(self):
        # For historical reasons, the code relies on "id: msg" so build
        # that up as .msg property for quick access.
        return "%s: %s" % (self.msg_id, self.msg_str)


_messages = {
    'E001': {
        'msg': 'Trailing Whitespace',
        'long_msg': None,
        'default': 'E'
    },
    'E002': {
        'msg': 'Tab indents',
        'long_msg':
        """
        Spaces are preferred to tabs in source files.
        """,
        'default': 'E'
    },
    'E003': {
        'msg': 'Indent not multiple of 4',
        'long_msg':
        """
        Four spaces should be used to offset logical blocks.
        """,
        'default': 'E'
    },
    'E004': {
        'msg': 'File did not end with a newline',
        'long_msg':
        """
        It is conventional to have a single newline ending files.
        """,
        'default': 'E'
    },
    'E005': {
        'msg': 'File does not begin with #! or have .sh prefix',
        'long_msg':
        """
        This can be useful for tools that use either the interpreter
        directive or the file-exension to select highlighting mode,
        syntax mode or determine MIME-type, such as file, gerrit and
        editors.
        """,
        'default': 'W'
    },
    'E006': {
        'msg': 'Line too long',
        'long_msg':
        """
        This check mimics the widely accepted convention from PEP8 and
        many other places that lines longer than 79 columns can not
        only cause problems when reading/writing code, but also often
        indicates a bad smell, e.g. too many levels of indentation due
        to overly complex functions which require refactoring into
        smaller chunks.
        """,
        'default': 'W'
    },
    'E010': {
        'msg': 'The "do" should be on same line as %s',
        'long_msg':
        """
        Ensure consistency of "do" directive being on the same line as
        it's command.  For example:

           for i in $(seq 1 100);
           do
              echo "hi"
           done

        will trigger this error
        """,
        'default': 'E'
    },
    'E011': {
        'msg': 'Then keyword is not on same line as if or elif keyword',
        'long_msg':
        """
        Similar to E010, this ensures consistency of if/elif statements
        """,
        'default': 'E'
    },
    'E012': {
        'msg': 'here-document at line %d delimited by end-of-file',
        'long_msg':
        """
        This check ensures the closure of heredocs (<<EOF directives).
        Bash will warn when a heredoc is delimited by end-of-file, but
        it is easily missed and can cause unexpected issues when a
        file is sourced.
        """,
        'default': 'E'
    },
    'E020': {
        'msg': 'Function declaration not in format ^function name {$',
        'long_msg':
        """
        There are several equivalent ways to define functions in Bash.
        This check is for consistency.
        """,
        'default': 'E'
    },
    'E040': {
        'msg': 'Syntax error',
        'long_msg':
        """
        `bash -n` determined that there was a syntax error preventing
        the script from parsing correctly and running.
        """,
        'default': 'E'
    },
    'E041': {
        'msg': 'Arithmetic expansion using $[ is deprecated for $((',
        'long_msg':
        """
        $[ is deprecated and not explained in the Bash manual.  $((
        should be used for arithmetic.
        """,
        'default': 'E'
    },
    'E042': {
        'msg': 'local declaration hides errors',
        'long_msg':
        """
        The return value of "local" is always 0; errors in subshells
        used for declaration are thus hidden and will not trigger "set -e".
        """,
        'default': 'W',
    },
    'E043': {
        'msg': 'Arithmetic compound has inconsistent return semantics',
        'long_msg':
        """
        The return value of ((expr)) is 1 if "expr" evalues to zero,
        otherwise 0.  Combined with "set -e", this can be quite
        confusing when something like ((counter++)) evaluates to zero,
        making the arithmetic evaluation return 1 and triggering the
        an error failure.  It is therefore best to use assignment with
        the $(( operator.
        """,
        'default': 'W',
    },


}

MESSAGES = {}

_default_errors = []
_default_warnings = []

for k, v in _messages.items():
    MESSAGES[k] = _Message(k, v['msg'], v['long_msg'], v['default'])

    if v['default'] == 'E':
        _default_errors.append(k)
    if v['default'] == 'W':
        _default_warnings.append(k)

# convert this to the regex strings.  This looks a bit weird
# but it fits the current model of error/warning/ignore checking
# easily.
_default_errors = '^(' + '|'.join(_default_errors) + ')'
_default_warnings = '^(' + '|'.join(_default_warnings) + ')'


def is_default_error(error):
    return re.search(_default_errors, error)


def is_default_warning(error):
    return re.search(_default_warnings, error)


def print_messages():

    print("\nAvailable bashate checks")
    print("------------------------\n")
    for k, v in MESSAGES.items():
        print(" [%(default)s] %(id)s : %(string)s" % {
            'default': v.default,
            'id': v.msg_id,
            'string': v.msg_str})
        if v.long_msg:
            for l in v.long_msg.split('\n'):
                print("            %s" % l)
        print("")