diff --git a/editor-plugin/src/commands.ts b/editor-plugin/src/commands.ts index 7add914..be5984e 100644 --- a/editor-plugin/src/commands.ts +++ b/editor-plugin/src/commands.ts @@ -80,10 +80,26 @@ export function registerCommands(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand('cargo-scan.create_chain', async () => { client.sendRequest('cargo-scan.create_chain'); + + client.onNotification('cargo-scan.info', (message: string) => { + vscode.window.showInformationMessage( + message, + 'View Logs', + // 'Settings' + ).then(selection => { + if (selection === 'View Logs') { + client.outputChannel.show(); + } + // else if (selection === 'Settings') { + // vscode.commands.executeCommand('workbench.action.openSettings', '@ext:PLsysSec.cargo-scan'); + // } + }); + }); + context.globalState.update('annotateEffects', false); context.globalState.update('chainAudit', false); locationsProvider.clear(); - annotations.clear(); + annotations.clear(); }) ); diff --git a/lang_server/src/server.rs b/lang_server/src/server.rs index c481ce8..9dfc3bf 100644 --- a/lang_server/src/server.rs +++ b/lang_server/src/server.rs @@ -64,6 +64,16 @@ impl Request for CallerCheckedCommand { const METHOD: &'static str = "cargo-scan.get_callers"; } +#[derive(Debug, Serialize, Deserialize)] +struct InfoMessageParams { + pub message: String, +} + +impl Notification for InfoMessageParams { + const METHOD: &'static str = "cargo-scan.info"; + type Params = InfoMessageParams; +} + pub fn run_server() -> anyhow::Result<(), Box> { let (connection, io_threads) = Connection::stdio(); @@ -190,10 +200,23 @@ fn runner( let create_args = Create { crate_path: root_crate_path.to_string_lossy().to_string(), manifest_path: chain_manifest.to_string_lossy().to_string(), - force_overwrite: true, ..Default::default() }; + if !create_args.force_overwrite { + let params = InfoMessageParams { + message: "May reuse existing audits for chain" + .to_string(), + }; + let value = serde_json::to_value(params.message)?; + let notification = + Message::Notification(lsp_server::Notification { + method: InfoMessageParams::METHOD.to_string(), + params: value, + }); + conn.sender.send(notification)?; + } + CommandRunner::run_command( Command::Create(create_args), outer_args, diff --git a/src/audit_chain.rs b/src/audit_chain.rs index f7213bd..7891bc6 100644 --- a/src/audit_chain.rs +++ b/src/audit_chain.rs @@ -479,10 +479,23 @@ fn make_new_audit_file( if args.force_overwrite { remove_file(audit_file_path.clone())?; } else { - return Err(anyhow!("Audit file already exists")); + info!( + "Using existing audit for {} v{} ({})", + package.name, + package.version, + audit_file_path.display() + ); + let audit_file = AuditFile::read_audit_file(audit_file_path.clone())? + .ok_or_else(|| { + anyhow!("Couldn't read audit: {}", audit_file_path.display()) + })?; + chain.add_crate_audit_file(package, audit_file_path, audit_file.version); + + return Ok(()); } } + info!("Making default audit for {} v{}", package.name, package.version); let sinks = collect_dependency_sinks(chain, &package.dependencies)?; let audit_file = AuditFile::new_default_with_sinks( &package_path, @@ -539,7 +552,6 @@ pub fn create_new_audit_chain( let mut traverse = DfsPostOrder::new(&graph, root_node); while let Some(node) = traverse.next(&graph) { let package = package_map.get(&node).unwrap(); - info!("Making default audit for {} v{}", package.name, package.version); let audit_type = if node == root_node { DefaultAuditType::Empty