28
28
import gi
29
29
30
30
warnings .filterwarnings ("ignore" ) # suppress GTK warnings
31
- gi .require_version (' Gtk' , ' 4.0' )
31
+ gi .require_version (" Gtk" , " 4.0" )
32
32
33
33
APP_VERSION = "@APP_VERSION@"
34
34
pkgdatadir = "@pkgdatadir@"
@@ -69,83 +69,169 @@ class CLI:
69
69
def __init__ (self ):
70
70
# self.__clear()
71
71
72
- self .parser = argparse .ArgumentParser (description = "Bottles is a tool to manage your bottles" )
73
- self .parser .add_argument ("-v" , "--version" , action = "version" , version = f"Bottles { APP_VERSION } " )
74
- self .parser .add_argument ("-j" , "--json" , action = "store_true" , help = "Outputs in JSON format" )
72
+ self .parser = argparse .ArgumentParser (
73
+ description = "Bottles is a tool to manage your bottles"
74
+ )
75
+ self .parser .add_argument (
76
+ "-v" , "--version" , action = "version" , version = f"Bottles { APP_VERSION } "
77
+ )
78
+ self .parser .add_argument (
79
+ "-j" , "--json" , action = "store_true" , help = "Outputs in JSON format"
80
+ )
75
81
76
- subparsers = self .parser .add_subparsers (dest = ' command' , help = ' sub-command help' )
82
+ subparsers = self .parser .add_subparsers (dest = " command" , help = " sub-command help" )
77
83
78
- info_parser = subparsers .add_parser ("info" , help = "Show information about Bottles" )
79
- info_parser .add_argument ('type' , choices = ['bottles-path' , 'health-check' ], help = "Type of information" )
84
+ info_parser = subparsers .add_parser (
85
+ "info" , help = "Show information about Bottles"
86
+ )
87
+ info_parser .add_argument (
88
+ "type" , choices = ["bottles-path" , "health-check" ], help = "Type of information"
89
+ )
80
90
81
91
list_parser = subparsers .add_parser ("list" , help = "List entities" )
82
- list_parser .add_argument ('type' , choices = ['bottles' , 'components' ], help = "Type of entity" )
83
- list_parser .add_argument ("-f" , "--filter" , help = "Filter bottles and components (e.g. '-f 'environment:gaming')" )
92
+ list_parser .add_argument (
93
+ "type" , choices = ["bottles" , "components" ], help = "Type of entity"
94
+ )
95
+ list_parser .add_argument (
96
+ "-f" ,
97
+ "--filter" ,
98
+ help = "Filter bottles and components (e.g. '-f 'environment:gaming')" ,
99
+ )
84
100
85
101
programs_parser = subparsers .add_parser ("programs" , help = "List programs" )
86
- programs_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
102
+ programs_parser .add_argument (
103
+ "-b" , "--bottle" , help = "Bottle name" , required = True
104
+ )
87
105
88
106
add_parser = subparsers .add_parser ("add" , help = "Add program" )
89
107
add_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
90
108
add_parser .add_argument ("-n" , "--name" , help = "Program name" , required = True )
91
109
add_parser .add_argument ("-p" , "--path" , help = "Program path" , required = True )
92
110
add_parser .add_argument ("-l" , "--launch-options" , help = "Program launch options" )
93
- add_parser .add_argument ("--no-dxvk" , action = "store_true" , help = "Disable DXVK for the program" )
94
- add_parser .add_argument ("--no-vkd3d" , action = "store_true" , help = "Disable VKD3D for the program" )
95
- add_parser .add_argument ("--no-dxvk-nvapi" , action = "store_true" , help = "Disable DXVK Nvapi for the program" )
111
+ add_parser .add_argument (
112
+ "--no-dxvk" , action = "store_true" , help = "Disable DXVK for the program"
113
+ )
114
+ add_parser .add_argument (
115
+ "--no-vkd3d" , action = "store_true" , help = "Disable VKD3D for the program"
116
+ )
117
+ add_parser .add_argument (
118
+ "--no-dxvk-nvapi" ,
119
+ action = "store_true" ,
120
+ help = "Disable DXVK Nvapi for the program" ,
121
+ )
96
122
97
123
tools_parser = subparsers .add_parser ("tools" , help = "Launch Wine tools" )
98
- tools_parser .add_argument ('tool' , choices = ['cmd' , 'winecfg' , 'uninstaller' , 'regedit' , 'taskmgr' , 'control' ,
99
- 'explorer' ], help = "Tool to launch" )
124
+ tools_parser .add_argument (
125
+ "tool" ,
126
+ choices = [
127
+ "cmd" ,
128
+ "winecfg" ,
129
+ "uninstaller" ,
130
+ "regedit" ,
131
+ "taskmgr" ,
132
+ "control" ,
133
+ "explorer" ,
134
+ ],
135
+ help = "Tool to launch" ,
136
+ )
100
137
tools_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
101
138
102
139
reg_parser = subparsers .add_parser ("reg" , help = "Manage registry" )
103
- reg_parser .add_argument ('action' , choices = ['add' , 'edit' , 'del' ], help = "Action to perform" )
140
+ reg_parser .add_argument (
141
+ "action" , choices = ["add" , "edit" , "del" ], help = "Action to perform"
142
+ )
104
143
reg_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
105
144
reg_parser .add_argument ("-k" , "--key" , help = "Registry key" , required = True )
106
145
reg_parser .add_argument ("-v" , "--value" , help = "Registry value" , required = True )
107
146
reg_parser .add_argument ("-d" , "--data" , help = "Data to be set" )
108
- reg_parser .add_argument ("-t" , "--key-type" , help = "Data type" ,
109
- choices = ['REG_DWORD' , 'REG_SZ' , 'REG_BINARY' , 'REG_MULTI_SZ' ])
147
+ reg_parser .add_argument (
148
+ "-t" ,
149
+ "--key-type" ,
150
+ help = "Data type" ,
151
+ choices = ["REG_DWORD" , "REG_SZ" , "REG_BINARY" , "REG_MULTI_SZ" ],
152
+ )
110
153
111
154
edit_parser = subparsers .add_parser ("edit" , help = "Edit a bottle configuration" )
112
155
edit_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
113
- edit_parser .add_argument ("--params" , help = "Set parameters (e.g. '-p dxvk:true')" )
114
- edit_parser .add_argument ("--env-var" ,
115
- help = "Add new environment variable (e.g. '-env-var WINEDEBUG=-all')" )
116
- edit_parser .add_argument ("--win" , help = "Change Windows version (e.g. '--win win7')" )
117
- edit_parser .add_argument ("--runner" , help = "Change Runner (e.g. '--runner caffe-7.2')" )
118
- edit_parser .add_argument ("--dxvk" , help = "Change DXVK (e.g. '--dxvk dxvk-1.9.0')" )
119
- edit_parser .add_argument ("--vkd3d" , help = "Change VKD3D (e.g. '--vkd3d vkd3d-proton-2.6')" )
120
- edit_parser .add_argument ("--nvapi" , help = "Change DXVK-Nvapi (e.g. '--nvapi dxvk-nvapi-1.9.0')" )
121
- edit_parser .add_argument ("--latencyflex" , help = "Change LatencyFleX (e.g. '--latencyflex latencyflex-v0.1.0')" )
156
+ edit_parser .add_argument (
157
+ "--params" , help = "Set parameters (e.g. '-p dxvk:true')"
158
+ )
159
+ edit_parser .add_argument (
160
+ "--env-var" ,
161
+ help = "Add new environment variable (e.g. '-env-var WINEDEBUG=-all')" ,
162
+ )
163
+ edit_parser .add_argument (
164
+ "--win" , help = "Change Windows version (e.g. '--win win7')"
165
+ )
166
+ edit_parser .add_argument (
167
+ "--runner" , help = "Change Runner (e.g. '--runner caffe-7.2')"
168
+ )
169
+ edit_parser .add_argument (
170
+ "--dxvk" , help = "Change DXVK (e.g. '--dxvk dxvk-1.9.0')"
171
+ )
172
+ edit_parser .add_argument (
173
+ "--vkd3d" , help = "Change VKD3D (e.g. '--vkd3d vkd3d-proton-2.6')"
174
+ )
175
+ edit_parser .add_argument (
176
+ "--nvapi" , help = "Change DXVK-Nvapi (e.g. '--nvapi dxvk-nvapi-1.9.0')"
177
+ )
178
+ edit_parser .add_argument (
179
+ "--latencyflex" ,
180
+ help = "Change LatencyFleX (e.g. '--latencyflex latencyflex-v0.1.0')" ,
181
+ )
122
182
123
183
new_parser = subparsers .add_parser ("new" , help = "Create a new bottle" )
124
184
new_parser .add_argument ("--bottle-name" , help = "Bottle name" , required = True )
125
- new_parser .add_argument ("--environment" , help = "Environment to apply (gaming|application|custom)" , required = True )
126
- new_parser .add_argument ("--custom-environment" , help = "Path to a custom environment.yml file" )
185
+ new_parser .add_argument (
186
+ "--environment" ,
187
+ help = "Environment to apply (gaming|application|custom)" ,
188
+ required = True ,
189
+ )
190
+ new_parser .add_argument (
191
+ "--custom-environment" , help = "Path to a custom environment.yml file"
192
+ )
127
193
new_parser .add_argument ("--arch" , help = "Architecture (win32|win64)" )
128
194
new_parser .add_argument ("--runner" , help = "Name of the runner to be used" )
129
195
new_parser .add_argument ("--dxvk" , help = "Name of the dxvk to be used" )
130
196
new_parser .add_argument ("--vkd3d" , help = "Name of the vkd3d to be used" )
131
197
new_parser .add_argument ("--nvapi" , help = "Name of the dxvk-nvapi to be used" )
132
- new_parser .add_argument ("--latencyflex" , help = "Name of the latencyflex to be used" )
198
+ new_parser .add_argument (
199
+ "--latencyflex" , help = "Name of the latencyflex to be used"
200
+ )
133
201
134
202
run_parser = subparsers .add_parser ("run" , help = "Run a program" )
135
203
run_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
136
204
run_parser .add_argument ("-e" , "--executable" , help = "Path to the executable" )
137
205
run_parser .add_argument ("-p" , "--program" , help = "Program to run" )
138
- run_parser .add_argument ("--args-replace" , action = 'store_false' , dest = 'keep_args' ,
139
- help = "Replace current program arguments, instead of append" )
140
- run_parser .add_argument ("args" , nargs = "*" , action = "extend" , help = "Arguments to pass to the executable" )
206
+ run_parser .add_argument (
207
+ "--args-replace" ,
208
+ action = "store_false" ,
209
+ dest = "keep_args" ,
210
+ help = "Replace current program arguments, instead of append" ,
211
+ )
212
+ run_parser .add_argument (
213
+ "args" ,
214
+ nargs = "*" ,
215
+ action = "extend" ,
216
+ help = "Arguments to pass to the executable" ,
217
+ )
141
218
142
- standalone_parser = subparsers .add_parser ("standalone" , help = "Generate a standalone script to launch commands "
143
- "without passing trough Bottles" )
144
- standalone_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
219
+ standalone_parser = subparsers .add_parser (
220
+ "standalone" ,
221
+ help = "Generate a standalone script to launch commands "
222
+ "without passing trough Bottles" ,
223
+ )
224
+ standalone_parser .add_argument (
225
+ "-b" , "--bottle" , help = "Bottle name" , required = True
226
+ )
145
227
146
- shell_parser = subparsers .add_parser ("shell" , help = "Launch commands in a Wine shell" )
228
+ shell_parser = subparsers .add_parser (
229
+ "shell" , help = "Launch commands in a Wine shell"
230
+ )
147
231
shell_parser .add_argument ("-b" , "--bottle" , help = "Bottle name" , required = True )
148
- shell_parser .add_argument ("-i" , "--input" , help = "Command to execute" , required = True )
232
+ shell_parser .add_argument (
233
+ "-i" , "--input" , help = "Command to execute" , required = True
234
+ )
149
235
150
236
self .__process_args ()
151
237
@@ -233,7 +319,11 @@ def list_bottles(self, c_filter=None):
233
319
234
320
if c_filter and c_filter .startswith ("environment:" ):
235
321
environment = c_filter .split (":" )[1 ].lower ()
236
- bottles = [name for name , bottle in bottles .items () if bottle .Environment .lower () == environment ]
322
+ bottles = [
323
+ name
324
+ for name , bottle in bottles .items ()
325
+ if bottle .Environment .lower () == environment
326
+ ]
237
327
238
328
if self .args .json :
239
329
sys .stdout .write (json .dumps (bottles ))
@@ -257,7 +347,7 @@ def list_components(self, c_filter=None):
257
347
"dxvk" : mng .dxvk_available ,
258
348
"vkd3d" : mng .vkd3d_available ,
259
349
"nvapi" : mng .nvapi_available ,
260
- "latencyflex" : mng .latencyflex_available
350
+ "latencyflex" : mng .latencyflex_available ,
261
351
}
262
352
263
353
if c_filter and c_filter .startswith ("category:" ):
@@ -376,7 +466,9 @@ def add_program(self):
376
466
"path" : _path ,
377
467
"dxvk" : not _no_dxvk if _no_dxvk else bottle .Parameters .dxvk ,
378
468
"vkd3d" : not _no_vkd3d if _no_vkd3d else bottle .Parameters .vkd3d ,
379
- "dxvk_nvapi" : not _no_dxvk_nvapi if _no_dxvk_nvapi else bottle .Parameters .dxvk_nvapi ,
469
+ "dxvk_nvapi" : (
470
+ not _no_dxvk_nvapi if _no_dxvk_nvapi else bottle .Parameters .dxvk_nvapi
471
+ ),
380
472
}
381
473
mng .update_config (bottle , _uuid , _program , scope = "External_Programs" )
382
474
sys .stdout .write (f"'{ _name } ' added to '{ bottle .Name } '!" )
@@ -529,7 +621,7 @@ def new_bottle(self):
529
621
nvapi = _nvapi ,
530
622
latencyflex = _latencyflex ,
531
623
arch = _arch ,
532
- custom_environment = _custom_environment
624
+ custom_environment = _custom_environment ,
533
625
)
534
626
535
627
# endregion
@@ -552,7 +644,15 @@ def run_program(self):
552
644
mng = Manager (g_settings = self .settings , is_cli = True )
553
645
mng .checks ()
554
646
555
- if _bottle not in mng .local_bottles :
647
+ if _bottle .startswith ('"' ) and _bottle .endswith ('"' ):
648
+ _bottle = _bottle [1 :- 1 ]
649
+ elif _bottle .startswith ("'" ) and _bottle .endswith ("'" ):
650
+ _bottle = _bottle [1 :- 1 ]
651
+
652
+ for b in mng .local_bottles .keys ():
653
+ if b == _bottle :
654
+ break
655
+ else :
556
656
sys .stderr .write (f"Bottle { _bottle } not found\n " )
557
657
exit (1 )
558
658
@@ -582,6 +682,12 @@ def run_program(self):
582
682
_program_fsr = program .get ("fsr" )
583
683
_program_virt_desktop = program .get ("virtual_desktop" )
584
684
685
+ _executable = _executable .replace ("file://" , "" )
686
+ if _executable .startswith ('"' ) and _executable .endswith ('"' ):
687
+ _executable = _executable [1 :- 1 ]
688
+ elif _executable .startswith ("'" ) and _executable .endswith ("'" ):
689
+ _executable = _executable [1 :- 1 ]
690
+
585
691
WineExecutor (
586
692
bottle ,
587
693
exec_path = _executable ,
@@ -592,7 +698,7 @@ def run_program(self):
592
698
program_vkd3d = _program_vkd3d ,
593
699
program_nvapi = _program_dxvk_nvapi ,
594
700
program_fsr = _program_fsr ,
595
- program_virt_desktop = _program_virt_desktop
701
+ program_virt_desktop = _program_virt_desktop ,
596
702
).run_cli ()
597
703
598
704
# endregion
@@ -633,7 +739,9 @@ def generate_standalone(self):
633
739
winecommand = WineCommand (config = bottle , command = '"$@"' )
634
740
env = winecommand .get_env (return_clean_env = True )
635
741
cmd = winecommand .get_cmd ('"$@"' , return_clean_cmd = True )
636
- winecommand .command .replace ("/usr/lib/extensions/vulkan/MangoHud/bin/mangohud" , "" )
742
+ winecommand .command .replace (
743
+ "/usr/lib/extensions/vulkan/MangoHud/bin/mangohud" , ""
744
+ )
637
745
638
746
if os .path .isfile (standalone_path ):
639
747
os .remove (standalone_path )
@@ -649,5 +757,5 @@ def generate_standalone(self):
649
757
sys .stdout .write ("Re-generate after every bottle change.\n " )
650
758
651
759
652
- if __name__ == ' __main__' :
760
+ if __name__ == " __main__" :
653
761
cli = CLI ()
0 commit comments