tabtab 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +76 -0
  3. data/PostInstall.txt +10 -0
  4. data/README.rdoc +385 -0
  5. data/Rakefile +25 -0
  6. data/bin/install_tabtab +10 -0
  7. data/bin/tabtab +10 -0
  8. data/examples/tabtab.sh +7 -0
  9. data/features/aliases_for_completions.feature +23 -0
  10. data/features/development.feature +19 -0
  11. data/features/different_shells_installation.feature +26 -0
  12. data/features/discovered_gem_app_completions.feature +37 -0
  13. data/features/external_app_completions.feature +24 -0
  14. data/features/file_completions.feature +17 -0
  15. data/features/hide_short_flags.feature +19 -0
  16. data/features/steps/cli.rb +63 -0
  17. data/features/steps/common.rb +211 -0
  18. data/features/steps/completions.rb +15 -0
  19. data/features/steps/configuration.rb +20 -0
  20. data/features/steps/env.rb +17 -0
  21. data/features/steps/gems.rb +18 -0
  22. data/features/steps/shells.rb +3 -0
  23. data/lib/dev_definitions/gem.rb +54 -0
  24. data/lib/dev_definitions/rake.rb +23 -0
  25. data/lib/dev_definitions/script-generate.rb +8 -0
  26. data/lib/dev_definitions/script-server.rb +14 -0
  27. data/lib/install_tabtab/cli.rb +139 -0
  28. data/lib/tabtab.rb +10 -0
  29. data/lib/tabtab/cli.rb +116 -0
  30. data/lib/tabtab/completions.rb +6 -0
  31. data/lib/tabtab/completions/external.rb +39 -0
  32. data/lib/tabtab/completions/file.rb +23 -0
  33. data/lib/tabtab/completions/gems.rb +44 -0
  34. data/lib/tabtab/definitions.rb +28 -0
  35. data/lib/tabtab/definitions/base.rb +146 -0
  36. data/lib/tabtab/definitions/command.rb +47 -0
  37. data/lib/tabtab/definitions/default.rb +41 -0
  38. data/lib/tabtab/definitions/flag.rb +38 -0
  39. data/lib/tabtab/definitions/root.rb +70 -0
  40. data/lib/tabtab/framework_testing.rb +11 -0
  41. data/lib/tabtab/local_config.rb +16 -0
  42. data/lib/tabtab/test/assertions.rb +6 -0
  43. data/lib/tabtab_definitions/cucumber.rb +19 -0
  44. data/lib/tabtab_definitions/github.rb +50 -0
  45. data/lib/tabtab_definitions/newgem.rb +27 -0
  46. data/lib/tabtab_definitions/rails.rb +15 -0
  47. data/lib/tabtab_definitions/rubyforge.rb +17 -0
  48. data/script/console +10 -0
  49. data/script/destroy +14 -0
  50. data/script/generate +14 -0
  51. data/spec/definition_spec.rb +334 -0
  52. data/spec/external_spec.rb +38 -0
  53. data/spec/fixtures/bin/test_app +11 -0
  54. data/spec/fixtures/gems/multi_app/History.txt +2 -0
  55. data/spec/fixtures/gems/multi_app/Manifest.txt +7 -0
  56. data/spec/fixtures/gems/multi_app/Rakefile +25 -0
  57. data/spec/fixtures/gems/multi_app/bin/test_app +11 -0
  58. data/spec/fixtures/gems/multi_app/lib/multi_app.rb +6 -0
  59. data/spec/fixtures/gems/multi_app/lib/tabtab_definitions/some_app.rb +5 -0
  60. data/spec/fixtures/gems/multi_app/multi_app-0.0.1.gem +0 -0
  61. data/spec/fixtures/gems/multi_app/multi_app.gemspec +38 -0
  62. data/spec/fixtures/gems/my_app/History.txt +2 -0
  63. data/spec/fixtures/gems/my_app/Manifest.txt +7 -0
  64. data/spec/fixtures/gems/my_app/Rakefile +25 -0
  65. data/spec/fixtures/gems/my_app/bin/test_app +11 -0
  66. data/spec/fixtures/gems/my_app/lib/my_app.rb +6 -0
  67. data/spec/fixtures/gems/my_app/lib/tabtab_definitions.rb +5 -0
  68. data/spec/fixtures/gems/my_app/my_app-0.0.1.gem +0 -0
  69. data/spec/fixtures/gems/my_app/my_app.gemspec +38 -0
  70. data/spec/framework_testing_spec.rb +55 -0
  71. data/spec/install_tabtab_cli_spec.rb +139 -0
  72. data/spec/spec.opts +1 -0
  73. data/spec/spec_helper.rb +14 -0
  74. data/spec/tabtab_cli_spec.rb +145 -0
  75. data/tasks/rspec.rake +21 -0
  76. data/website/images/tabtab.png +0 -0
  77. metadata +167 -0
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-11-12
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,76 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/install_tabtab
7
+ bin/tabtab
8
+ examples/tabtab.sh
9
+ features/aliases_for_completions.feature
10
+ features/development.feature
11
+ features/different_shells_installation.feature
12
+ features/discovered_gem_app_completions.feature
13
+ features/external_app_completions.feature
14
+ features/file_completions.feature
15
+ features/hide_short_flags.feature
16
+ features/steps/cli.rb
17
+ features/steps/common.rb
18
+ features/steps/completions.rb
19
+ features/steps/configuration.rb
20
+ features/steps/env.rb
21
+ features/steps/gems.rb
22
+ features/steps/shells.rb
23
+ lib/dev_definitions/gem.rb
24
+ lib/dev_definitions/rake.rb
25
+ lib/dev_definitions/script-generate.rb
26
+ lib/dev_definitions/script-server.rb
27
+ lib/install_tabtab/cli.rb
28
+ lib/tabtab.rb
29
+ lib/tabtab/cli.rb
30
+ lib/tabtab/completions.rb
31
+ lib/tabtab/completions/external.rb
32
+ lib/tabtab/completions/file.rb
33
+ lib/tabtab/completions/gems.rb
34
+ lib/tabtab/definitions.rb
35
+ lib/tabtab/definitions/base.rb
36
+ lib/tabtab/definitions/command.rb
37
+ lib/tabtab/definitions/default.rb
38
+ lib/tabtab/definitions/flag.rb
39
+ lib/tabtab/definitions/root.rb
40
+ lib/tabtab/framework_testing.rb
41
+ lib/tabtab/local_config.rb
42
+ lib/tabtab/test/assertions.rb
43
+ lib/tabtab_definitions/cucumber.rb
44
+ lib/tabtab_definitions/github.rb
45
+ lib/tabtab_definitions/newgem.rb
46
+ lib/tabtab_definitions/rails.rb
47
+ lib/tabtab_definitions/rubyforge.rb
48
+ script/console
49
+ script/destroy
50
+ script/generate
51
+ spec/definition_spec.rb
52
+ spec/external_spec.rb
53
+ spec/fixtures/bin/test_app
54
+ spec/fixtures/gems/multi_app/History.txt
55
+ spec/fixtures/gems/multi_app/Manifest.txt
56
+ spec/fixtures/gems/multi_app/Rakefile
57
+ spec/fixtures/gems/multi_app/bin/test_app
58
+ spec/fixtures/gems/multi_app/lib/multi_app.rb
59
+ spec/fixtures/gems/multi_app/lib/tabtab_definitions/some_app.rb
60
+ spec/fixtures/gems/multi_app/multi_app-0.0.1.gem
61
+ spec/fixtures/gems/multi_app/multi_app.gemspec
62
+ spec/fixtures/gems/my_app/History.txt
63
+ spec/fixtures/gems/my_app/Manifest.txt
64
+ spec/fixtures/gems/my_app/Rakefile
65
+ spec/fixtures/gems/my_app/bin/test_app
66
+ spec/fixtures/gems/my_app/lib/my_app.rb
67
+ spec/fixtures/gems/my_app/lib/tabtab_definitions.rb
68
+ spec/fixtures/gems/my_app/my_app-0.0.1.gem
69
+ spec/fixtures/gems/my_app/my_app.gemspec
70
+ spec/framework_testing_spec.rb
71
+ spec/install_tabtab_cli_spec.rb
72
+ spec/spec.opts
73
+ spec/spec_helper.rb
74
+ spec/tabtab_cli_spec.rb
75
+ tasks/rspec.rake
76
+ website/images/tabtab.png
@@ -0,0 +1,10 @@
1
+
2
+ NOTE: tabtab is currently only operational with the bash shell (see README.rdoc)
3
+
4
+ To install all included auto-completions and get the sexiness instantly:
5
+
6
+ * Run 'install_tabtab'
7
+ * Add 'source ~/.tabtab.bash' to your .bash_profile
8
+ * Open a new terminal AND/OR Run 'source ~/.tabtab.bash' in your terminal
9
+
10
+ To try it out, type 'gem ' and press TAB twice. That is, TabTab. Enjoy.
@@ -0,0 +1,385 @@
1
+ = tabtab
2
+
3
+ * http://tabtab.rubyforge.org
4
+
5
+ == DESCRIPTION:
6
+
7
+ Create and install double-tab ('tab tab') auto-completions for any
8
+ command-line application on any shell (bash, fish, ksh, etc).
9
+
10
+ When you use the command-line, you can double-tab to auto-complete the name
11
+ of a command-line application or a target file or folder. Its possible to
12
+ provide your own completions for applications: git comes with bash shell completions,
13
+ and the fish shell includes a library of completions for many applications.
14
+
15
+ == QUICK START/TRIAL ME:
16
+
17
+ The tabtab gem comes with some pre-defined completions for some popular applications
18
+ that benefit from completions: rails, newgem, cucumber, github (and its alias gh).
19
+ It takes 2 minutes to trial this project and see if you like it:
20
+
21
+ bash>
22
+ sudo gem install tabtab
23
+ install_tabtab
24
+ source ~/.tabtab.bash
25
+
26
+ rails -d TABTAB
27
+
28
+ cd project/hosted/on/github/with/contributors/like/rails/or/rspec
29
+ github TABTAB
30
+ gh netTAB feTAB
31
+ gh netTAB web TABTAB
32
+
33
+ It just works.
34
+
35
+ Now, add 'source ~/.tabtab.bash' to your .bash_profile so you have this awesomeness in all your
36
+ terminal shells.
37
+
38
+ Read on to learn how to write your own auto-completions with only a few lines of Ruby...
39
+
40
+ == FEATURES/PROBLEMS:
41
+
42
+ * Completion defintions/recipes are shell agnostic (bash, fish, ksh, etc)
43
+ * Definitions are written in Ruby
44
+ * Can be bundled within RubyGems, explicitly referenced in local files, or
45
+ automatically generated from -h help output from existing applications.
46
+ * Very easy to use: 'install_tabtab' to find available completions, then 'source ~/.tabtab.bash'
47
+
48
+ == SAMPLE DEFINITION:
49
+
50
+ TabTab definitions for auto-completions are very easy to write. Initially
51
+ you can store them in a normal Ruby file (say ~/.tabtab/myapp.rb) and
52
+ later, if the application is a Ruby application and distributed as a RubyGem
53
+ you can bundle it with the distribution.
54
+
55
+ === Flags
56
+
57
+ A sample TabTab definition for the script/server command that is found
58
+ within all Ruby on Rails applications:
59
+
60
+ TabTab::Definition.register('script/server') do |c|
61
+ c.flag :debugger, :d
62
+
63
+ c.flag :environment, :e do
64
+ Dir['config/environments/*.rb'].map { |env| env.gsub(/^.*environments\//,'').gsub(/.rb$/,'') }
65
+ end
66
+
67
+ # script/server -p TABTAB -> generated first available port 3000, 3001, 3002
68
+ c.flag :port, :p do
69
+ port = 3000
70
+ until `netstat -an | grep "^tcp" | grep #{port}`.strip.empty? || port > 3010
71
+ port += 1
72
+ end
73
+ port > 3010 ? [] : [port.to_s]
74
+ end
75
+ end
76
+
77
+ This definition defines 3 flags (each with short and long names): --debugger, --environment, and --port.
78
+ The --debugger flag is a simple autocompletion. At the command-line, if you typed "script/server --d" and
79
+ pressed double-tab it would instantly complete to "script/server --debugger ".
80
+
81
+ The other two flags can take values (e.g. "--environment development" or "--port 3000") and their
82
+ definitions are more powerful. If you double-tab after "script/server --environment " you will be
83
+ presented with options [development, test, production] for completion. If you type the first
84
+ letter, it will complete to the full value.
85
+
86
+ Similarly for "--port". The algorithm above will find the first available port number from 3000+.
87
+ As it only returns a single value in its result array, this value is automatically displayed
88
+ on the command line. Very tricky indeed.
89
+
90
+ The #flag method (and its alias #flags) takes 1+ symbols describing the flag names. Its last
91
+ argument can be a string as a description. This is not used for bash shell users, but is
92
+ available to ksh/fish users who's autocompletion systems are capable of displaying them
93
+ inline with the completion options.
94
+
95
+ The #flag method can also take a block. The result of the block must be an array of strings.
96
+ These blocks (also available to #command and #default methods below) are called 'value blocks'.
97
+ They return the complete, or a useful subset, of available values for the flag or command.
98
+
99
+ === Commands
100
+
101
+ Many command-line apps take a command as their first argument. For example, the github CLI
102
+ has commands such as: info, pull, and network. The latter even has sub-commands.
103
+ Subsequently, you might run the following at the command line:
104
+
105
+ github info
106
+ github pull drnic
107
+ github network commits
108
+ github network web drnic
109
+
110
+ The following sample of the tabtab definition for the github command
111
+ shows how tabtab can provide autocompletions for every example above,
112
+ including the user values for the 'github pull' and 'github network web' commands.
113
+
114
+ TabTab::Definition.register('github') do |c|
115
+ def users
116
+ `github info | grep "^ -" | sed -e "s/ - //" | sed -e "s/ .*$//"`.split("\n")
117
+ end
118
+
119
+ c.command :info, "Show info"
120
+
121
+ c.command :pull, "Pull from a remote." do |pull|
122
+ pull.default { users }
123
+ pull.flag :merge
124
+ end
125
+
126
+ c.command :network, "Project network tools" do |network|
127
+ network.command(:web) { users }
128
+ network.command :commits
129
+ end
130
+ end
131
+
132
+ The #command method requires a symbol for the name, and can take a string for the
133
+ command description (see Flags section above).
134
+
135
+ The #command method can also take a value block, like #flag above. It must return
136
+ an array of strings.
137
+
138
+ The above example shows the behaviour of the 'github network web' command being abstracted
139
+ into a separate method. Similarly, this method could be defined in an external Module,
140
+ and included as necessary.
141
+
142
+ Note that 'pull.flag :merge' defines that 'github pull' can complete to 'github pull --merge'
143
+ as well as the list of values returned from the #default value block.
144
+
145
+ === Default value blocks
146
+
147
+ In the sample github definition above, the 'c.command :pull' value block is not
148
+ the immediate block passed to the #command method. Instead the value block is
149
+ defined via 'pull.default { }' This is an alternate syntax to the earlier value block,
150
+ and is used where your command can autocomplete to various flags, sub-commands or other
151
+ from within a generated list of values (via the #default value block).
152
+
153
+ === Value block syntax
154
+
155
+ Value blocks are normal Ruby blocks that return an array of Strings.
156
+
157
+ The following syntax options for the 'run' command are functionally equivalent:
158
+
159
+ TabTab::Definition.register('myapp') do |c|
160
+ c.command :run do
161
+ %w[things to run]
162
+ end
163
+
164
+ c.command :run, "A description" do
165
+ %w[things to run]
166
+ end
167
+
168
+ c.command :run do |run|
169
+ run.default do
170
+ %w[things to run]
171
+ end
172
+ end
173
+
174
+ c.command(:run, "A description") { %w[things to run] }
175
+
176
+ def things_to_run
177
+ $[things to run]
178
+ end
179
+ c.command(:run) { things_to_run }
180
+ end
181
+
182
+ === Application name aliases
183
+
184
+ I don't ever type 'script/generate', rather I have an alias 'gen' for it.
185
+
186
+ TabTab supports user-defined aliases (you might have an alias 'g' for 'script/generate') via its
187
+ ~/.tabtab.yml configuration file. See Aliases section below.
188
+
189
+ == INSTALL:
190
+
191
+ * sudo gem install tabtab
192
+
193
+ == SETUP:
194
+
195
+ Run `install_tabtab` to install the completions that come built-in with the
196
+ tabtab RubyGem, and within any other RubyGem, at the time of execution.
197
+
198
+ In your .bash_profile add:
199
+
200
+ source ~/.tabtab.bash
201
+
202
+ === Future shells:
203
+
204
+ In your .fish_profile add:
205
+
206
+ source ~/.tabtab.fish
207
+
208
+ In your .ksh_profile add:
209
+
210
+ source ~/.tabtab.ksh
211
+
212
+ === Re-running install_tabtab
213
+
214
+ You never need to run this command again after new RubyGem updates, but
215
+ you do need to re-run this command each time you:
216
+
217
+ * install a RubyGem that contains a tabtab_definitions.rb file for the first time
218
+ (once install_tabtab has discovered the gem it will automatically pick up
219
+ changes to the definitions in future gem versions)
220
+ * want to add completions defined in a local file, rather than bundled in a gem (see Local Files below)
221
+ * want to add completions for 'external' apps (see External below)
222
+
223
+ Each time you run install_tabtab the above ~/.tabtab.sh file(s) will be updated. You then need to restart
224
+ your shell(s) to load the new completions, or run the above command explicitly.
225
+
226
+ === RubyGems: Completion Definitions in RubyGems
227
+
228
+ By default, install_tabtab automatically finds any completion definitions bundled in RubyGems.
229
+ The tabtab gem itself includes lots of definitions for applications such as rails, script/server,
230
+ rake, gem, cucumber, github, and others.
231
+
232
+ In time, the development and deployment of each
233
+ script may be adopted by the relevant project owners and bundled in their RubyGems rather than
234
+ the tabtab gem itself.
235
+
236
+ You can bundle tabtab defintions for 1 or more applications in your own RubyGems. Typically,
237
+ you will include tabtab defintions for the applications that you bundle with your gem. For example,
238
+ the global 'rails' app and the per-rails project 'script/server' applications are bundled in the
239
+ 'railties' gem. Rails would ideally include its tabtab definitions in this railties gem and
240
+ the core Rails team would maintain/update the tabtab definition whenever the actual
241
+ applications are updated. This way the application and the tabtab defintions will be consistent.
242
+
243
+ To include tabtab definitions in a RubyGem, you need to add a 'tabtab_definitions.rb' file
244
+ somewhere in your gem. The suggested location is 'lib/tabtab_definitions.rb'.
245
+
246
+ === Local Files: Completion Definitions in Local Files
247
+
248
+ You can create and develop your own tabtab definitions for your apps or other people's apps.
249
+ Its really simple. Really easy.
250
+
251
+ 1. Create a file
252
+ 2. Include the definition code:
253
+
254
+ TabTab::Definition.register('TARGET_APP_NAME') do |c| ... end
255
+
256
+ 3. Create a ~/.tabtab.yml file
257
+ 4. Add file configuration:
258
+
259
+ files:
260
+ "/Users/drnic/.tabtab_definitions/TARGET_APP_NAME.rb": TARGET_APP_NAME
261
+
262
+ You can include multiple definitions in a single file (using multiple 'register(app_name)' calls)
263
+ and including a list of file names:
264
+
265
+ files:
266
+ "/Users/drnic/.tabtab_definitions/my_definitions.rb": curl, mongrel_rails
267
+
268
+ You can include multiple files for multiple applications:
269
+
270
+ files:
271
+ "/Users/drnic/.tabtab_definitions/curl.rb": curl
272
+ "/Users/drnic/.tabtab_definitions/mongrel.rb": mongrel_rails
273
+
274
+ === External: Completions for Applications without Definitions
275
+
276
+ As a bonus feature, tabtab supports autocompletions for existing applications
277
+ without requiring a definition file. Neat! For example, the 'curl' command has lots of flag options.
278
+ For shits-and-giggles, run 'curl -h'. There are currently 56 different flag options. Fifty six!
279
+
280
+ It would be so sweet to instantly get an autocompletion for these flags without any
281
+ coding effort; no definition file.
282
+
283
+ It is as simple as adding an "external" key to your ~/.tabtab.yml config file:
284
+
285
+ external:
286
+ - curl
287
+ - cap
288
+
289
+ === Hide small flags
290
+
291
+ Many applications have command-line flag arguments, such as --port (long) or -p (short).
292
+ The short form is useful if you are typing them yourself - they are two characters long.
293
+ If you are using auto-completions, it may not be meaningful nor useful to see the
294
+ short form flags.
295
+
296
+ You can disable short-form versions of flags via the ~/.tabtab.yml config file. Add the following line:
297
+
298
+ shortflags: disable
299
+
300
+ === Aliases: Reusing Completions against local Aliases
301
+
302
+ TabTab supports user-defined aliases (you might have an alias 'g' for 'script/generate') via its
303
+ ~/.tabtab.yml configuration file.
304
+
305
+ Use the "aliases" key to your ~/.tabtab.yml config file:
306
+
307
+ aliases:
308
+ gen: script/generate
309
+ console: script/console
310
+ ss: script/server
311
+ server: script/server
312
+
313
+ == SHELL SUPPORT:
314
+
315
+ TabTab is shell agnostic. If your shell supports auto-completions, then it should be possible
316
+ to hook in the TabTab definitions.
317
+
318
+ Yet it initially only supports Bash. Why? I know how to hook bash's completion mechanism
319
+ into an external app.
320
+
321
+ For bash's complete command, the -C option allows me to specify an external command that will
322
+ handle the request for completion options. Below, 'tabtab' is the external completion command and it will
323
+ be used for the github command.
324
+
325
+ complete -o default -C tabtab github
326
+
327
+ For bash, when tabtab is executed, its last 3 arguments are: command name, current token, previous token.
328
+ It also passes the entire current command line via $COMP_LINE.
329
+
330
+ I know that fish and ksh and other shells have sexy completion support. But I cannot figure out how
331
+ to configure them to delegate to tabtab.
332
+
333
+ Fish's complete only seems to allow calls to fish functions, and not external apps. But perhaps
334
+ the fish function can then delegate to tabtab? Perhaps I just need a _tabtab fish function, which
335
+ proxies the request through to the tabtab command?
336
+
337
+ If you know these things, or are proficient enough in your preferred shell to poke around and help out
338
+ please let me know. I have some cucumber scenarios ready and waiting for your help.
339
+
340
+
341
+ == REQUIREMENTS:
342
+
343
+ Currently, tabtab works with the bash shell, though it is designed to be
344
+ shell agnostic.
345
+
346
+ == SOURCE:
347
+
348
+ The source for this project is at http://github.com/drnic/tabtab
349
+
350
+ Using git, you can clone the project, run its tests and install it:
351
+
352
+ git clone git://github.com/drnic/tabtab.git
353
+ cd tabtab
354
+ rake
355
+ rake install_gem
356
+
357
+ == SPONSOR
358
+
359
+ * Mocra - the premier iPhone/Rails consultancy
360
+ * http://mocra.com
361
+
362
+ == LICENSE:
363
+
364
+ (The MIT License)
365
+
366
+ Copyright (c) 2008 Dr Nic Williams (http://drnicwilliams.com)
367
+
368
+ Permission is hereby granted, free of charge, to any person obtaining
369
+ a copy of this software and associated documentation files (the
370
+ 'Software'), to deal in the Software without restriction, including
371
+ without limitation the rights to use, copy, modify, merge, publish,
372
+ distribute, sublicense, and/or sell copies of the Software, and to
373
+ permit persons to whom the Software is furnished to do so, subject to
374
+ the following conditions:
375
+
376
+ The above copyright notice and this permission notice shall be
377
+ included in all copies or substantial portions of the Software.
378
+
379
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
380
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
381
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
382
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
383
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
384
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
385
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.