Skip to content

Commit

Permalink
Rework workspace & repo content finding with ContentScanner type
Browse files Browse the repository at this point in the history
  • Loading branch information
SpontanCombust committed Mar 25, 2024
1 parent 1d80cd6 commit 380d34f
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 257 deletions.
104 changes: 40 additions & 64 deletions crates/lsp/src/indexing/content_indexing.rs
Original file line number Diff line number Diff line change
@@ -1,97 +1,73 @@
use std::collections::HashMap;
use tokio::time::Instant;
use abs_path::AbsPath;
use witcherscript_project::content::{ContentScanError, ProjectDirectory, find_content_in_directory};
use witcherscript_project::content::ContentScanError;
use witcherscript_project::source_tree::SourceTreeDifference;
use witcherscript_project::{Content, ContentRepositories, FileError};
use witcherscript_project::{ContentScanner, FileError};
use witcherscript_project::content_graph::{ContentGraphDifference, ContentGraphError};
use crate::{reporting::IntoLspDiagnostic, Backend};


impl Backend {
pub async fn scan_workspace_projects(&self) {
self.log_info("Scanning workspace projects...").await;

let mut projects = Vec::new();

pub async fn setup_workspace_content_scanners(&self) {
let mut graph = self.content_graph.write().await;
let workspace_roots = self.workspace_roots.read().await;

graph.clear_workspace_scanners();

for root in workspace_roots.iter() {
let (contents, errors) = find_content_in_directory(root, true);

for content in contents {
if let Ok(proj) = content.into_any().downcast::<ProjectDirectory>() {
projects.push(proj);
}
}

for err in errors {
self.report_content_scan_error(err).await;
}
}
let scanner =
ContentScanner::new(root.clone()).unwrap()
.recursive(true)
.only_projects(true);

if projects.is_empty() {
self.log_info("Found no projects in the workspace.").await;
} else {
for proj in &projects {
self.log_info(format!("Found project {}", proj.content_name())).await;
}
graph.add_workspace_scanner(scanner);
}

let mut graph = self.content_graph.write().await;
graph.set_workspace_projects(projects);
}

pub async fn scan_content_repositories(&self) {
self.log_info("Scanning content repositories...").await;
}

let mut repos = ContentRepositories::new();

pub async fn setup_repository_content_scanners(&self) {
let mut graph = self.content_graph.write().await;
let config = self.config.read().await;

let mut repo_paths = Vec::new();

for repo in &config.project_repositories {
repo_paths.push(repo.clone());
}

repo_paths.push(config.game_directory.join("content"));
repo_paths.push(config.game_directory.join("Mods"));


graph.clear_repository_scanners();

for repo in repo_paths {
if !repo.as_os_str().is_empty() {
match AbsPath::resolve(repo, None) {
match AbsPath::resolve(&repo, None) {
Ok(abs_repo) => {
repos.add_repository(abs_repo);
match ContentScanner::new(abs_repo) {
Ok(scanner) => {
let scanner = scanner.recursive(false).only_projects(false);
graph.add_repository_scanner(scanner);
},
Err(err) => {
self.report_content_scan_error(err).await;
},
}
}
Err(_) => {
self.log_error(format!("Invalid project repository path: {}", repo.display())).await;
}
}
}
}
if !config.game_directory.as_os_str().is_empty() {
match AbsPath::resolve(&config.game_directory, None) {
Ok(abs_game_directory) => {
repos.add_repository(abs_game_directory.join("content").unwrap());
repos.add_repository(abs_game_directory.join("Mods").unwrap());
}
Err(_) => {
self.log_error(format!("Invalid game directory path: {}", config.game_directory.display())).await;
}
}
}

repos.scan();

for err in &repos.errors {
self.report_content_scan_error(err.clone()).await;
}

if repos.found_content().is_empty() {
self.log_info("Found no script contents in repositories.").await;
} else {
for content in repos.found_content() {
self.log_info(format!("Found script content {}", content.content_name())).await;
}
}

let mut graph = self.content_graph.write().await;
graph.set_repositories(repos);
}

pub async fn build_content_graph(&self) {
self.log_info("Building content graph...").await;

self.clear_all_diagnostics().await;

let mut graph = self.content_graph.write().await;
let diff = graph.build();

Expand Down
4 changes: 1 addition & 3 deletions crates/lsp/src/providers/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use crate::Backend;

pub async fn did_change_configuration(backend: &Backend, _: lsp::DidChangeConfigurationParams) {
if backend.fetch_config().await {
backend.clear_all_diagnostics().await;

backend.scan_content_repositories().await;
backend.setup_repository_content_scanners().await;
backend.build_content_graph().await;
}
}
7 changes: 3 additions & 4 deletions crates/lsp/src/providers/document_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use tower_lsp::jsonrpc::Result;
use abs_path::AbsPath;
use witcherscript::{script_document::ScriptDocument, Script};
use witcherscript_analysis::{diagnostics::Diagnostic, jobs::syntax_analysis};
use witcherscript_project::Manifest;
use witcherscript_project::{content::ProjectDirectory, Manifest};
use crate::{reporting::IntoLspDiagnostic, Backend};


Expand Down Expand Up @@ -49,13 +49,12 @@ pub async fn did_open(backend: &Backend, params: lsp::DidOpenTextDocumentParams)
let project_is_known = backend
.content_graph
.read().await
.get_workspace_projects()
.iter()
.nodes()
.filter_map(|n| n.content.as_any().downcast_ref::<ProjectDirectory>())
.any(|p| p.manifest_path() == &doc_path);

if !project_is_known {
backend.log_info("Opened unknown manifest file").await;
backend.scan_workspace_projects().await;
backend.build_content_graph().await;
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/lsp/src/providers/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub async fn initialized(backend: &Backend, _: lsp::InitializedParams) {
}
]).await.unwrap();

backend.scan_content_repositories().await;
backend.scan_workspace_projects().await;
backend.setup_workspace_content_scanners().await;
backend.setup_repository_content_scanners().await;
backend.build_content_graph().await;
}
4 changes: 1 addition & 3 deletions crates/lsp/src/providers/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ pub async fn did_change_workspace_folders(backend: &Backend, params: lsp::DidCha
workspace_roots.extend(added);
}

backend.clear_all_diagnostics().await;

backend.scan_workspace_projects().await;
backend.setup_workspace_content_scanners().await;
backend.build_content_graph().await;
}
47 changes: 0 additions & 47 deletions crates/project/src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,53 +176,6 @@ pub enum ContentScanError {
NotContent,
}

pub fn find_content_in_directory(path: &AbsPath, scan_recursively: bool) -> (Vec<Box<dyn Content>>, Vec<ContentScanError>) {
let mut contents = Vec::new();
let mut errors = Vec::new();

if path.is_dir() {
if let Ok(content) = try_make_content(path) {
contents.push(content);
} else {
_find_content_in_directory(path, scan_recursively, &mut contents, &mut errors);
}
}

(contents, errors)
}

fn _find_content_in_directory(path: &AbsPath, scan_recursively: bool, contents: &mut Vec<Box<dyn Content>>, errors: &mut Vec<ContentScanError>) {
match std::fs::read_dir(path) {
Ok(iter) => {
for entry in iter {
match entry {
Ok(entry) => {
let candidate = AbsPath::resolve(entry.path(), None).unwrap();
if candidate.is_dir() {
match try_make_content(&candidate) {
Ok(content) => contents.push(content),
Err(err) => {
if let (&ContentScanError::NotContent, true) = (&err, scan_recursively) {
_find_content_in_directory(&candidate, scan_recursively, contents, errors)
} else {
errors.push(err);
}
}
}
}
},
Err(err) => {
errors.push(FileError::new(path.clone(), err).into());
}
}
}
},
Err(err) => {
errors.push(FileError::new(path.clone(), err).into());
}
}
}

pub fn try_make_content(path: &AbsPath) -> Result<Box<dyn Content>, ContentScanError> {
let manifest_path = path.join(Manifest::FILE_NAME).unwrap();
if manifest_path.exists() {
Expand Down
Loading

0 comments on commit 380d34f

Please sign in to comment.