Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/cli/src/commands/args.rs
3314 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
use std::{fmt, path::PathBuf};
7
8
use crate::{constants, log, options, tunnels::code_server::CodeServerArgs};
9
use clap::{Args, Parser, Subcommand, ValueEnum};
10
use const_format::concatcp;
11
12
const CLI_NAME: &str = concatcp!(constants::PRODUCT_NAME_LONG, " CLI");
13
const HELP_COMMANDS: &str = concatcp!(
14
"Usage: ",
15
constants::APPLICATION_NAME,
16
" [options][paths...]
17
18
To read output from another program, append '-' (e.g. 'echo Hello World | {name} -')"
19
);
20
21
const STANDALONE_TEMPLATE: &str = concatcp!(
22
CLI_NAME,
23
" Standalone - {version}
24
25
",
26
HELP_COMMANDS,
27
"
28
Running editor commands requires installing ",
29
constants::QUALITYLESS_PRODUCT_NAME,
30
", and may differ slightly.
31
32
{all-args}"
33
);
34
const INTEGRATED_TEMPLATE: &str = concatcp!(
35
CLI_NAME,
36
" - {version}
37
38
",
39
HELP_COMMANDS,
40
"
41
42
{all-args}"
43
);
44
45
const COMMIT_IN_VERSION: &str = match constants::VSCODE_CLI_COMMIT {
46
Some(c) => c,
47
None => "unknown",
48
};
49
const NUMBER_IN_VERSION: &str = match constants::VSCODE_CLI_VERSION {
50
Some(c) => c,
51
None => "dev",
52
};
53
const VERSION: &str = concatcp!(NUMBER_IN_VERSION, " (commit ", COMMIT_IN_VERSION, ")");
54
55
#[derive(Parser, Debug, Default)]
56
#[clap(
57
help_template = INTEGRATED_TEMPLATE,
58
long_about = None,
59
name = constants::APPLICATION_NAME,
60
version = VERSION,
61
)]
62
pub struct IntegratedCli {
63
#[clap(flatten)]
64
pub core: CliCore,
65
}
66
67
/// Common CLI shared between integrated and standalone interfaces.
68
#[derive(Args, Debug, Default, Clone)]
69
pub struct CliCore {
70
/// One or more files, folders, or URIs to open.
71
#[clap(name = "paths")]
72
pub open_paths: Vec<String>,
73
74
#[clap(flatten, next_help_heading = Some("EDITOR OPTIONS"))]
75
pub editor_options: EditorOptions,
76
77
#[clap(flatten, next_help_heading = Some("EDITOR TROUBLESHOOTING"))]
78
pub troubleshooting: EditorTroubleshooting,
79
80
#[clap(flatten, next_help_heading = Some("GLOBAL OPTIONS"))]
81
pub global_options: GlobalOptions,
82
83
#[clap(subcommand)]
84
pub subcommand: Option<Commands>,
85
}
86
87
#[derive(Parser, Debug, Default)]
88
#[clap(
89
help_template = STANDALONE_TEMPLATE,
90
long_about = None,
91
version = VERSION,
92
name = constants::APPLICATION_NAME,
93
)]
94
pub struct StandaloneCli {
95
#[clap(flatten)]
96
pub core: CliCore,
97
98
#[clap(subcommand)]
99
pub subcommand: Option<StandaloneCommands>,
100
}
101
102
pub enum AnyCli {
103
Integrated(IntegratedCli),
104
Standalone(StandaloneCli),
105
}
106
107
impl AnyCli {
108
pub fn core(&self) -> &CliCore {
109
match self {
110
AnyCli::Integrated(cli) => &cli.core,
111
AnyCli::Standalone(cli) => &cli.core,
112
}
113
}
114
}
115
116
impl CliCore {
117
pub fn get_base_code_args(&self) -> Vec<String> {
118
let mut args = self.open_paths.clone();
119
self.editor_options.add_code_args(&mut args);
120
self.troubleshooting.add_code_args(&mut args);
121
self.global_options.add_code_args(&mut args);
122
args
123
}
124
}
125
126
impl<'a> From<&'a CliCore> for CodeServerArgs {
127
fn from(cli: &'a CliCore) -> Self {
128
let mut args = CodeServerArgs {
129
log: cli.global_options.log,
130
accept_server_license_terms: true,
131
..Default::default()
132
};
133
134
args.log = cli.global_options.log;
135
args.accept_server_license_terms = true;
136
137
if cli.global_options.verbose {
138
args.verbose = true;
139
}
140
141
if cli.global_options.disable_telemetry {
142
args.telemetry_level = Some(options::TelemetryLevel::Off);
143
} else if cli.global_options.telemetry_level.is_some() {
144
args.telemetry_level = cli.global_options.telemetry_level;
145
}
146
147
args
148
}
149
}
150
151
#[derive(Subcommand, Debug, Clone)]
152
pub enum StandaloneCommands {
153
/// Updates the CLI.
154
Update(StandaloneUpdateArgs),
155
}
156
157
#[derive(Args, Debug, Clone)]
158
pub struct StandaloneUpdateArgs {
159
/// Only check for updates, without actually updating the CLI.
160
#[clap(long)]
161
pub check: bool,
162
}
163
164
#[derive(Subcommand, Debug, Clone)]
165
166
pub enum Commands {
167
/// Create a tunnel that's accessible on vscode.dev from anywhere.
168
/// Run `code tunnel --help` for more usage info.
169
Tunnel(TunnelArgs),
170
171
/// Manage editor extensions.
172
#[clap(name = "ext")]
173
Extension(ExtensionArgs),
174
175
/// Print process usage and diagnostics information.
176
Status,
177
178
/// Changes the version of the editor you're using.
179
Version(VersionArgs),
180
181
/// Runs a local web version of VS Code.
182
#[clap(about = concatcp!("Runs a local web version of ", constants::PRODUCT_NAME_LONG))]
183
ServeWeb(ServeWebArgs),
184
185
/// Runs the control server on process stdin/stdout
186
#[clap(hide = true)]
187
CommandShell(CommandShellArgs),
188
}
189
190
#[derive(Args, Debug, Clone)]
191
pub struct ServeWebArgs {
192
/// Host to listen on, defaults to 'localhost'
193
#[clap(long)]
194
pub host: Option<String>,
195
// The path to a socket file for the server to listen to.
196
#[clap(long)]
197
pub socket_path: Option<String>,
198
/// Port to listen on. If 0 is passed a random free port is picked.
199
#[clap(long, default_value_t = 8000)]
200
pub port: u16,
201
/// A secret that must be included with all requests.
202
#[clap(long)]
203
pub connection_token: Option<String>,
204
/// A file containing a secret that must be included with all requests.
205
#[clap(long)]
206
pub connection_token_file: Option<String>,
207
/// Run without a connection token. Only use this if the connection is secured by other means.
208
#[clap(long)]
209
pub without_connection_token: bool,
210
/// If set, the user accepts the server license terms and the server will be started without a user prompt.
211
#[clap(long)]
212
pub accept_server_license_terms: bool,
213
/// Specifies the path under which the web UI and the code server is provided.
214
#[clap(long)]
215
pub server_base_path: Option<String>,
216
/// Specifies the directory that server data is kept in.
217
#[clap(long)]
218
pub server_data_dir: Option<String>,
219
/// Use a specific commit SHA for the client.
220
#[clap(long)]
221
pub commit_id: Option<String>,
222
}
223
224
#[derive(Args, Debug, Clone)]
225
pub struct CommandShellArgs {
226
#[clap(flatten)]
227
pub server_args: BaseServerArgs,
228
229
/// Listen on a socket instead of stdin/stdout.
230
#[clap(long)]
231
pub on_socket: bool,
232
/// Listen on a host/port instead of stdin/stdout.
233
#[clap(long, num_args = 0..=2, default_missing_value = "0")]
234
pub on_port: Vec<u16>,
235
/// Listen on a host/port instead of stdin/stdout.
236
#[clap[long]]
237
pub on_host: Option<String>,
238
/// Require the given token string to be given in the handshake.
239
#[clap(long, env = "VSCODE_CLI_REQUIRE_TOKEN")]
240
pub require_token: Option<String>,
241
/// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists
242
#[clap(long, hide = true)]
243
pub parent_process_id: Option<String>,
244
}
245
246
#[derive(Args, Debug, Clone)]
247
pub struct ExtensionArgs {
248
#[clap(subcommand)]
249
pub subcommand: ExtensionSubcommand,
250
251
#[clap(flatten)]
252
pub desktop_code_options: DesktopCodeOptions,
253
}
254
255
impl ExtensionArgs {
256
pub fn add_code_args(&self, target: &mut Vec<String>) {
257
self.desktop_code_options.add_code_args(target);
258
self.subcommand.add_code_args(target);
259
}
260
}
261
262
#[derive(Subcommand, Debug, Clone)]
263
pub enum ExtensionSubcommand {
264
/// List installed extensions.
265
List(ListExtensionArgs),
266
/// Install an extension.
267
Install(InstallExtensionArgs),
268
/// Uninstall an extension.
269
Uninstall(UninstallExtensionArgs),
270
/// Update the installed extensions.
271
Update,
272
}
273
274
impl ExtensionSubcommand {
275
pub fn add_code_args(&self, target: &mut Vec<String>) {
276
match self {
277
ExtensionSubcommand::List(args) => {
278
target.push("--list-extensions".to_string());
279
if args.show_versions {
280
target.push("--show-versions".to_string());
281
}
282
if let Some(category) = &args.category {
283
target.push(format!("--category={category}"));
284
}
285
}
286
ExtensionSubcommand::Install(args) => {
287
for id in args.id_or_path.iter() {
288
target.push(format!("--install-extension={id}"));
289
}
290
if args.pre_release {
291
target.push("--pre-release".to_string());
292
}
293
if args.donot_include_pack_and_dependencies {
294
target.push("do-not-include-pack-dependencies".to_string());
295
}
296
if args.force {
297
target.push("--force".to_string());
298
}
299
}
300
ExtensionSubcommand::Uninstall(args) => {
301
for id in args.id.iter() {
302
target.push(format!("--uninstall-extension={id}"));
303
}
304
}
305
ExtensionSubcommand::Update => {
306
target.push("--update-extensions".to_string());
307
}
308
}
309
}
310
}
311
312
#[derive(Args, Debug, Clone)]
313
pub struct ListExtensionArgs {
314
/// Filters installed extensions by provided category, when using --list-extensions.
315
#[clap(long, value_name = "category")]
316
pub category: Option<String>,
317
318
/// Show versions of installed extensions, when using --list-extensions.
319
#[clap(long)]
320
pub show_versions: bool,
321
}
322
323
#[derive(Args, Debug, Clone)]
324
pub struct InstallExtensionArgs {
325
/// Either an extension id or a path to a VSIX. The identifier of an
326
/// extension is '${publisher}.${name}'. Use '--force' argument to update
327
/// to latest version. To install a specific version provide '@${version}'.
328
/// For example: '[email protected]'.
329
#[clap(name = "ext-id | id")]
330
pub id_or_path: Vec<String>,
331
332
/// Installs the pre-release version of the extension
333
#[clap(long)]
334
pub pre_release: bool,
335
336
/// Don't include installing pack and dependencies of the extension
337
#[clap(long)]
338
pub donot_include_pack_and_dependencies: bool,
339
340
/// Update to the latest version of the extension if it's already installed.
341
#[clap(long)]
342
pub force: bool,
343
}
344
345
#[derive(Args, Debug, Clone)]
346
pub struct UninstallExtensionArgs {
347
/// One or more extension identifiers to uninstall. The identifier of an
348
/// extension is '${publisher}.${name}'. Use '--force' argument to update
349
/// to latest version.
350
#[clap(name = "ext-id")]
351
pub id: Vec<String>,
352
}
353
354
#[derive(Args, Debug, Clone)]
355
pub struct VersionArgs {
356
#[clap(subcommand)]
357
pub subcommand: VersionSubcommand,
358
}
359
360
#[derive(Subcommand, Debug, Clone)]
361
pub enum VersionSubcommand {
362
/// Switches the version of the editor in use.
363
Use(UseVersionArgs),
364
365
/// Shows the currently configured editor version.
366
Show,
367
}
368
369
#[derive(Args, Debug, Clone)]
370
pub struct UseVersionArgs {
371
/// The version of the editor you want to use. Can be "stable", "insiders",
372
/// or an absolute path to an existing install.
373
#[clap(value_name = "stable | insiders | x.y.z | path")]
374
pub name: String,
375
376
/// The directory where the version can be found.
377
#[clap(long, value_name = "path")]
378
pub install_dir: Option<String>,
379
}
380
381
#[derive(Args, Debug, Default, Clone)]
382
pub struct EditorOptions {
383
/// Compare two files with each other.
384
#[clap(short, long, value_names = &["file", "file"])]
385
pub diff: Vec<String>,
386
387
/// Add folder(s) to the last active window.
388
#[clap(short, long, value_name = "folder")]
389
pub add: Option<String>,
390
391
/// Open a file at the path on the specified line and character position.
392
#[clap(short, long, value_name = "file:line[:character]")]
393
pub goto: Option<String>,
394
395
/// Force to open a new window.
396
#[clap(short, long)]
397
pub new_window: bool,
398
399
/// Force to open a file or folder in an
400
#[clap(short, long)]
401
pub reuse_window: bool,
402
403
/// Wait for the files to be closed before returning.
404
#[clap(short, long)]
405
pub wait: bool,
406
407
/// The locale to use (e.g. en-US or zh-TW).
408
#[clap(long, value_name = "locale")]
409
pub locale: Option<String>,
410
411
/// Enables proposed API features for extensions. Can receive one or
412
/// more extension IDs to enable individually.
413
#[clap(long, value_name = "ext-id")]
414
pub enable_proposed_api: Vec<String>,
415
416
#[clap(flatten)]
417
pub code_options: DesktopCodeOptions,
418
}
419
420
impl EditorOptions {
421
pub fn add_code_args(&self, target: &mut Vec<String>) {
422
if !self.diff.is_empty() {
423
target.push("--diff".to_string());
424
for file in self.diff.iter() {
425
target.push(file.clone());
426
}
427
}
428
if let Some(add) = &self.add {
429
target.push("--add".to_string());
430
target.push(add.clone());
431
}
432
if let Some(goto) = &self.goto {
433
target.push("--goto".to_string());
434
target.push(goto.clone());
435
}
436
if self.new_window {
437
target.push("--new-window".to_string());
438
}
439
if self.reuse_window {
440
target.push("--reuse-window".to_string());
441
}
442
if self.wait {
443
target.push("--wait".to_string());
444
}
445
if let Some(locale) = &self.locale {
446
target.push(format!("--locale={locale}"));
447
}
448
if !self.enable_proposed_api.is_empty() {
449
for id in self.enable_proposed_api.iter() {
450
target.push(format!("--enable-proposed-api={id}"));
451
}
452
}
453
self.code_options.add_code_args(target);
454
}
455
}
456
457
/// Arguments applicable whenever the desktop editor is launched
458
#[derive(Args, Debug, Default, Clone)]
459
pub struct DesktopCodeOptions {
460
/// Set the root path for extensions.
461
#[clap(long, value_name = "dir")]
462
pub extensions_dir: Option<String>,
463
464
/// Specifies the directory that user data is kept in. Can be used to
465
/// open multiple distinct instances of the editor.
466
#[clap(long, value_name = "dir")]
467
pub user_data_dir: Option<String>,
468
469
/// Sets the editor version to use for this command. The preferred version
470
/// can be persisted with `code version use <version>`. Can be "stable",
471
/// "insiders", a version number, or an absolute path to an existing install.
472
#[clap(long, value_name = "stable | insiders | x.y.z | path")]
473
pub use_version: Option<String>,
474
}
475
476
/// Argument specifying the output format.
477
#[derive(Args, Debug, Clone)]
478
pub struct OutputFormatOptions {
479
/// Set the data output formats.
480
#[clap(value_enum, long, value_name = "format", default_value_t = OutputFormat::Text)]
481
pub format: OutputFormat,
482
}
483
484
impl DesktopCodeOptions {
485
pub fn add_code_args(&self, target: &mut Vec<String>) {
486
if let Some(extensions_dir) = &self.extensions_dir {
487
target.push(format!("--extensions-dir={extensions_dir}"));
488
}
489
if let Some(user_data_dir) = &self.user_data_dir {
490
target.push(format!("--user-data-dir={user_data_dir}"));
491
}
492
}
493
}
494
495
#[derive(Args, Debug, Default, Clone)]
496
pub struct GlobalOptions {
497
/// Directory where CLI metadata should be stored.
498
#[clap(long, env = "VSCODE_CLI_DATA_DIR", global = true)]
499
pub cli_data_dir: Option<String>,
500
501
/// Print verbose output (implies --wait).
502
#[clap(long, global = true)]
503
pub verbose: bool,
504
505
/// Log to a file in addition to stdout. Used when running as a service.
506
#[clap(long, global = true, hide = true)]
507
pub log_to_file: Option<PathBuf>,
508
509
/// Log level to use.
510
#[clap(long, value_enum, value_name = "level", global = true)]
511
pub log: Option<log::Level>,
512
513
/// Disable telemetry for the current command, even if it was previously
514
/// accepted as part of the license prompt or specified in '--telemetry-level'
515
#[clap(long, global = true, hide = true)]
516
pub disable_telemetry: bool,
517
518
/// Sets the initial telemetry level
519
#[clap(value_enum, long, global = true, hide = true)]
520
pub telemetry_level: Option<options::TelemetryLevel>,
521
}
522
523
impl GlobalOptions {
524
pub fn add_code_args(&self, target: &mut Vec<String>) {
525
if self.verbose {
526
target.push("--verbose".to_string());
527
}
528
if let Some(log) = self.log {
529
target.push(format!("--log={log}"));
530
}
531
if self.disable_telemetry {
532
target.push("--disable-telemetry".to_string());
533
}
534
if let Some(telemetry_level) = &self.telemetry_level {
535
target.push(format!("--telemetry-level={telemetry_level}"));
536
}
537
}
538
}
539
540
#[derive(Args, Debug, Default, Clone)]
541
pub struct EditorTroubleshooting {
542
/// Run CPU profiler during startup.
543
#[clap(long)]
544
pub prof_startup: bool,
545
546
/// Disable all installed extensions.
547
#[clap(long)]
548
pub disable_extensions: bool,
549
550
/// Disable an extension.
551
#[clap(long, value_name = "ext-id")]
552
pub disable_extension: Vec<String>,
553
554
/// Turn sync on or off.
555
#[clap(value_enum, long, value_name = "on | off")]
556
pub sync: Option<SyncState>,
557
558
/// Allow debugging and profiling of extensions. Check the developer tools for the connection URI.
559
#[clap(long, value_name = "port")]
560
pub inspect_extensions: Option<u16>,
561
562
/// Allow debugging and profiling of extensions with the extension host
563
/// being paused after start. Check the developer tools for the connection URI.
564
#[clap(long, value_name = "port")]
565
pub inspect_brk_extensions: Option<u16>,
566
567
/// Disable GPU hardware acceleration.
568
#[clap(long)]
569
pub disable_gpu: bool,
570
571
/// Shows all telemetry events which the editor collects.
572
#[clap(long)]
573
pub telemetry: bool,
574
}
575
576
impl EditorTroubleshooting {
577
pub fn add_code_args(&self, target: &mut Vec<String>) {
578
if self.prof_startup {
579
target.push("--prof-startup".to_string());
580
}
581
if self.disable_extensions {
582
target.push("--disable-extensions".to_string());
583
}
584
for id in self.disable_extension.iter() {
585
target.push(format!("--disable-extension={id}"));
586
}
587
if let Some(sync) = &self.sync {
588
target.push(format!("--sync={sync}"));
589
}
590
if let Some(port) = &self.inspect_extensions {
591
target.push(format!("--inspect-extensions={port}"));
592
}
593
if let Some(port) = &self.inspect_brk_extensions {
594
target.push(format!("--inspect-brk-extensions={port}"));
595
}
596
if self.disable_gpu {
597
target.push("--disable-gpu".to_string());
598
}
599
if self.telemetry {
600
target.push("--telemetry".to_string());
601
}
602
}
603
}
604
605
#[derive(ValueEnum, Clone, Copy, Debug)]
606
pub enum SyncState {
607
On,
608
Off,
609
}
610
611
impl fmt::Display for SyncState {
612
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
613
match self {
614
SyncState::Off => write!(f, "off"),
615
SyncState::On => write!(f, "on"),
616
}
617
}
618
}
619
620
#[derive(ValueEnum, Clone, Copy, Debug)]
621
pub enum OutputFormat {
622
Json,
623
Text,
624
}
625
626
#[derive(Args, Clone, Debug, Default)]
627
pub struct ExistingTunnelArgs {
628
/// Name you'd like to assign preexisting tunnel to use to connect the tunnel
629
/// Old option, new code should just use `--name`.
630
#[clap(long, hide = true)]
631
pub tunnel_name: Option<String>,
632
633
/// Token to authenticate and use preexisting tunnel
634
#[clap(long, hide = true)]
635
pub host_token: Option<String>,
636
637
/// ID of preexisting tunnel to use to connect the tunnel
638
#[clap(long, hide = true)]
639
pub tunnel_id: Option<String>,
640
641
/// Cluster of preexisting tunnel to use to connect the tunnel
642
#[clap(long, hide = true)]
643
pub cluster: Option<String>,
644
}
645
646
#[derive(Args, Debug, Clone, Default)]
647
pub struct TunnelServeArgs {
648
#[clap(flatten)]
649
pub server_args: BaseServerArgs,
650
651
/// Optional details to connect to an existing tunnel
652
#[clap(flatten, next_help_heading = Some("ADVANCED OPTIONS"))]
653
pub tunnel: ExistingTunnelArgs,
654
655
/// Randomly name machine for port forwarding service
656
#[clap(long)]
657
pub random_name: bool,
658
659
/// Prevents the machine going to sleep while this command runs.
660
#[clap(long)]
661
pub no_sleep: bool,
662
663
/// Sets the machine name for port forwarding service
664
#[clap(long)]
665
pub name: Option<String>,
666
667
/// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists
668
#[clap(long, hide = true)]
669
pub parent_process_id: Option<String>,
670
671
/// If set, the user accepts the server license terms and the server will be started without a user prompt.
672
#[clap(long)]
673
pub accept_server_license_terms: bool,
674
}
675
676
#[derive(Args, Debug, Clone, Default)]
677
pub struct BaseServerArgs {
678
/// Requests that extensions be preloaded and installed on connecting servers.
679
#[clap(long)]
680
pub install_extension: Vec<String>,
681
682
/// Specifies the directory that server data is kept in.
683
#[clap(long)]
684
pub server_data_dir: Option<String>,
685
686
/// Set the root path for extensions.
687
#[clap(long)]
688
pub extensions_dir: Option<String>,
689
}
690
691
impl BaseServerArgs {
692
pub fn apply_to(&self, csa: &mut CodeServerArgs) {
693
csa.install_extensions
694
.extend_from_slice(&self.install_extension);
695
696
if let Some(d) = &self.server_data_dir {
697
csa.server_data_dir = Some(d.clone());
698
}
699
700
if let Some(d) = &self.extensions_dir {
701
csa.extensions_dir = Some(d.clone());
702
}
703
}
704
}
705
706
#[derive(Args, Debug, Clone)]
707
pub struct TunnelArgs {
708
#[clap(subcommand)]
709
pub subcommand: Option<TunnelSubcommand>,
710
711
#[clap(flatten)]
712
pub serve_args: TunnelServeArgs,
713
}
714
715
#[derive(Subcommand, Debug, Clone)]
716
pub enum TunnelSubcommand {
717
/// Delete all servers which are currently not running.
718
Prune,
719
720
/// Stops any running tunnel on the system.
721
Kill,
722
723
/// Restarts any running tunnel on the system.
724
Restart,
725
726
/// Gets whether there is a tunnel running on the current machine.
727
Status,
728
729
/// Rename the name of this machine associated with port forwarding service.
730
Rename(TunnelRenameArgs),
731
732
/// Remove this machine's association with the port forwarding service.
733
Unregister,
734
735
#[clap(subcommand)]
736
User(TunnelUserSubCommands),
737
738
/// (Preview) Manages the tunnel when installed as a system service,
739
#[clap(subcommand)]
740
Service(TunnelServiceSubCommands),
741
742
/// (Preview) Forwards local port using the dev tunnel
743
#[clap(hide = true)]
744
ForwardInternal(TunnelForwardArgs),
745
}
746
747
#[derive(Subcommand, Debug, Clone)]
748
pub enum TunnelServiceSubCommands {
749
/// Installs or re-installs the tunnel service on the machine.
750
Install(TunnelServiceInstallArgs),
751
752
/// Uninstalls and stops the tunnel service.
753
Uninstall,
754
755
/// Shows logs for the running service.
756
Log,
757
758
/// Internal command for running the service
759
#[clap(hide = true)]
760
InternalRun,
761
}
762
763
#[derive(Args, Debug, Clone)]
764
pub struct TunnelServiceInstallArgs {
765
/// If set, the user accepts the server license terms and the server will be started without a user prompt.
766
#[clap(long)]
767
pub accept_server_license_terms: bool,
768
769
/// Sets the machine name for port forwarding service
770
#[clap(long)]
771
pub name: Option<String>,
772
}
773
774
#[derive(Args, Debug, Clone)]
775
pub struct TunnelRenameArgs {
776
/// The name you'd like to rename your machine to.
777
pub name: String,
778
}
779
780
#[derive(Args, Debug, Clone)]
781
pub struct TunnelForwardArgs {
782
/// One or more ports to forward.
783
pub ports: Vec<u16>,
784
785
/// Login args -- used for convenience so the forwarding call is a single action.
786
#[clap(flatten)]
787
pub login: LoginArgs,
788
}
789
790
#[derive(Subcommand, Debug, Clone)]
791
pub enum TunnelUserSubCommands {
792
/// Log in to port forwarding service
793
Login(LoginArgs),
794
795
/// Log out of port forwarding service
796
Logout,
797
798
/// Show the account that's logged into port forwarding service
799
Show,
800
}
801
802
#[derive(Args, Debug, Clone)]
803
pub struct LoginArgs {
804
/// An access token to store for authentication.
805
#[clap(long, requires = "provider", env = "VSCODE_CLI_ACCESS_TOKEN")]
806
pub access_token: Option<String>,
807
808
/// An access token to store for authentication.
809
#[clap(long, requires = "access_token", env = "VSCODE_CLI_REFRESH_TOKEN")]
810
pub refresh_token: Option<String>,
811
812
/// The auth provider to use. If not provided, a prompt will be shown.
813
#[clap(value_enum, long)]
814
pub provider: Option<AuthProvider>,
815
}
816
817
#[derive(clap::ValueEnum, Debug, Clone, Copy)]
818
pub enum AuthProvider {
819
Microsoft,
820
Github,
821
}
822
823