This file is indexed.

/usr/share/doc/python-cement-doc/html/_sources/examples/bash_auto_completion.txt is in python-cement-doc 2.10.0-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
BASH Auto Completion
--------------------

Auto Completion, or "TAB Completion" is a very common and familiar feature in
BASH (and other modern shells).  It is possible to auto-complete Cement apps
(using BASH for this example) including sub-levels for nested controllers.
The difficulty is that this auto-completion code must be maintained outside of
Cement and your application code, and be implemented in the shell environment
generally by use of an "RC" file, or similar means.  This then must be updated
anytime your application is modified (or atleast any time the
sub-commands/controllers/arguments are modified).

Note that, in the future, we would love to include some form of
"BASH RC Generator" that will do this for you, however in the meantime the
following is a working example that can be used as a model for adding BASH
auto-completion to your app.

Update: As of Cement 2.7.x, the 
:ref:`Argcomplete Framework Extension<cement.ext.ext_argcomplete>` can be 
used as an alternative to this example.  Both are viable options though
this route is much more manual, and the Argcomplete route might not fit your 
needs.

Example Cement App
^^^^^^^^^^^^^^^^^^

The following application code implements three levels of namespaces, or
sub-commands, that are implemented via nested-controllers.

.. code-block:: python

    from cement.core.foundation import CementApp
    from cement.core.controller import CementBaseController, expose

    class BaseController(CementBaseController):
        class Meta:
            label = 'base'

        @expose()
        def base_cmd1(self):
            print("Inside BaseController.base_cmd1()")

    class EmbeddedController(CementBaseController):
        class Meta:
            label = 'embedded'
            description = "embedded with base namespace"
            stacked_on = 'base'
            stacked_type = 'embedded'

        @expose()
        def base_cmd2(self):
            print("Inside EmbeddedController.base_cmd2()")

        @expose()
        def embedded_cmd3(self):
            print("Inside EmbeddedController.embedded_cmd3()")

    class SecondLevelController(CementBaseController):
        class Meta:
            label = 'second'
            description = ''
            stacked_on = 'base'
            stacked_type = 'nested'

        @expose()
        def second_cmd4(self):
            print("Inside SecondLevelController.second_cmd4()")

        @expose()
        def second_cmd5(self):
            print("Inside SecondLevelController.second_cmd5()")

    class ThirdLevelController(CementBaseController):
        class Meta:
            label = 'third'
            description = ''
            stacked_on = 'second'
            stacked_type = 'nested'

        @expose()
        def third_cmd6(self):
            print("Inside ThirdLevelController.third_cmd6()")

        @expose()
        def third_cmd7(self):
            print("Inside ThirdLevelController.third_cmd7()")


    class MyApp(CementApp):
        class Meta:
            label = 'myapp'
            handlers = [
                BaseController,
                EmbeddedController,
                SecondLevelController,
                ThirdLevelController,
                ]


    def main():
        with MyApp() as app:
            app.run()

    if __name__ == '__main__':
        main()

This looks like:

.. code-block:: bash

    $ python myapp.py --help
    usage: myapp.py (sub-commands ...) [options ...] {arguments ...}

    Base Controller

    commands:

      base-cmd1

      base-cmd2

      embedded-cmd3

      second


    $ python myapp.py second --help

    commands:

      second-cmd4

      second-cmd5

      third


    $ python myapp.py second third --help

    commands:

      third-cmd6

      third-cmd7



For demonstration purposes, we are going to create a BASH alias here so that
we can call our `myapp` command name as if we would in production (not
development):

.. code-block:: bash

    $ alias myapp="python ./myapp.py"


In the "real world" your actual `myapp` command would be setup/installed by
something like this in `setup.py`:

.. code-block:: python

    entry_points="""
        [console_scripts]
        myapp = myapp.cli.main:main
        """,


Or by simply copying `myapp.py` to `/usr/bin/myapp`, or similar.

Example BASH RC
^^^^^^^^^^^^^^^

The following is a BASH RC script that will setup auto-completiong for the
above Cement App `myapp`.  You **will** need to modify this, it is just an
example and is not intended to be copy and pasted:

.. code-block:: bash

    alias myapp="python ./myapp.py"

    _myapp_complete()
    {
        local cur prev BASE_LEVEL

        COMPREPLY=()
        cur=${COMP_WORDS[COMP_CWORD]}
        prev=${COMP_WORDS[COMP_CWORD-1]}

        # SETUP THE BASE LEVEL (everything after "myapp")
        if [ $COMP_CWORD -eq 1 ]; then
            COMPREPLY=( $(compgen \
                          -W "base-cmd1 base-cmd2 embedded-cmd3 second" \
                          -- $cur) )


        # SETUP THE SECOND LEVEL (EVERYTHING AFTER "myapp second")
        elif [ $COMP_CWORD -eq 2 ]; then
            case "$prev" in

                # HANDLE EVERYTHING AFTER THE SECOND LEVEL NAMESPACE
                "second")
                    COMPREPLY=( $(compgen \
                                  -W "second-cmd4 second-cmd5 third" \
                                  -- $cur) )
                    ;;

                # IF YOU HAD ANOTHER CONTROLLER, YOU'D HANDLE THAT HERE
                "some-other-controller")
                    COMPREPLY=( $(compgen \
                                  -W "some-other-sub-command" \
                                  -- $cur) )
                    ;;

                # EVERYTHING ELSE
                *)
                    ;;
            esac

        # SETUP THE THIRD LEVEL (EVERYTHING AFTER "myapp second third")
        elif [ $COMP_CWORD -eq 3 ]; then
            case "$prev" in
                # HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
                "third")
                    COMPREPLY=( $(compgen \
                                  -W "third-cmd6 third-cmd7" \
                                  -- $cur) )
                    ;;

                # IF YOU HAD ANOTHER CONTROLLER, YOU'D HANDLE THAT HERE
                "some-other-controller")
                    COMPREPLY=( $(compgen \
                                  -W "some-other-sub-command" \
                                  -- $cur) )
                    ;;

                *)
                    ;;
            esac
        fi

        return 0

    } &&
    complete -F _myapp_complete myapp



You would then "source" the RC file:

.. code-block:: bash

    $ source myapp.rc


In the "real world" you would probably put this in a system wide location
such at ``/etc/profile.d`` or similar (in a production deployment).

Finally, this is what it looks like:

.. code-block:: bash

    # show all sub-commands at the base level
    $ myapp [tab] [tab]
    base-cmd1      base-cmd2      embedded-cmd3      second

    # auto-complete a partial matching sub-command
    $ myapp base [tab]

    $ myapp base-cmd [tab] [tab]
    base-cmd1      base-cmd2

    # auto-complete a full matching sub-command
    $ myapp sec [tab]

    $ myapp second

    # show all sub-commands under the second namespace
    $ myapp second [tab] [tab]
    second-cmd4      second-cmd5      third

    # show all sub-commands under the third namespace
    $ myapp second third [tab] [tab]
    third-cmd6      third-cmd7