Skip to content

Commit

Permalink
refactor!: don't modify args sent to godot
Browse files Browse the repository at this point in the history
  • Loading branch information
adalinesimonian committed Jan 18, 2025
1 parent e49d405 commit b98676b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 40 deletions.
19 changes: 6 additions & 13 deletions src/godot_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,16 +521,6 @@ impl<'a> GodotManager<'a> {
}
}

// If no args pointing to files are provided, but the current directory includes a
// project.godot file, add it to the args. Otherwise, Godot may error out with a
// "No main scene set" message.
let current_dir = std::env::current_dir()?;
let project_file = current_dir.join("project.godot");
let mut godot_args = godot_args.to_vec();
if project_file.exists() && godot_args.iter().all(|arg| !Path::new(arg).exists()) {
godot_args.push(project_file.to_string_lossy().to_string());
}

if console {
// Run the process attached to the terminal and wait for it to exit
std::process::Command::new(&path)
Expand Down Expand Up @@ -921,10 +911,13 @@ impl<'a> GodotManager<'a> {
}

/// Try to determine the version to use based on the current Godot project
pub fn determine_version(&self) -> Option<GodotVersion> {
let current_dir = std::env::current_dir().ok()?;
pub fn determine_version<P: AsRef<Path>>(&self, path: Option<P>) -> Option<GodotVersion> {
let current_dir = match path {
Some(p) => p.as_ref().to_path_buf(),
None => std::env::current_dir().ok()?,
};

project_version_detector::detect_godot_version_in_path(self.i18n, current_dir)
project_version_detector::detect_godot_version_in_path(self.i18n, &current_dir)
}

/// Pin a version to .gdvmrc in the current directory
Expand Down
74 changes: 47 additions & 27 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use anyhow::{anyhow, Result};
use clap::{value_parser, Arg, ArgMatches, Command};
use godot_manager::{GodotManager, InstallOutcome};
use i18n::I18n;
use std::io::{self, Write};
use std::{
io::{self, Write},
path::Path,
};

use version_utils::GodotVersion;

Expand All @@ -36,26 +39,6 @@ fn main() -> Result<()> {
// Pass all arguments to Godot
let args: Vec<String> = std::env::args().skip(1).collect();

// Search for the first argument that is a valid file and change to its directory
// This is to make sure that we are using the working directory of the project when checking
// for the Godot version to run
if let Some(file) = args.iter().find(|arg| std::path::Path::new(arg).exists()) {
let file_path = std::path::Path::new(file);

// Resolve to absolute path
let abs_path: std::path::PathBuf = if file_path.is_absolute() {
file_path.to_path_buf()
} else {
std::env::current_dir()?.join(file_path)
};

// Get the parent directory of the file
if let Some(file_dir) = abs_path.parent() {
// Change the current working directory to the file's directory
std::env::set_current_dir(file_dir)?;
}
}

if let Err(err) = sub_run_inner(RunConfig {
i18n: &i18n,
manager: &GodotManager::new(&i18n)?,
Expand Down Expand Up @@ -403,12 +386,37 @@ fn sub_run_inner(config: RunConfig) -> Result<()> {
force_on_mismatch,
} = config;

// Try to see if a path was given in raw_args. First, by checking if the --path flag was given
// and then by checking if the first argument is a path. Prefer the --path flag if both are
// given.
let mut possible_paths: Vec<&str> = Vec::new();
for arg in raw_args.iter() {
if arg == "--path" {
if let Some(p) = raw_args.get(raw_args.iter().position(|x| x == "--path").unwrap() + 1)
{
possible_paths.clear();
possible_paths.push(p);
break;
}
} else if arg.starts_with('-') {
continue;
} else {
possible_paths.push(arg);
}
}

let resolved_version = if let Some(v) = version_input {
let mut requested_version = GodotVersion::from_match_str(v)?;

requested_version.is_csharp = Some(csharp_flag);

if warn_project_version_mismatch(i18n, manager, &requested_version, false) {
if warn_project_version_mismatch(
i18n,
manager,
&requested_version,
false,
Some(&possible_paths),
) {
if force_on_mismatch {
eprintln_i18n!(
i18n,
Expand All @@ -428,7 +436,7 @@ fn sub_run_inner(config: RunConfig) -> Result<()> {

manager.auto_install_version(&requested_version)?
} else if let Some(pinned) = manager.get_pinned_version() {
if warn_project_version_mismatch(i18n, manager, &pinned, true) {
if warn_project_version_mismatch::<&Path>(i18n, manager, &pinned, true, None) {
if force_on_mismatch {
eprintln_i18n!(
i18n,
Expand All @@ -447,7 +455,10 @@ fn sub_run_inner(config: RunConfig) -> Result<()> {
}

manager.auto_install_version(&pinned)?
} else if let Some(project_version) = manager.determine_version() {
} else if let Some(project_version) = possible_paths
.iter()
.find_map(|p| manager.determine_version(Some(p)))
{
eprintln_i18n!(
i18n,
"warning-using-project-version",
Expand Down Expand Up @@ -476,13 +487,22 @@ fn sub_run_inner(config: RunConfig) -> Result<()> {
}

/// Show a warning if the project version is different from the pinned version
fn warn_project_version_mismatch(
fn warn_project_version_mismatch<P: AsRef<Path>>(
i18n: &I18n,
manager: &GodotManager,
requested: &GodotVersion,
is_pin: bool,
paths: Option<&[P]>,
) -> bool {
if let Some(project_version) = manager.determine_version() {
let determined_version = if let Some(paths) = paths {
paths
.iter()
.find_map(|p| manager.determine_version(Some(p)))
} else {
manager.determine_version::<P>(None)
};

if let Some(project_version) = determined_version {
// Check if they don't match (project versions at most specify major.minor or
// major.minor.patch, and if .patch is not specified, it's assumed to allow any patch)
if project_version.major.is_some() && requested.major.is_some() && project_version.major != requested.major // Check major if both are Some
Expand Down Expand Up @@ -642,7 +662,7 @@ fn sub_pin(i18n: &I18n, manager: &GodotManager, matches: &ArgMatches) -> Result<

version.is_csharp = Some(csharp);

warn_project_version_mismatch(i18n, manager, &version, true);
warn_project_version_mismatch::<&Path>(i18n, manager, &version, true, None);

let resolved_version = manager.auto_install_version(&version)?;

Expand Down

0 comments on commit b98676b

Please sign in to comment.