0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-01 12:16:11 -05:00

Merge remote-tracking branch 'upstream/main' into check-workspace-member-compiler-options

This commit is contained in:
Nayeem Rahman 2024-12-19 01:47:38 +00:00
commit 1c2fb5cde1
44 changed files with 571 additions and 131 deletions

34
Cargo.lock generated
View file

@ -380,7 +380,7 @@ dependencies = [
"rustversion",
"serde",
"sync_wrapper",
"tower",
"tower 0.4.13",
"tower-layer",
"tower-service",
]
@ -1650,6 +1650,7 @@ dependencies = [
"dyn-clone",
"error_reporter",
"fast-socks5",
"h2 0.4.4",
"hickory-resolver",
"http 1.1.0",
"http-body-util",
@ -1666,7 +1667,7 @@ dependencies = [
"tokio-rustls",
"tokio-socks",
"tokio-util",
"tower",
"tower 0.5.2",
"tower-http",
"tower-service",
]
@ -1924,7 +1925,7 @@ dependencies = [
[[package]]
name = "deno_node"
version = "0.120.0"
version = "0.121.0"
dependencies = [
"aead-gcm-stream",
"aes",
@ -2321,7 +2322,7 @@ dependencies = [
"serde_json",
"tokio",
"tokio-util",
"tower",
"tower 0.4.13",
"tracing",
]
@ -4551,9 +4552,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.153"
version = "0.2.168"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
[[package]]
name = "libffi"
@ -7975,7 +7976,7 @@ dependencies = [
"socket2",
"tokio",
"tokio-stream",
"tower",
"tower 0.4.13",
"tower-layer",
"tower-service",
"tracing",
@ -8001,6 +8002,21 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.1"
@ -8029,9 +8045,9 @@ checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"

View file

@ -84,7 +84,7 @@ deno_io = { version = "0.93.0", path = "./ext/io" }
deno_kv = { version = "0.91.0", path = "./ext/kv" }
deno_napi = { version = "0.114.0", path = "./ext/napi" }
deno_net = { version = "0.175.0", path = "./ext/net" }
deno_node = { version = "0.120.0", path = "./ext/node" }
deno_node = { version = "0.121.0", path = "./ext/node" }
deno_telemetry = { version = "0.5.0", path = "./ext/telemetry" }
deno_tls = { version = "0.170.0", path = "./ext/tls" }
deno_url = { version = "0.183.0", path = "./ext/url" }
@ -150,7 +150,7 @@ indexmap = { version = "2", features = ["serde"] }
ipnet = "2.3"
jsonc-parser = { version = "=0.26.2", features = ["serde"] }
lazy-regex = "3"
libc = "0.2.126"
libc = "0.2.168"
libz-sys = { version = "1.1.20", default-features = false }
log = { version = "0.4.20", features = ["kv"] }
lsp-types = "=0.97.0" # used by tower-lsp and "proposed" feature is unstable in patch releases
@ -203,7 +203,7 @@ tokio-metrics = { version = "0.3.0", features = ["rt"] }
tokio-rustls = { version = "0.26.0", default-features = false, features = ["ring", "tls12"] }
tokio-socks = "0.5.1"
tokio-util = "0.7.4"
tower = { version = "0.4.13", default-features = false, features = ["util"] }
tower = { version = "0.5.2", default-features = false, features = ["retry", "util"] }
tower-http = { version = "0.6.1", features = ["decompression-br", "decompression-gzip"] }
tower-lsp = { package = "deno_tower_lsp", version = "0.1.0", features = ["proposed"] }
tower-service = "0.3.2"

View file

@ -145,9 +145,7 @@ impl HttpClient {
}
pub fn get(&self, url: Url) -> Result<RequestBuilder, http::Error> {
let body = http_body_util::Empty::new()
.map_err(|never| match never {})
.boxed();
let body = deno_fetch::ReqBody::empty();
let mut req = http::Request::new(body);
*req.uri_mut() = url.as_str().parse()?;
Ok(RequestBuilder {
@ -179,9 +177,7 @@ impl HttpClient {
S: serde::Serialize,
{
let json = deno_core::serde_json::to_vec(ser)?;
let body = http_body_util::Full::new(json.into())
.map_err(|never| match never {})
.boxed();
let body = deno_fetch::ReqBody::full(json.into());
let builder = self.post(url, body)?;
Ok(builder.header(
http::header::CONTENT_TYPE,
@ -194,9 +190,7 @@ impl HttpClient {
url: &Url,
headers: HeaderMap,
) -> Result<http::Response<ResBody>, SendError> {
let body = http_body_util::Empty::new()
.map_err(|never| match never {})
.boxed();
let body = deno_fetch::ReqBody::empty();
let mut request = http::Request::new(body);
*request.uri_mut() = http::Uri::try_from(url.as_str())?;
*request.headers_mut() = headers;

View file

@ -26,6 +26,7 @@ use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::url::Url;
use deno_runtime::deno_fetch;
use deno_terminal::colors;
use http_body_util::BodyExt;
use serde::Deserialize;
@ -911,9 +912,7 @@ async fn publish_package(
package.config
);
let body = http_body_util::Full::new(package.tarball.bytes.clone())
.map_err(|never| match never {})
.boxed();
let body = deno_fetch::ReqBody::full(package.tarball.bytes.clone());
let response = http_client
.post(url.parse()?, body)?
.header(

View file

@ -3,7 +3,6 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use deno_ast::ModuleSpecifier;
@ -28,6 +27,7 @@ use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use deno_semver::package::PackageReqReference;
use deno_semver::Version;
use deno_semver::VersionReq;
use import_map::ImportMap;
use import_map::ImportMapWithDiagnostics;
@ -42,6 +42,7 @@ use crate::jsr::JsrFetchResolver;
use crate::module_loader::ModuleLoadPreparer;
use crate::npm::CliNpmResolver;
use crate::npm::NpmFetchResolver;
use crate::util::sync::AtomicFlag;
use super::ConfigUpdater;
@ -447,7 +448,7 @@ pub struct DepManager {
pending_changes: Vec<Change>,
dependencies_resolved: AtomicBool,
dependencies_resolved: AtomicFlag,
module_load_preparer: Arc<ModuleLoadPreparer>,
// TODO(nathanwhit): probably shouldn't be pub
pub(crate) jsr_fetch_resolver: Arc<JsrFetchResolver>,
@ -489,7 +490,7 @@ impl DepManager {
resolved_versions: Vec::new(),
latest_versions: Vec::new(),
jsr_fetch_resolver,
dependencies_resolved: AtomicBool::new(false),
dependencies_resolved: AtomicFlag::lowered(),
module_load_preparer,
npm_fetch_resolver,
npm_resolver,
@ -530,10 +531,7 @@ impl DepManager {
}
async fn run_dependency_resolution(&self) -> Result<(), AnyError> {
if self
.dependencies_resolved
.load(std::sync::atomic::Ordering::Relaxed)
{
if self.dependencies_resolved.is_raised() {
return Ok(());
}
@ -556,9 +554,7 @@ impl DepManager {
}
DepKind::Jsr => graph.packages.mappings().contains_key(&dep.req),
}) {
self
.dependencies_resolved
.store(true, std::sync::atomic::Ordering::Relaxed);
self.dependencies_resolved.raise();
graph_permit.commit();
return Ok(());
}
@ -613,6 +609,7 @@ impl DepManager {
)
.await?;
self.dependencies_resolved.raise();
graph_permit.commit();
Ok(())
@ -655,10 +652,6 @@ impl DepManager {
if self.latest_versions.len() == self.deps.len() {
return Ok(self.latest_versions.clone());
}
let latest_tag_req = deno_semver::VersionReq::from_raw_text_and_inner(
"latest".into(),
deno_semver::RangeSetOrTag::Tag("latest".into()),
);
let mut latest_versions = Vec::with_capacity(self.deps.len());
let npm_sema = Semaphore::new(32);
@ -670,14 +663,25 @@ impl DepManager {
DepKind::Npm => futs.push_back(
async {
let semver_req = &dep.req;
let latest_req = PackageReq {
name: dep.req.name.clone(),
version_req: latest_tag_req.clone(),
};
let _permit = npm_sema.acquire().await;
let semver_compatible =
self.npm_fetch_resolver.req_to_nv(semver_req).await;
let latest = self.npm_fetch_resolver.req_to_nv(&latest_req).await;
let info =
self.npm_fetch_resolver.package_info(&semver_req.name).await;
let latest = info
.and_then(|info| {
let latest_tag = info.dist_tags.get("latest")?;
let lower_bound = &semver_compatible.as_ref()?.version;
if latest_tag > lower_bound {
Some(latest_tag.clone())
} else {
latest_version(Some(latest_tag), info.versions.keys())
}
})
.map(|version| PackageNv {
name: semver_req.name.clone(),
version,
});
PackageLatestVersion {
latest,
semver_compatible,
@ -688,14 +692,29 @@ impl DepManager {
DepKind::Jsr => futs.push_back(
async {
let semver_req = &dep.req;
let latest_req = PackageReq {
name: dep.req.name.clone(),
version_req: deno_semver::WILDCARD_VERSION_REQ.clone(),
};
let _permit = jsr_sema.acquire().await;
let semver_compatible =
self.jsr_fetch_resolver.req_to_nv(semver_req).await;
let latest = self.jsr_fetch_resolver.req_to_nv(&latest_req).await;
let info =
self.jsr_fetch_resolver.package_info(&semver_req.name).await;
let latest = info
.and_then(|info| {
let lower_bound = &semver_compatible.as_ref()?.version;
latest_version(
Some(lower_bound),
info.versions.iter().filter_map(|(version, version_info)| {
if !version_info.yanked {
Some(version)
} else {
None
}
}),
)
})
.map(|version| PackageNv {
name: semver_req.name.clone(),
version,
});
PackageLatestVersion {
latest,
semver_compatible,
@ -893,3 +912,18 @@ fn parse_req_reference(
DepKind::Jsr => JsrPackageReqReference::from_str(input)?.into_inner(),
})
}
fn latest_version<'a>(
start: Option<&Version>,
versions: impl IntoIterator<Item = &'a Version>,
) -> Option<Version> {
let mut best = start;
for version in versions {
match best {
Some(best_version) if version > best_version => best = Some(version),
None => best = Some(version),
_ => {}
}
}
best.cloned()
}

View file

@ -94,7 +94,7 @@ pub async fn execute_script(
return Ok(0);
};
let task_regex = arg_to_regex(task_name)?;
let task_name_filter = arg_to_task_name_filter(task_name)?;
let mut packages_task_info: Vec<PackageTaskInfo> = vec![];
for folder in workspace.config_folders() {
@ -137,12 +137,20 @@ pub async fn execute_script(
// Match tasks in deno.json
for name in tasks_config.task_names() {
if task_regex.is_match(name) && !visited.contains(name) {
let matches_filter = match &task_name_filter {
TaskNameFilter::Exact(n) => *n == name,
TaskNameFilter::Regex(re) => re.is_match(name),
};
if matches_filter && !visited.contains(name) {
matched.insert(name.to_string());
visit_task(&tasks_config, &mut visited, name);
}
}
if matched.is_empty() {
continue;
}
packages_task_info.push(PackageTaskInfo {
matched_tasks: matched
.iter()
@ -902,3 +910,41 @@ fn strip_ansi_codes_and_escape_control_chars(s: &str) -> String {
})
.collect()
}
fn arg_to_task_name_filter(input: &str) -> Result<TaskNameFilter, AnyError> {
if !input.contains("*") {
return Ok(TaskNameFilter::Exact(input));
}
let mut regex_str = regex::escape(input);
regex_str = regex_str.replace("\\*", ".*");
let re = Regex::new(&regex_str)?;
Ok(TaskNameFilter::Regex(re))
}
#[derive(Debug)]
enum TaskNameFilter<'s> {
Exact(&'s str),
Regex(regex::Regex),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_arg_to_task_name_filter() {
assert!(matches!(
arg_to_task_name_filter("test").unwrap(),
TaskNameFilter::Exact("test")
));
assert!(matches!(
arg_to_task_name_filter("test-").unwrap(),
TaskNameFilter::Exact("test-")
));
assert!(matches!(
arg_to_task_name_filter("test*").unwrap(),
TaskNameFilter::Regex(_)
));
}
}

View file

@ -23,6 +23,7 @@ deno_permissions.workspace = true
deno_tls.workspace = true
dyn-clone = "1"
error_reporter = "1"
h2.workspace = true
hickory-resolver.workspace = true
http.workspace = true
http-body-util.workspace = true

View file

@ -10,6 +10,7 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::cmp::min;
use std::convert::From;
use std::future;
use std::path::Path;
use std::path::PathBuf;
use std::pin::Pin;
@ -66,6 +67,7 @@ use http::header::USER_AGENT;
use http::Extensions;
use http::Method;
use http::Uri;
use http_body_util::combinators::BoxBody;
use http_body_util::BodyExt;
use hyper::body::Frame;
use hyper_util::client::legacy::connect::HttpConnector;
@ -75,6 +77,7 @@ use hyper_util::rt::TokioExecutor;
use hyper_util::rt::TokioTimer;
use serde::Deserialize;
use serde::Serialize;
use tower::retry;
use tower::ServiceExt;
use tower_http::decompression::Decompression;
@ -476,9 +479,7 @@ where
// If a body is passed, we use it, and don't return a body for streaming.
con_len = Some(data.len() as u64);
http_body_util::Full::new(data.to_vec().into())
.map_err(|never| match never {})
.boxed()
ReqBody::full(data.to_vec().into())
}
(_, Some(resource)) => {
let resource = state
@ -491,7 +492,7 @@ where
}
_ => {}
}
ReqBody::new(ResourceToBodyAdapter::new(resource))
ReqBody::streaming(ResourceToBodyAdapter::new(resource))
}
(None, None) => unreachable!(),
}
@ -501,9 +502,7 @@ where
if matches!(method, Method::POST | Method::PUT) {
con_len = Some(0);
}
http_body_util::Empty::new()
.map_err(|never| match never {})
.boxed()
ReqBody::empty()
};
let mut request = http::Request::new(body);
@ -1066,7 +1065,8 @@ pub fn create_http_client(
}
let pooled_client = builder.build(connector);
let decompress = Decompression::new(pooled_client).gzip(true).br(true);
let retry_client = retry::Retry::new(FetchRetry, pooled_client);
let decompress = Decompression::new(retry_client).gzip(true).br(true);
Ok(Client {
inner: decompress,
@ -1083,7 +1083,12 @@ pub fn op_utf8_to_byte_string(#[string] input: String) -> ByteString {
#[derive(Clone, Debug)]
pub struct Client {
inner: Decompression<hyper_util::client::legacy::Client<Connector, ReqBody>>,
inner: Decompression<
retry::Retry<
FetchRetry,
hyper_util::client::legacy::Client<Connector, ReqBody>,
>,
>,
// Used to check whether to include a proxy-authorization header
proxies: Arc<proxy::Proxies>,
user_agent: HeaderValue,
@ -1174,10 +1179,70 @@ impl Client {
}
}
pub type ReqBody =
http_body_util::combinators::BoxBody<Bytes, deno_core::error::AnyError>;
pub type ResBody =
http_body_util::combinators::BoxBody<Bytes, deno_core::error::AnyError>;
// This is a custom enum to allow the retry policy to clone the variants that could be retried.
pub enum ReqBody {
Full(http_body_util::Full<Bytes>),
Empty(http_body_util::Empty<Bytes>),
Streaming(BoxBody<Bytes, deno_core::error::AnyError>),
}
pub type ResBody = BoxBody<Bytes, deno_core::error::AnyError>;
impl ReqBody {
pub fn full(bytes: Bytes) -> Self {
ReqBody::Full(http_body_util::Full::new(bytes))
}
pub fn empty() -> Self {
ReqBody::Empty(http_body_util::Empty::new())
}
pub fn streaming<B>(body: B) -> Self
where
B: hyper::body::Body<Data = Bytes, Error = deno_core::error::AnyError>
+ Send
+ Sync
+ 'static,
{
ReqBody::Streaming(BoxBody::new(body))
}
}
impl hyper::body::Body for ReqBody {
type Data = Bytes;
type Error = deno_core::error::AnyError;
fn poll_frame(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
match &mut *self {
ReqBody::Full(ref mut b) => {
Pin::new(b).poll_frame(cx).map_err(|never| match never {})
}
ReqBody::Empty(ref mut b) => {
Pin::new(b).poll_frame(cx).map_err(|never| match never {})
}
ReqBody::Streaming(ref mut b) => Pin::new(b).poll_frame(cx),
}
}
fn is_end_stream(&self) -> bool {
match self {
ReqBody::Full(ref b) => b.is_end_stream(),
ReqBody::Empty(ref b) => b.is_end_stream(),
ReqBody::Streaming(ref b) => b.is_end_stream(),
}
}
fn size_hint(&self) -> hyper::body::SizeHint {
match self {
ReqBody::Full(ref b) => b.size_hint(),
ReqBody::Empty(ref b) => b.size_hint(),
ReqBody::Streaming(ref b) => b.size_hint(),
}
}
}
/// Copied from https://github.com/seanmonstar/reqwest/blob/b9d62a0323d96f11672a61a17bf8849baec00275/src/async_impl/request.rs#L572
/// Check the request URL for a "username:password" type authority, and if
@ -1214,3 +1279,102 @@ pub fn extract_authority(url: &mut Url) -> Option<(String, Option<String>)> {
fn op_fetch_promise_is_settled(promise: v8::Local<v8::Promise>) -> bool {
promise.state() != v8::PromiseState::Pending
}
/// Deno.fetch's retry policy.
#[derive(Clone, Debug)]
struct FetchRetry;
/// Marker extension that a request has been retried once.
#[derive(Clone, Debug)]
struct Retried;
impl<ResBody, E>
retry::Policy<http::Request<ReqBody>, http::Response<ResBody>, E>
for FetchRetry
where
E: std::error::Error + 'static,
{
/// Don't delay retries.
type Future = future::Ready<()>;
fn retry(
&mut self,
req: &mut http::Request<ReqBody>,
result: &mut Result<http::Response<ResBody>, E>,
) -> Option<Self::Future> {
if req.extensions().get::<Retried>().is_some() {
// only retry once
return None;
}
match result {
Ok(..) => {
// never retry a Response
None
}
Err(err) => {
if is_error_retryable(&*err) {
req.extensions_mut().insert(Retried);
Some(future::ready(()))
} else {
None
}
}
}
}
fn clone_request(
&mut self,
req: &http::Request<ReqBody>,
) -> Option<http::Request<ReqBody>> {
let body = match req.body() {
ReqBody::Full(b) => ReqBody::Full(b.clone()),
ReqBody::Empty(b) => ReqBody::Empty(*b),
ReqBody::Streaming(..) => return None,
};
let mut clone = http::Request::new(body);
*clone.method_mut() = req.method().clone();
*clone.uri_mut() = req.uri().clone();
*clone.headers_mut() = req.headers().clone();
*clone.extensions_mut() = req.extensions().clone();
Some(clone)
}
}
fn is_error_retryable(err: &(dyn std::error::Error + 'static)) -> bool {
// Note: hyper doesn't promise it will always be this h2 version. Keep up to date.
if let Some(err) = find_source::<h2::Error>(err) {
// They sent us a graceful shutdown, try with a new connection!
if err.is_go_away()
&& err.is_remote()
&& err.reason() == Some(h2::Reason::NO_ERROR)
{
return true;
}
// REFUSED_STREAM was sent from the server, which is safe to retry.
// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.7-3.2
if err.is_reset()
&& err.is_remote()
&& err.reason() == Some(h2::Reason::REFUSED_STREAM)
{
return true;
}
}
false
}
fn find_source<'a, E: std::error::Error + 'static>(
err: &'a (dyn std::error::Error + 'static),
) -> Option<&'a E> {
let mut err = Some(err);
while let Some(src) = err {
if let Some(found) = src.downcast_ref::<E>() {
return Some(found);
}
err = src.source();
}
None
}

View file

@ -133,11 +133,7 @@ async fn rust_test_client_with_resolver(
let req = http::Request::builder()
.uri(format!("https://{}/foo", src_addr))
.body(
http_body_util::Empty::new()
.map_err(|err| match err {})
.boxed(),
)
.body(crate::ReqBody::empty())
.unwrap();
let resp = client.send(req).await.unwrap();
assert_eq!(resp.status(), http::StatusCode::OK);

View file

@ -122,9 +122,7 @@ impl RemoteTransport for FetchClient {
headers: http::HeaderMap,
body: Bytes,
) -> Result<(Url, http::StatusCode, Self::Response), anyhow::Error> {
let body = http_body_util::Full::new(body)
.map_err(|never| match never {})
.boxed();
let body = deno_fetch::ReqBody::full(body);
let mut req = http::Request::new(body);
*req.method_mut() = http::Method::POST;
*req.uri_mut() = url.as_str().parse()?;

View file

@ -2,7 +2,7 @@
[package]
name = "deno_node"
version = "0.120.0"
version = "0.121.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -73,12 +73,17 @@ pub fn cpu_info() -> Option<Vec<CpuInfo>> {
cpu_speed = 2_400_000_000;
}
extern "C" {
fn mach_host_self() -> std::ffi::c_uint;
static mut mach_task_self_: std::ffi::c_uint;
}
let mut num_cpus: libc::natural_t = 0;
let mut info: *mut libc::processor_cpu_load_info_data_t =
std::ptr::null_mut();
let mut msg_type: libc::mach_msg_type_number_t = 0;
if libc::host_processor_info(
libc::mach_host_self(),
mach_host_self(),
libc::PROCESSOR_CPU_LOAD_INFO,
&mut num_cpus,
&mut info as *mut _ as *mut libc::processor_info_array_t,
@ -111,7 +116,7 @@ pub fn cpu_info() -> Option<Vec<CpuInfo>> {
}
libc::vm_deallocate(
libc::mach_task_self(),
mach_task_self_,
info.as_ptr() as libc::vm_address_t,
msg_type as _,
);

View file

@ -67,9 +67,9 @@ generate_builtin_node_module_lists! {
"process",
"punycode",
"querystring",
"repl",
"readline",
"readline/promises",
"repl",
"stream",
"stream/consumers",
"stream/promises",
@ -90,3 +90,10 @@ generate_builtin_node_module_lists! {
"worker_threads",
"zlib",
}
#[test]
fn test_builtins_are_sorted() {
let mut builtins_list = SUPPORTED_BUILTIN_NODE_MODULES.to_vec();
builtins_list.sort();
assert_eq!(SUPPORTED_BUILTIN_NODE_MODULES, builtins_list);
}

View file

@ -30,50 +30,58 @@ export function access(
mode = getValidMode(mode, "access");
const cb = makeCallback(callback);
Deno.lstat(path).then((info) => {
if (info.mode === null) {
// If the file mode is unavailable, we pretend it has
// the permission
cb(null);
return;
}
const m = +mode || 0;
let fileMode = +info.mode || 0;
if (Deno.build.os !== "windows" && info.uid === Deno.uid()) {
// If the user is the owner of the file, then use the owner bits of
// the file permission
fileMode >>= 6;
}
// TODO(kt3k): Also check the case when the user belong to the group
// of the file
if ((m & fileMode) === m) {
// all required flags exist
cb(null);
} else {
// some required flags don't
// deno-lint-ignore no-explicit-any
const e: any = new Error(`EACCES: permission denied, access '${path}'`);
e.path = path;
e.syscall = "access";
e.errno = codeMap.get("EACCES");
e.code = "EACCES";
cb(e);
}
}, (err) => {
if (err instanceof Deno.errors.NotFound) {
// deno-lint-ignore no-explicit-any
const e: any = new Error(
`ENOENT: no such file or directory, access '${path}'`,
);
e.path = path;
e.syscall = "access";
e.errno = codeMap.get("ENOENT");
e.code = "ENOENT";
cb(e);
} else {
cb(err);
}
});
Deno.lstat(path).then(
(info) => {
if (info.mode === null) {
// If the file mode is unavailable, we pretend it has
// the permission
cb(null);
return;
}
let m = +mode || 0;
let fileMode = +info.mode || 0;
if (Deno.build.os === "windows") {
m &= ~fs.X_OK; // Ignore the X_OK bit on Windows
} else if (info.uid === Deno.uid()) {
// If the user is the owner of the file, then use the owner bits of
// the file permission
fileMode >>= 6;
}
// TODO(kt3k): Also check the case when the user belong to the group
// of the file
if ((m & fileMode) === m) {
// all required flags exist
cb(null);
} else {
// some required flags don't
// deno-lint-ignore no-explicit-any
const e: any = new Error(`EACCES: permission denied, access '${path}'`);
e.path = path;
e.syscall = "access";
e.errno = codeMap.get("EACCES");
e.code = "EACCES";
cb(e);
}
},
(err) => {
if (err instanceof Deno.errors.NotFound) {
// deno-lint-ignore no-explicit-any
const e: any = new Error(
`ENOENT: no such file or directory, access '${path}'`,
);
e.path = path;
e.syscall = "access";
e.errno = codeMap.get("ENOENT");
e.code = "ENOENT";
cb(e);
} else {
cb(err);
}
},
);
}
export const accessPromise = promisify(access) as (
@ -91,9 +99,11 @@ export function accessSync(path: string | Buffer | URL, mode?: number) {
// the permission
return;
}
const m = +mode! || 0;
let m = +mode! || 0;
let fileMode = +info.mode! || 0;
if (Deno.build.os !== "windows" && info.uid === Deno.uid()) {
if (Deno.build.os === "windows") {
m &= ~fs.X_OK; // Ignore the X_OK bit on Windows
} else if (info.uid === Deno.uid()) {
// If the user is the owner of the file, then use the owner bits of
// the file permission
fileMode >>= 6;

View file

@ -424,8 +424,11 @@ fn rss() -> usize {
let mut count = libc::MACH_TASK_BASIC_INFO_COUNT;
// SAFETY: libc calls
let r = unsafe {
extern "C" {
static mut mach_task_self_: std::ffi::c_uint;
}
libc::task_info(
libc::mach_task_self(),
mach_task_self_,
libc::MACH_TASK_BASIC_INFO,
task_info.as_mut_ptr() as libc::task_info_t,
&mut count as *mut libc::mach_msg_type_number_t,

View file

@ -104,11 +104,7 @@ pub fn op_worker_sync_fetch(
let (body, mime_type, res_url) = match script_url.scheme() {
"http" | "https" => {
let mut req = http::Request::new(
http_body_util::Empty::new()
.map_err(|never| match never {})
.boxed(),
);
let mut req = http::Request::new(deno_fetch::ReqBody::empty());
*req.uri_mut() = script_url.as_str().parse()?;
let resp =

View file

@ -278,11 +278,15 @@ pub fn mem_info() -> Option<MemInfo> {
mem_info.swap_total = xs.xsu_total;
mem_info.swap_free = xs.xsu_avail;
extern "C" {
fn mach_host_self() -> std::ffi::c_uint;
}
let mut count: u32 = libc::HOST_VM_INFO64_COUNT as _;
let mut stat = std::mem::zeroed::<libc::vm_statistics64>();
if libc::host_statistics64(
// TODO(@littledivy): Put this in a once_cell.
libc::mach_host_self(),
mach_host_self(),
libc::HOST_VM_INFO64,
&mut stat as *mut libc::vm_statistics64 as *mut _,
&mut count,

View file

@ -8609,9 +8609,9 @@ fn lsp_completions_node_specifier() {
"node:process",
"node:punycode",
"node:querystring",
"node:repl",
"node:readline",
"node:readline/promises",
"node:repl",
"node:stream",
"node:stream/consumers",
"node:stream/promises",

View file

@ -0,0 +1 @@
export const foo = 1;

View file

@ -0,0 +1,5 @@
{
"exports": {
".": "mod.ts"
}
}

View file

@ -0,0 +1 @@
export const foo = 1;

View file

@ -0,0 +1,5 @@
{
"exports": {
".": "mod.ts"
}
}

View file

@ -0,0 +1,6 @@
{
"versions": {
"2.0.0-beta.1": {},
"2.0.0-beta.2": {}
}
}

View file

@ -0,0 +1 @@
export const foo = 1;

View file

@ -0,0 +1,3 @@
{
"exports": {}
}

View file

@ -0,0 +1 @@
export const foo = 1;

View file

@ -0,0 +1,5 @@
{
"exports": {
".": "mod.ts"
}
}

View file

@ -0,0 +1 @@
export const foo = 1;

View file

@ -0,0 +1,5 @@
{
"exports": {
".": "mod.ts"
}
}

View file

@ -0,0 +1,7 @@
{
"versions": {
"1.0.0": {},
"2.0.0-beta.1": {},
"2.0.0-beta.2": {}
}
}

View file

@ -0,0 +1,7 @@
{
"name": "@denotest/has-pre-release",
"version": "1.0.0",
"publishConfig": {
"tag": "latest"
}
}

View file

@ -0,0 +1,4 @@
{
"name": "@denotest/has-pre-release",
"version": "2.0.0-beta.1"
}

View file

@ -0,0 +1,4 @@
{
"name": "@denotest/has-pre-release",
"version": "2.0.0-beta.2"
}

View file

@ -0,0 +1,11 @@
{
"tempDir": true,
"tests": {
// Regression test for https://github.com/denoland/deno/issues/27370
"root": {
"args": "task test-all",
"output": "root.out",
"exitCode": 0
}
}
}

View file

@ -0,0 +1,6 @@
{
"workspace": ["./subdir"],
"tasks": {
"test-all": "deno task --recursive test"
}
}

View file

@ -0,0 +1,3 @@
Task test-all deno task --recursive test
Task test echo 'ok'
ok

View file

@ -0,0 +1,5 @@
{
"tasks": {
"test": "echo 'ok'"
}
}

View file

@ -0,0 +1,21 @@
{
"tempDir": true,
"steps": [
{
"args": "i",
"output": "[WILDCARD]"
},
{
"args": "outdated",
"output": "outdated.out"
},
{
"args": "outdated --compatible",
"output": "outdated.out"
},
{
"args": "outdated --update --latest",
"output": "update.out"
}
]
}

View file

@ -0,0 +1,7 @@
{
"imports": {
"@denotest/npm-has-pre-release": "npm:@denotest/has-pre-release@^2.0.0-beta.1",
"@denotest/jsr-has-pre-release": "jsr:@denotest/has-pre-release@^2.0.0-beta.1",
"@denotest/has-only-pre-release": "jsr:@denotest/has-only-pre-release@^2.0.0-beta.1"
}
}

28
tests/specs/update/pre_release/deno.lock generated Normal file
View file

@ -0,0 +1,28 @@
{
"version": "4",
"specifiers": {
"jsr:@denotest/has-only-pre-release@^2.0.0-beta.1": "2.0.0-beta.1",
"jsr:@denotest/has-pre-release@^2.0.0-beta.1": "2.0.0-beta.1",
"npm:@denotest/has-pre-release@^2.0.0-beta.1": "2.0.0-beta.1"
},
"jsr": {
"@denotest/has-only-pre-release@2.0.0-beta.1": {
"integrity": "43fd680ea94bb5db5fe1a2d86101c47d0e2cc77323b881755cea9a0372e49537"
},
"@denotest/has-pre-release@2.0.0-beta.1": {
"integrity": "43fd680ea94bb5db5fe1a2d86101c47d0e2cc77323b881755cea9a0372e49537"
}
},
"npm": {
"@denotest/has-pre-release@2.0.0-beta.1": {
"integrity": "sha512-K1fHe1L2EUSLgijtzzALNpkkIO0SrX3z+IXvVjjOIE8HKd4T7lkpzDdoUp+WllwS3KXmuJh+9vIfY5lFp38pew=="
}
},
"workspace": {
"dependencies": [
"jsr:@denotest/has-only-pre-release@^2.0.0-beta.1",
"jsr:@denotest/has-pre-release@^2.0.0-beta.1",
"npm:@denotest/has-pre-release@^2.0.0-beta.1"
]
}
}

View file

@ -0,0 +1,11 @@
┌────────────────────────────────────┬──────────────┬──────────────┬──────────────┐
│ Package │ Current │ Update │ Latest │
├────────────────────────────────────┼──────────────┼──────────────┼──────────────┤
│ jsr:@denotest/has-only-pre-release │ 2.0.0-beta.1 │ 2.0.0-beta.2 │ 2.0.0-beta.2 │
├────────────────────────────────────┼──────────────┼──────────────┼──────────────┤
│ jsr:@denotest/has-pre-release │ 2.0.0-beta.1 │ 2.0.0-beta.2 │ 2.0.0-beta.2 │
├────────────────────────────────────┼──────────────┼──────────────┼──────────────┤
│ npm:@denotest/has-pre-release │ 2.0.0-beta.1 │ 2.0.0-beta.2 │ 2.0.0-beta.2 │
└────────────────────────────────────┴──────────────┴──────────────┴──────────────┘
[WILDCARD]

View file

@ -0,0 +1,5 @@
[WILDCARD]
Updated 3 dependencies:
- jsr:@denotest/has-only-pre-release 2.0.0-beta.1 -> 2.0.0-beta.2
- jsr:@denotest/has-pre-release 2.0.0-beta.1 -> 2.0.0-beta.2
- npm:@denotest/has-pre-release 2.0.0-beta.1 -> 2.0.0-beta.2

View file

@ -28,6 +28,8 @@ Deno.test(
try {
await fs.promises.access(file, fs.constants.R_OK);
await fs.promises.access(file, fs.constants.W_OK);
await fs.promises.access(file, fs.constants.X_OK);
await fs.promises.access(file, fs.constants.F_OK);
} finally {
await Deno.remove(file);
}
@ -60,6 +62,8 @@ Deno.test(
try {
fs.accessSync(file, fs.constants.R_OK);
fs.accessSync(file, fs.constants.W_OK);
fs.accessSync(file, fs.constants.X_OK);
fs.accessSync(file, fs.constants.F_OK);
} finally {
Deno.removeSync(file);
}

View file

@ -267,6 +267,7 @@ fn get_npm_package(
let mut tarballs = HashMap::new();
let mut versions = serde_json::Map::new();
let mut latest_version = semver::Version::parse("0.0.0").unwrap();
let mut dist_tags = serde_json::Map::new();
for entry in fs::read_dir(&package_folder)? {
let entry = entry?;
let file_type = entry.file_type()?;
@ -345,6 +346,14 @@ fn get_npm_package(
}
}
if let Some(publish_config) = version_info.get("publishConfig") {
if let Some(tag) = publish_config.get("tag") {
if let Some(tag) = tag.as_str() {
dist_tags.insert(tag.to_string(), version.clone().into());
}
}
}
versions.insert(version.clone(), version_info.into());
let version = semver::Version::parse(&version)?;
if version.cmp(&latest_version).is_gt() {
@ -352,8 +361,9 @@ fn get_npm_package(
}
}
let mut dist_tags = serde_json::Map::new();
dist_tags.insert("latest".to_string(), latest_version.to_string().into());
if !dist_tags.contains_key("latest") {
dist_tags.insert("latest".to_string(), latest_version.to_string().into());
}
// create the registry file for this package
let mut registry_file = serde_json::Map::new();