1use crate::constants::IS_INTERACTIVE_CLI;
6use crate::state::{LauncherPaths, PersistedState};
7use crate::util::errors::{AnyError, CodeError};
8use crate::util::input::prompt_yn;
9use lazy_static::lazy_static;
10use serde::{Deserialize, Serialize};
11
12lazy_static! {
13 static ref LICENSE_TEXT: Option<Vec<String>> =
14 option_env!("VSCODE_CLI_SERVER_LICENSE").and_then(|s| serde_json::from_str(s).unwrap());
15}
16
17const LICENSE_PROMPT: Option<&'static str> = option_env!("VSCODE_CLI_REMOTE_LICENSE_PROMPT");
18
19#[derive(Clone, Default, Serialize, Deserialize)]
20struct PersistedConsent {
21 pub consented: Option<bool>,
22}
23
24pub fn require_consent(
25 paths: &LauncherPaths,
26 accept_server_license_terms: bool,
27) -> Result<(), AnyError> {
28 match &*LICENSE_TEXT {
29 Some(t) => println!("{}", t.join("\r\n")),
30 None => return Ok(()),
31 }
32
33 let prompt = match LICENSE_PROMPT {
34 Some(p) => p,
35 None => return Ok(()),
36 };
37
38 let license: PersistedState<PersistedConsent> =
39 PersistedState::new(paths.root().join("license_consent.json"));
40
41 let mut load = license.load();
42 if let Some(true) = load.consented {
43 return Ok(());
44 }
45
46 if accept_server_license_terms {
47 load.consented = Some(true);
48 } else if !*IS_INTERACTIVE_CLI {
49 return Err(CodeError::NeedsInteractiveLegalConsent.into());
50 } else {
51 match prompt_yn(prompt) {
52 Ok(true) => {
53 load.consented = Some(true);
54 }
55 Ok(false) => return Err(CodeError::DeniedLegalConset.into()),
56 Err(_) => return Err(CodeError::NeedsInteractiveLegalConsent.into()),
57 }
58 }
59
60 license.save(load)?;
61 Ok(())
62}