mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
parent
bdc53b45b7
commit
7d151efc68
7 changed files with 244 additions and 29 deletions
100
cli/info.rs
100
cli/info.rs
|
@ -23,6 +23,7 @@ const EMPTY_CONNECTOR: char = ' ';
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModuleGraphInfoDep {
|
||||
pub specifier: String,
|
||||
#[serde(skip_serializing_if = "is_false")]
|
||||
pub is_dynamic: bool,
|
||||
#[serde(rename = "code", skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_code: Option<ModuleSpecifier>,
|
||||
|
@ -30,6 +31,10 @@ pub struct ModuleGraphInfoDep {
|
|||
pub maybe_type: Option<ModuleSpecifier>,
|
||||
}
|
||||
|
||||
fn is_false(b: &bool) -> bool {
|
||||
!b
|
||||
}
|
||||
|
||||
impl ModuleGraphInfoDep {
|
||||
fn write_info<S: AsRef<str> + fmt::Display + Clone>(
|
||||
&self,
|
||||
|
@ -68,6 +73,8 @@ impl ModuleGraphInfoDep {
|
|||
pub struct ModuleGraphInfoMod {
|
||||
pub specifier: ModuleSpecifier,
|
||||
pub dependencies: Vec<ModuleGraphInfoDep>,
|
||||
#[serde(rename = "typeDependency", skip_serializing_if = "Option::is_none")]
|
||||
pub maybe_type_dependency: Option<ModuleGraphInfoDep>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub size: Option<usize>,
|
||||
#[serde(
|
||||
|
@ -92,6 +99,7 @@ impl Default for ModuleGraphInfoMod {
|
|||
ModuleGraphInfoMod {
|
||||
specifier: resolve_url("https://deno.land/x/mod.ts").unwrap(),
|
||||
dependencies: Vec::new(),
|
||||
maybe_type_dependency: None,
|
||||
size: None,
|
||||
media_type: None,
|
||||
local: None,
|
||||
|
@ -119,7 +127,10 @@ impl ModuleGraphInfoMod {
|
|||
} else {
|
||||
SIBLING_CONNECTOR
|
||||
};
|
||||
let child_connector = if self.dependencies.is_empty() || was_seen {
|
||||
let child_connector = if (self.dependencies.is_empty()
|
||||
&& self.maybe_type_dependency.is_none())
|
||||
|| was_seen
|
||||
{
|
||||
CHILD_NO_DEPS_CONNECTOR
|
||||
} else {
|
||||
CHILD_DEPS_CONNECTOR
|
||||
|
@ -175,7 +186,16 @@ impl ModuleGraphInfoMod {
|
|||
prefix.push(EMPTY_CONNECTOR);
|
||||
let dep_count = self.dependencies.len();
|
||||
for (idx, dep) in self.dependencies.iter().enumerate() {
|
||||
dep.write_info(f, &prefix, idx == dep_count - 1, modules, seen)?;
|
||||
dep.write_info(
|
||||
f,
|
||||
&prefix,
|
||||
idx == dep_count - 1 && self.maybe_type_dependency.is_none(),
|
||||
modules,
|
||||
seen,
|
||||
)?;
|
||||
}
|
||||
if let Some(dep) = &self.maybe_type_dependency {
|
||||
dep.write_info(f, &prefix, true, modules, seen)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +253,16 @@ impl fmt::Display for ModuleGraphInfo {
|
|||
let mut seen = HashSet::new();
|
||||
let dep_len = root.dependencies.len();
|
||||
for (idx, dep) in root.dependencies.iter().enumerate() {
|
||||
dep.write_info(f, "", idx == dep_len - 1, &self.modules, &mut seen)?;
|
||||
dep.write_info(
|
||||
f,
|
||||
"",
|
||||
idx == dep_len - 1 && root.maybe_type_dependency.is_none(),
|
||||
&self.modules,
|
||||
&mut seen,
|
||||
)?;
|
||||
}
|
||||
if let Some(dep) = &root.maybe_type_dependency {
|
||||
dep.write_info(f, "", true, &self.modules, &mut seen)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -296,6 +325,8 @@ mod test {
|
|||
let specifier_b = resolve_url("https://deno.land/x/b.ts").unwrap();
|
||||
let specifier_c_js = resolve_url("https://deno.land/x/c.js").unwrap();
|
||||
let specifier_c_dts = resolve_url("https://deno.land/x/c.d.ts").unwrap();
|
||||
let specifier_d_js = resolve_url("https://deno.land/x/d.js").unwrap();
|
||||
let specifier_d_dts = resolve_url("https://deno.land/x/d.d.ts").unwrap();
|
||||
let modules = vec![
|
||||
ModuleGraphInfoMod {
|
||||
specifier: specifier_a.clone(),
|
||||
|
@ -329,6 +360,12 @@ mod test {
|
|||
},
|
||||
ModuleGraphInfoMod {
|
||||
specifier: specifier_c_js,
|
||||
dependencies: vec![ModuleGraphInfoDep {
|
||||
specifier: "./d.js".to_string(),
|
||||
is_dynamic: false,
|
||||
maybe_code: Some(specifier_d_js.clone()),
|
||||
maybe_type: None,
|
||||
}],
|
||||
size: Some(789),
|
||||
media_type: Some(MediaType::JavaScript),
|
||||
local: Some(PathBuf::from("/cache/deps/https/deno.land/x/c.js")),
|
||||
|
@ -343,6 +380,28 @@ mod test {
|
|||
checksum: Some("a2b3c4d5".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
ModuleGraphInfoMod {
|
||||
specifier: specifier_d_js,
|
||||
size: Some(987),
|
||||
maybe_type_dependency: Some(ModuleGraphInfoDep {
|
||||
specifier: "/x/d.d.ts".to_string(),
|
||||
is_dynamic: false,
|
||||
maybe_code: None,
|
||||
maybe_type: Some(specifier_d_dts.clone()),
|
||||
}),
|
||||
media_type: Some(MediaType::JavaScript),
|
||||
local: Some(PathBuf::from("/cache/deps/https/deno.land/x/d.js")),
|
||||
checksum: Some("5k6j7h8g".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
ModuleGraphInfoMod {
|
||||
specifier: specifier_d_dts,
|
||||
size: Some(67),
|
||||
media_type: Some(MediaType::Dts),
|
||||
local: Some(PathBuf::from("/cache/deps/https/deno.land/x/d.d.ts")),
|
||||
checksum: Some("0h0h0h0h0h".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
];
|
||||
ModuleGraphInfo {
|
||||
root: specifier_a,
|
||||
|
@ -359,11 +418,13 @@ mod test {
|
|||
let expected = r#"local: /cache/deps/https/deno.land/x/a.ts
|
||||
type: TypeScript
|
||||
emit: /cache/emit/https/deno.land/x/a.js
|
||||
dependencies: 3 unique (total 97.66KB)
|
||||
dependencies: 5 unique (total 97.66KB)
|
||||
|
||||
https://deno.land/x/a.ts (123B)
|
||||
└─┬ https://deno.land/x/b.ts (456B)
|
||||
├── https://deno.land/x/c.js (789B)
|
||||
├─┬ https://deno.land/x/c.js (789B)
|
||||
│ └─┬ https://deno.land/x/d.js (987B)
|
||||
│ └── https://deno.land/x/d.d.ts (67B)
|
||||
└── https://deno.land/x/c.d.ts (999B)
|
||||
"#;
|
||||
assert_eq!(actual, expected);
|
||||
|
@ -383,7 +444,6 @@ https://deno.land/x/a.ts (123B)
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./b.ts",
|
||||
"isDynamic": false,
|
||||
"code": "https://deno.land/x/b.ts"
|
||||
}
|
||||
],
|
||||
|
@ -398,7 +458,6 @@ https://deno.land/x/a.ts (123B)
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./c.js",
|
||||
"isDynamic": false,
|
||||
"code": "https://deno.land/x/c.js",
|
||||
"type": "https://deno.land/x/c.d.ts"
|
||||
}
|
||||
|
@ -411,7 +470,12 @@ https://deno.land/x/a.ts (123B)
|
|||
},
|
||||
{
|
||||
"specifier": "https://deno.land/x/c.js",
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
{
|
||||
"specifier": "./d.js",
|
||||
"code": "https://deno.land/x/d.js"
|
||||
}
|
||||
],
|
||||
"size": 789,
|
||||
"mediaType": "JavaScript",
|
||||
"local": "/cache/deps/https/deno.land/x/c.js",
|
||||
|
@ -424,6 +488,26 @@ https://deno.land/x/a.ts (123B)
|
|||
"mediaType": "Dts",
|
||||
"local": "/cache/deps/https/deno.land/x/c.d.ts",
|
||||
"checksum": "a2b3c4d5"
|
||||
},
|
||||
{
|
||||
"specifier": "https://deno.land/x/d.js",
|
||||
"dependencies": [],
|
||||
"typeDependency": {
|
||||
"specifier": "/x/d.d.ts",
|
||||
"type": "https://deno.land/x/d.d.ts"
|
||||
},
|
||||
"size": 987,
|
||||
"mediaType": "JavaScript",
|
||||
"local": "/cache/deps/https/deno.land/x/d.js",
|
||||
"checksum": "5k6j7h8g"
|
||||
},
|
||||
{
|
||||
"specifier": "https://deno.land/x/d.d.ts",
|
||||
"dependencies": [],
|
||||
"size": 67,
|
||||
"mediaType": "Dts",
|
||||
"local": "/cache/deps/https/deno.land/x/d.d.ts",
|
||||
"checksum": "0h0h0h0h0h"
|
||||
}
|
||||
],
|
||||
"size": 99999
|
||||
|
|
|
@ -435,17 +435,9 @@ impl Module {
|
|||
.entry(desc.specifier.to_string())
|
||||
.or_insert_with(|| Dependency::new(location));
|
||||
dep.is_dynamic = desc.is_dynamic;
|
||||
if let Some(specifier) = maybe_specifier {
|
||||
if desc.kind == swc_ecmascript::dep_graph::DependencyKind::ExportType
|
||||
|| desc.kind == swc_ecmascript::dep_graph::DependencyKind::ImportType
|
||||
{
|
||||
dep.maybe_type = Some(specifier);
|
||||
} else {
|
||||
dep.maybe_code = Some(specifier);
|
||||
}
|
||||
}
|
||||
// If the dependency wasn't a type only dependency already, and there is
|
||||
// a `@deno-types` comment, then we will set the `maybe_type` dependency.
|
||||
dep.maybe_code = maybe_specifier;
|
||||
// If there is a `@deno-types` pragma, we will add it to the dependency
|
||||
// if one doesn't already exist.
|
||||
if maybe_type.is_some() && dep.maybe_type.is_none() {
|
||||
dep.maybe_type = maybe_type;
|
||||
}
|
||||
|
@ -1475,9 +1467,19 @@ impl Graph {
|
|||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let maybe_type_dependency =
|
||||
module.maybe_types.clone().map(|(specifier, _type)| {
|
||||
info::ModuleGraphInfoDep {
|
||||
specifier,
|
||||
is_dynamic: false,
|
||||
maybe_code: None,
|
||||
maybe_type: Some(_type),
|
||||
}
|
||||
});
|
||||
Some(info::ModuleGraphInfoMod {
|
||||
specifier: sp.clone(),
|
||||
dependencies,
|
||||
maybe_type_dependency,
|
||||
size: Some(module.size()),
|
||||
media_type: Some(module.media_type),
|
||||
local: Some(module.source_path.clone()),
|
||||
|
|
125
cli/schemas/module-graph.json
Normal file
125
cli/schemas/module-graph.json
Normal file
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"$id": "https://deno.land/schemas/module-graph.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"description": "A JSON representation of a Deno module dependency graph.",
|
||||
"required": [
|
||||
"root",
|
||||
"modules",
|
||||
"size"
|
||||
],
|
||||
"title": "Deno Dependency Graph Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"root": {
|
||||
"default": "",
|
||||
"description": "The root specifier for the graph.",
|
||||
"examples": [
|
||||
"https://deno.land/x/mod.ts"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"modules": {
|
||||
"default": [],
|
||||
"description": "The modules that are part of the graph.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/module"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "The total size of all the unique dependencies in the graph in bytes.",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"module": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"specifier",
|
||||
"dependencies"
|
||||
],
|
||||
"properties": {
|
||||
"specifier": {
|
||||
"type": "string",
|
||||
"description": "The fully qualified module specifier (URL) for the module."
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "array",
|
||||
"description": "An array of dependencies of the module.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dependency"
|
||||
}
|
||||
},
|
||||
"typeDependency": {
|
||||
"$ref": "#/definitions/dependency",
|
||||
"description": "The type dependency for the module. This is set when the file contains a reference to its types or the module was supplied with a types header."
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "The size of the module on disk in bytes."
|
||||
},
|
||||
"mediaType": {
|
||||
"type": "string",
|
||||
"description": "How the file is treated within Deno. All the possible media types that Deno considers are listed here, but in practice, several of them would never appear in a module graph.",
|
||||
"enum": [
|
||||
"JavaScript",
|
||||
"TypeScript",
|
||||
"JSX",
|
||||
"TSX",
|
||||
"Dts",
|
||||
"Json",
|
||||
"Wasm",
|
||||
"TsBuildInfo",
|
||||
"SourceMap",
|
||||
"Unknown"
|
||||
]
|
||||
},
|
||||
"local": {
|
||||
"type": "string",
|
||||
"description": "The path to the local file. For local modules this will be the local file path, for remote modules and data URLs, this would be the path to the file in the Deno cache."
|
||||
},
|
||||
"checksum": {
|
||||
"type": "string",
|
||||
"description": "The checksum of the local source file. This can be used to validate if the current on disk version matches the version described here."
|
||||
},
|
||||
"emit": {
|
||||
"type": "string",
|
||||
"description": "The path to an emitted version of the module, if the module requires transpilation to be loaded into the Deno runtime."
|
||||
},
|
||||
"map": {
|
||||
"type": "string",
|
||||
"description": "The path to an optionally emitted source map between the original and emitted version of the file."
|
||||
},
|
||||
"error": {
|
||||
"type": "string",
|
||||
"description": "If when resolving the module, Deno encountered an error and the module is unavailable, the text of that error will be indicated here."
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependency": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"specifier"
|
||||
],
|
||||
"properties": {
|
||||
"specifier": {
|
||||
"type": "string",
|
||||
"description": "The specifier provided from within the module."
|
||||
},
|
||||
"isDynamic": {
|
||||
"type": "boolean",
|
||||
"description": "A flag that indicates if the import is dynamically imported. A dynamic import may not be fully resolved until it is accessed at runtime."
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "The fully qualified module specifier (URL) for the code dependency."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The fully qualified module specifier (URL) for the type only dependency."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./subdir/mod1.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/subdir/mod1.ts"
|
||||
}
|
||||
],
|
||||
|
@ -20,7 +19,6 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./subdir2/mod2.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/subdir/subdir2/mod2.ts"
|
||||
}
|
||||
],
|
||||
|
@ -42,7 +40,6 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "../print_hello.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/subdir/print_hello.ts"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./recursive_imports/A.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/A.ts"
|
||||
}
|
||||
],
|
||||
|
@ -20,12 +19,10 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./B.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/B.ts"
|
||||
},
|
||||
{
|
||||
"specifier": "./common.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/common.ts"
|
||||
}
|
||||
],
|
||||
|
@ -39,12 +36,10 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./C.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/C.ts"
|
||||
},
|
||||
{
|
||||
"specifier": "./common.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/common.ts"
|
||||
}
|
||||
],
|
||||
|
@ -58,12 +53,10 @@
|
|||
"dependencies": [
|
||||
{
|
||||
"specifier": "./A.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/A.ts"
|
||||
},
|
||||
{
|
||||
"specifier": "./common.ts",
|
||||
"isDynamic": false,
|
||||
"code": "file://[WILDCARD]/cli/tests/recursive_imports/common.ts"
|
||||
}
|
||||
],
|
||||
|
|
8
cli/tests/info/types_header.out
Normal file
8
cli/tests/info/types_header.out
Normal file
|
@ -0,0 +1,8 @@
|
|||
[WILDCARD]
|
||||
local: [WILDCARD]type_directives_01.ts
|
||||
type: TypeScript
|
||||
dependencies: 2 unique (total [WILDCARD])
|
||||
|
||||
[WILDCARD]/type_directives_01.ts ([WILDCARD])
|
||||
└─┬ http://127.0.0.1:4545/xTypeScriptTypes.js ([WILDCARD])
|
||||
└── http://127.0.0.1:4545/xTypeScriptTypes.d.ts ([WILDCARD])
|
|
@ -118,3 +118,9 @@ itest!(data_null_error {
|
|||
args: "info info/data_null_error/mod.ts",
|
||||
output: "info/data_null_error/data_null_error.out",
|
||||
});
|
||||
|
||||
itest!(deno_info_types_header_direct {
|
||||
args: "info --reload type_directives_01.ts",
|
||||
output: "info/types_header.out",
|
||||
http_server: true,
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue