Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ use serde::Deserialize;
use serde::Serialize;

use super::flags_net;
use crate::util::env::resolve_cwd;
use crate::util::fs::canonicalize_path;

#[derive(Clone, Debug, Default, Eq, PartialEq)]
Expand Down Expand Up @@ -1415,7 +1416,7 @@ impl Flags {
exclude: excluded_paths,
..
})) => {
let cwd = std::env::current_dir()?;
let cwd = resolve_cwd(self.initial_cwd.as_deref())?;
PathOrPatternSet::from_exclude_relative_path_or_patterns(
&cwd,
excluded_paths,
Expand Down Expand Up @@ -6145,7 +6146,8 @@ fn completions_parse(
unsafe {
std::env::set_var("COMPLETE", &shell);
}
handle_shell_completion_with_args(std::env::args_os().take(1))?;
let cwd = resolve_cwd(None)?;
handle_shell_completion_with_args(std::env::args_os().take(1), &cwd)?;
Ok(())
}),
));
Expand Down Expand Up @@ -7024,8 +7026,8 @@ fn task_parse(
Ok(())
}

pub fn handle_shell_completion() -> Result<(), AnyError> {
handle_shell_completion_with_args(std::env::args_os())
pub fn handle_shell_completion(cwd: &Path) -> Result<(), AnyError> {
handle_shell_completion_with_args(std::env::args_os(), cwd)
}

struct ZshCompleterUnsorted;
Expand Down Expand Up @@ -7112,6 +7114,7 @@ compdef _clap_dynamic_completer_NAME BIN"#

fn handle_shell_completion_with_args(
args: impl IntoIterator<Item = OsString>,
cwd: &Path,
) -> Result<(), AnyError> {
let args = args.into_iter().collect::<Vec<_>>();
let app = clap_root();
Expand All @@ -7124,7 +7127,7 @@ fn handle_shell_completion_with_args(
&clap_complete::env::Powershell,
&ZshCompleterUnsorted,
]))
.try_complete(args, Some(&std::env::current_dir()?))?;
.try_complete(args, Some(cwd))?;

// we should only run this function when we're doing completions
assert!(ran_completion);
Expand Down Expand Up @@ -12560,12 +12563,12 @@ mod tests {
#[test]
fn test_config_path_args() {
let flags = flags_from_vec(svec!["deno", "run", "foo.js"]).unwrap();
let cwd = std::env::current_dir().unwrap();
let cwd = resolve_cwd(None).unwrap().into_owned();

assert_eq!(flags.config_path_args(&cwd), Some(vec![cwd.clone()]));

let flags = flags_from_vec(svec!["deno", "run", "sub_dir/foo.js"]).unwrap();
let cwd = std::env::current_dir().unwrap();
let cwd = resolve_cwd(None).unwrap().into_owned();
assert_eq!(
flags.config_path_args(&cwd),
Some(vec![cwd.join("sub_dir").clone()])
Expand Down
5 changes: 3 additions & 2 deletions cli/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1785,13 +1785,14 @@ mod test {
use pretty_assertions::assert_eq;

use super::*;
use crate::util::env::resolve_cwd;

#[test]
fn resolve_import_map_flags_take_precedence() {
let config_text = r#"{
"importMap": "import_map.json"
}"#;
let cwd = &std::env::current_dir().unwrap();
let cwd = &resolve_cwd(None).unwrap();
let config_specifier = Url::parse("file:///deno/deno.jsonc").unwrap();
let config_file = ConfigFile::new(config_text, config_specifier).unwrap();
let actual = resolve_import_map_specifier(
Expand Down Expand Up @@ -1859,7 +1860,7 @@ mod test {

#[test]
fn test_flags_to_permission_options() {
let base_dir = std::env::current_dir().unwrap().join("sub");
let base_dir = resolve_cwd(None).unwrap().join("sub");
{
let flags = PermissionFlags::default();
let config = PermissionsObjectWithBase {
Expand Down
2 changes: 2 additions & 0 deletions cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ fn compress_decls(out_dir: &Path) {
}

fn process_node_types(out_dir: &Path) {
#[allow(clippy::disallowed_methods)] // build script
let root_dir = Path::new(".").canonicalize().unwrap();
let dts_dir = root_dir.join("tsc").join("dts");
let node_dir = dts_dir.join("node");
Expand Down Expand Up @@ -201,6 +202,7 @@ fn process_node_types(out_dir: &Path) {
}

fn compress_source(out_dir: &Path, file: &str) {
#[allow(clippy::disallowed_methods)] // build script
let path = Path::new(file)
.canonicalize()
.unwrap_or_else(|_| panic!("expected file \"{file}\" to exist"));
Expand Down
3 changes: 3 additions & 0 deletions cli/clippy.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
disallowed-methods = [
{ path = "reqwest::Client::new", reason = "create an HttpClient via an HttpClientProvider instead" },
{ path = "std::fs::canonicalize", reason = "use crate::util::fs::canonicalize_path instead" },
{ path = "std::path::Path::canonicalize", reason = "use crate::util::fs::canonicalize_path instead" },
{ path = "std::env::current_dir", reason = "use crate::util::env::resolve_cwd instead and prefer passing it the initial_cwd" },
{ path = "std::process::exit", reason = "use deno_runtime::exit instead" },
{ path = "clap::Arg::env", reason = "ensure environment variables are resolved after loading the .env file instead" },
{ path = "tokio::signal::ctrl_c", reason = "use deno_signals crate instead" },
Expand Down
3 changes: 1 addition & 2 deletions cli/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,6 @@ impl CliFactory {
self.npm_installer_if_managed().await?.cloned(),
npm_resolver.clone(),
self.text_only_progress_bar().clone(),
self.sys(),
self.create_cli_main_worker_options()?,
self.root_permissions_container()?.clone(),
))
Expand Down Expand Up @@ -1228,7 +1227,7 @@ impl CliFactory {
create_hmr_runner,
maybe_coverage_dir,
default_npm_caching_strategy: cli_options.default_npm_caching_strategy(),
maybe_initial_cwd: Some(Arc::new(initial_cwd)),
initial_cwd: Arc::new(initial_cwd),
})
}

Expand Down
33 changes: 19 additions & 14 deletions cli/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
use deno_telemetry::OtelConfig;
use deno_terminal::colors;
use factory::CliFactory;
use util::fs::canonicalize_path;

const MODULE_NOT_FOUND: &str = "Module not found";
const UNSUPPORTED_SCHEME: &str = "Unsupported scheme";

use self::util::draw_thread::DrawThread;
use self::util::env::resolve_cwd;
use crate::args::CompletionsFlags;
use crate::args::DenoSubcommand;
use crate::args::Flags;
Expand Down Expand Up @@ -193,9 +195,9 @@ async fn run_subcommand(
DenoSubcommand::Fmt(fmt_flags) => spawn_subcommand(async move {
tools::fmt::format(Arc::new(flags), fmt_flags).await
}),
DenoSubcommand::Init(init_flags) => {
spawn_subcommand(async { tools::init::init_project(init_flags).await })
}
DenoSubcommand::Init(init_flags) => spawn_subcommand(async {
tools::init::init_project(flags, init_flags).await
}),
DenoSubcommand::Info(info_flags) => spawn_subcommand(async {
tools::info::info(Arc::new(flags), info_flags).await
}),
Expand Down Expand Up @@ -416,7 +418,7 @@ async fn run_subcommand(
unsafe {
env::set_var(
"DENO_COVERAGE_DIR",
PathBuf::from(coverage_dir).canonicalize()?,
canonicalize_path(&PathBuf::from(coverage_dir))?,
)
};
}
Expand Down Expand Up @@ -659,15 +661,17 @@ pub fn main() {
(None, None, None);

let args = waited_args.unwrap_or(args);
let initial_cwd = waited_cwd.map(Some).unwrap_or_else(|| {
match std::env::current_dir().with_context(|| "Failed getting cwd.") {
Ok(cwd) => Some(cwd),
Err(err) => {
log::error!("Failed getting cwd: {err}");
None
}
}
});
#[allow(clippy::disallowed_methods)] // ok because initialization of cwd
let initial_cwd =
waited_cwd
.map(Some)
.unwrap_or_else(|| match std::env::current_dir() {
Ok(cwd) => Some(cwd),
Err(err) => {
log::error!("Failed getting cwd: {err}");
None
}
});

// NOTE(lucacasonato): due to new PKU feature introduced in V8 11.6 we need to
// initialize the V8 platform on a parent thread of all threads that will spawn
Expand Down Expand Up @@ -706,7 +710,8 @@ async fn resolve_flags_and_init(
// this env var is used by clap to enable dynamic completions, it's set by the shell when
// executing deno to get dynamic completions.
if std::env::var("COMPLETE").is_ok() {
crate::args::handle_shell_completion()?;
let cwd = resolve_cwd(initial_cwd.as_deref())?;
crate::args::handle_shell_completion(&cwd)?;
deno_runtime::exit(0);
}

Expand Down
3 changes: 2 additions & 1 deletion cli/lsp/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use super::tsc;
use crate::jsr::JsrFetchResolver;
use crate::lsp::registries::DocumentationCompletionItemData;
use crate::lsp::tsgo;
use crate::util::env::resolve_cwd;
use crate::util::path::is_importable_ext;
use crate::util::path::relative_specifier;

Expand Down Expand Up @@ -434,7 +435,7 @@ fn get_local_completions(
.ok()?;
let resolved_parent_path = url_to_file_path(&resolved_parent).ok()?;
if resolved_parent_path.is_dir() {
let cwd = std::env::current_dir().ok()?;
let cwd = resolve_cwd(None).ok()?;
let entries = std::fs::read_dir(resolved_parent_path).ok()?;
let items = entries
.filter_map(|de| {
Expand Down
3 changes: 2 additions & 1 deletion cli/lsp/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use crate::http_util::HttpClientProvider;
use crate::lsp::logging::lsp_warn;
use crate::npm::CliNpmCacheHttpClient;
use crate::sys::CliSys;
use crate::util::fs::canonicalize_path;
use crate::util::fs::canonicalize_path_maybe_not_exists;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
Expand Down Expand Up @@ -1845,7 +1846,7 @@ impl ConfigTree {
let pkg_json_cache = PackageJsonMemCache::default();
let workspace_cache = WorkspaceMemCache::default();
let mut scopes = BTreeMap::new();
let fs_root_url = std::fs::canonicalize("/")
let fs_root_url = canonicalize_path(Path::new("/"))
.ok()
.and_then(|p| Url::from_directory_path(p).ok())
.unwrap_or_else(|| Url::parse("file:///").unwrap());
Expand Down
7 changes: 3 additions & 4 deletions cli/lsp/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ use crate::tools::fmt::format_file;
use crate::tools::fmt::format_parsed_source;
use crate::tools::upgrade::check_for_upgrades_for_lsp;
use crate::tools::upgrade::upgrade_check_enabled;
use crate::util::env::resolve_cwd;
use crate::util::fs::remove_dir_all_if_exists;
use crate::util::path::to_percent_decoded_str;
use crate::util::sync::AsyncFlag;
Expand Down Expand Up @@ -584,9 +585,7 @@ impl Inner {
cache.deno_dir(),
&http_client_provider,
));
let initial_cwd = std::env::current_dir().unwrap_or_else(|_| {
panic!("Could not resolve current working directory")
});
let initial_cwd = resolve_cwd(None).unwrap().into_owned();

Self {
ambient_modules_regex_cache: Default::default(),
Expand Down Expand Up @@ -3987,7 +3986,7 @@ struct PrepareCacheResult {
impl Inner {
async fn initialized(&mut self) -> Vec<Registration> {
let mut registrations = Vec::with_capacity(2);
init_log_file(self.config.log_file());
init_log_file(self.config.log_file(), &self.initial_cwd);
self.update_debug_flag();
self.update_global_cache().await;
self.refresh_workspace_files();
Expand Down
3 changes: 1 addition & 2 deletions cli/lsp/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ impl LogFile {
}
}

pub fn init_log_file(enabled: bool) {
pub fn init_log_file(enabled: bool, cwd: &Path) {
let prepare_path = || {
if !enabled {
return None;
}
let cwd = std::env::current_dir().ok()?;
let now = SystemTime::now();
let now: DateTime<Utc> = now.into();
let now = now.to_rfc3339().replace(':', "_");
Expand Down
1 change: 1 addition & 0 deletions cli/lsp/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ fn lsp_range_to_std_range(
}

fn get_cwd_uri() -> Result<ModuleSpecifier, AnyError> {
#[allow(clippy::disallowed_methods)] // ok, used for initialization
let cwd = std::env::current_dir()?;
ModuleSpecifier::from_directory_path(&cwd)
.map_err(|_| anyhow!("Could not get URI from {}", cwd.display()))
Expand Down
1 change: 1 addition & 0 deletions cli/module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,7 @@ impl<TGraphContainer: ModuleGraphContainer>
deno_path_util::resolve_path(referrer, &self.shared.initial_cwd)?
} else {
// this cwd check is slow, so try to avoid it
#[allow(clippy::disallowed_methods)] // ok, actually needs the current cwd
let cwd = std::env::current_dir().map_err(UnableToGetCwdError)?;
deno_path_util::resolve_path(referrer, &cwd)?
})
Expand Down
1 change: 1 addition & 0 deletions cli/ops/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ fn op_lint_create_serialized_ast(
#[string] source: String,
) -> Result<Uint8Array, LintError> {
let file_text = deno_ast::strip_bom(source);
#[allow(clippy::disallowed_methods)] // allow a cwd lookup here
let path = std::env::current_dir()?.join(file_name);
let specifier = ModuleSpecifier::from_file_path(&path)
.map_err(|_| LintError::PathParse(path))?;
Expand Down
4 changes: 3 additions & 1 deletion cli/rt/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ impl ModuleLoader for EmbeddedModuleLoader {
_kind: ResolutionKind,
) -> Result<Url, ModuleLoaderError> {
let referrer = if referrer == "." {
let current_dir = std::env::current_dir().unwrap();
#[allow(clippy::disallowed_methods)] // ok to use current_dir here
let current_dir =
std::env::current_dir().map_err(JsErrorBox::from_err)?;
deno_core::resolve_path(".", &current_dir)
.map_err(JsErrorBox::from_err)?
} else {
Expand Down
9 changes: 5 additions & 4 deletions cli/task_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use tokio_util::sync::CancellationToken;
use crate::node::CliNodeResolver;
use crate::npm::CliManagedNpmResolver;
use crate::npm::CliNpmResolver;
use crate::util::fs::canonicalize_path;

pub fn get_script_with_args(script: &str, argv: &[String]) -> String {
let additional_args = argv
Expand Down Expand Up @@ -246,7 +247,7 @@ impl ShellCommand for NpmCommand {
return ExecutableCommand::new(
"deno".to_string(),
std::env::current_exe()
.and_then(|p| p.canonicalize())
.and_then(|p| canonicalize_path(&p))
.unwrap(),
)
.execute(ShellCommandContext {
Expand Down Expand Up @@ -277,7 +278,7 @@ impl Default for DenoCommand {
Self(ExecutableCommand::new(
"deno".to_string(),
std::env::current_exe()
.and_then(|p| p.canonicalize())
.and_then(|p| canonicalize_path(&p))
.unwrap(),
))
}
Expand Down Expand Up @@ -330,7 +331,7 @@ impl ShellCommand for NodeCommand {
ExecutableCommand::new(
"deno".to_string(),
std::env::current_exe()
.and_then(|p| p.canonicalize())
.and_then(|p| canonicalize_path(&p))
.unwrap(),
)
.execute(ShellCommandContext {
Expand Down Expand Up @@ -430,7 +431,7 @@ impl ShellCommand for NodeModulesFileRunCommand {
let executable_command = deno_task_shell::ExecutableCommand::new(
"deno".to_string(),
std::env::current_exe()
.and_then(|p| p.canonicalize())
.and_then(|p| canonicalize_path(&p))
.unwrap(),
);
// set this environment variable so that the launched process knows the npm command name
Expand Down
7 changes: 4 additions & 3 deletions cli/tools/bundle/externals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ mod tests {
use std::path::Path;

use super::ExternalsMatcher;
use crate::util::env::resolve_cwd;

struct Matches {
pre_resolve: Vec<String>,
Expand All @@ -147,7 +148,7 @@ mod tests {
.into_iter()
.map(|p| p.as_ref().to_string())
.collect::<Vec<_>>();
let cwd = std::env::current_dir().unwrap();
let cwd = resolve_cwd(None).unwrap();
let matcher = ExternalsMatcher::new(&patterns, &cwd);
for path in matches.pre_resolve {
if !matcher.is_pre_resolve_match(&path) {
Expand Down Expand Up @@ -213,7 +214,7 @@ mod tests {
["/node_modules/foo"]
));

let cwd = std::env::current_dir().unwrap();
let cwd = resolve_cwd(None).unwrap();
assert!(matches_all(
["./foo"],
Matches {
Expand Down Expand Up @@ -242,7 +243,7 @@ mod tests {
},
["other/@std/fs", "./@std/fs/foo.ts", "./@std/fs"]
));
let cwd = std::env::current_dir().unwrap();
let cwd = resolve_cwd(None).unwrap();
assert!(matches_all(
["./foo/*"],
Matches {
Expand Down
Loading