summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbartOssh <lenart.consulting@gmail.com>2020-09-16 15:38:38 +0200
committerGitHub <noreply@github.com>2020-09-16 15:38:38 +0200
commit81ca7096c5e8830cf8707c77fd244672e7e67c79 (patch)
treeff73340eb97b2601b41903a641b4cb99911f8aa5
parentd4a24c870e87b55dab425bc2c320aa88a6224030 (diff)
refactor(unstable): deno info --json output (#7417)
Provide flat JSON structured output. Fix BrokenPipe error when piping out to "head".
-rw-r--r--cli/fmt.rs2
-rw-r--r--cli/info.rs62
-rw-r--r--cli/main.rs4
-rw-r--r--cli/tests/055_info_file_json.out50
4 files changed, 86 insertions, 32 deletions
diff --git a/cli/fmt.rs b/cli/fmt.rs
index e225b328b..16b90b1c7 100644
--- a/cli/fmt.rs
+++ b/cli/fmt.rs
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-//! This module provides file formating utilities using
+//! This module provides file formatting utilities using
//! [`dprint-plugin-typescript`](https://github.com/dsherret/dprint-plugin-typescript).
//!
//! At the moment it is only consumed using CLI but in
diff --git a/cli/info.rs b/cli/info.rs
index fdc021eff..7b5c0151b 100644
--- a/cli/info.rs
+++ b/cli/info.rs
@@ -4,8 +4,9 @@ use crate::module_graph::{ModuleGraph, ModuleGraphFile, ModuleGraphLoader};
use crate::ModuleSpecifier;
use crate::Permissions;
use deno_core::error::AnyError;
+use serde::ser::Serializer;
use serde::Serialize;
-use std::collections::{HashMap, HashSet};
+use std::collections::{BTreeMap, HashMap, HashSet};
use std::sync::Arc;
// TODO(bartlomieju): rename
@@ -18,7 +19,10 @@ pub struct ModuleDepInfo {
compiled: Option<String>,
map: Option<String>,
dep_count: usize,
+ #[serde(skip_serializing)]
deps: FileInfoDepTree,
+ total_size: Option<usize>,
+ files: FileInfoDepFlatGraph,
}
impl ModuleDepInfo {
@@ -26,7 +30,7 @@ impl ModuleDepInfo {
pub async fn new(
global_state: &Arc<GlobalState>,
module_specifier: ModuleSpecifier,
- ) -> Result<ModuleDepInfo, AnyError> {
+ ) -> Result<Self, AnyError> {
// First load module as if it was to be executed by worker
// including compilation step
let mut module_graph_loader = ModuleGraphLoader::new(
@@ -59,7 +63,9 @@ impl ModuleDepInfo {
crate::media_type::enum_name_media_type(out.media_type).to_string();
let deps = FileInfoDepTree::new(&module_graph, &module_specifier);
+ let total_size = deps.total_size;
let dep_count = get_unique_dep_count(&module_graph) - 1;
+ let files = FileInfoDepFlatGraph::new(&module_graph);
let info = Self {
local: local_filename,
@@ -68,6 +74,8 @@ impl ModuleDepInfo {
map: map_filename,
dep_count,
deps,
+ total_size,
+ files,
};
Ok(info)
@@ -223,6 +231,54 @@ impl FileInfoDepTree {
}
}
+/// Flat graph vertex with all shallow dependencies
+#[derive(Serialize)]
+#[serde(rename_all = "camelCase")]
+struct FileInfoVertex {
+ size: usize,
+ deps: Vec<String>,
+}
+
+impl FileInfoVertex {
+ /// Creates new `FileInfoVertex` that is a single vertex dependency module
+ fn new(size: usize, deps: Vec<String>) -> Self {
+ Self { size, deps }
+ }
+}
+
+struct FileInfoDepFlatGraph(HashMap<String, FileInfoVertex>);
+
+impl FileInfoDepFlatGraph {
+ /// Creates new `FileInfoDepFlatGraph`, flat graph of a shallow module dependencies
+ ///
+ /// Each graph vertex represents unique dependency with its all shallow dependencies
+ fn new(module_graph: &ModuleGraph) -> Self {
+ let mut inner = HashMap::new();
+ module_graph
+ .iter()
+ .for_each(|(module_name, module_graph_file)| {
+ let size = module_graph_file.size();
+ let mut deps = Vec::new();
+ module_graph_file.imports.iter().for_each(|import| {
+ deps.push(import.resolved_specifier.to_string());
+ });
+ inner.insert(module_name.clone(), FileInfoVertex::new(size, deps));
+ });
+ Self(inner)
+ }
+}
+
+impl Serialize for FileInfoDepFlatGraph {
+ /// Serializes inner hash map which is ordered by the key
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let ordered: BTreeMap<_, _> = self.0.iter().collect();
+ ordered.serialize(serializer)
+ }
+}
+
/// Returns a `ModuleGraphFile` associated to the provided `ModuleSpecifier`.
///
/// If the `specifier` is associated with a file that has a populated redirect field,
@@ -374,7 +430,7 @@ mod test {
}
#[test]
- fn get_new_prefix_adds_a_vertial_bar_if_not_is_last() {
+ fn get_new_prefix_adds_a_vertical_bar_if_not_is_last() {
let prefix = get_new_prefix("", false);
assert_eq!(prefix, "│ ".to_string());
diff --git a/cli/main.rs b/cli/main.rs
index a300c3d69..d121d1c92 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -187,8 +187,8 @@ async fn info_command(
if json {
write_json_to_stdout(&json!(info))
} else {
- print!("{}", info);
- Ok(())
+ write_to_stdout_ignore_sigpipe(format!("{}", info).as_bytes())
+ .map_err(AnyError::from)
}
}
}
diff --git a/cli/tests/055_info_file_json.out b/cli/tests/055_info_file_json.out
index 5c5da8836..c3f5f1c36 100644
--- a/cli/tests/055_info_file_json.out
+++ b/cli/tests/055_info_file_json.out
@@ -4,31 +4,29 @@
"compiled": null,
"map": null,
"depCount": 3,
- "deps": {
- "name": "file://[WILDCARD]/005_more_imports.ts",
- "size": 211,
- "totalSize": 757,
- "deps": [
- {
- "name": "file://[WILDCARD]/subdir/mod1.ts",
- "size": 320,
- "totalSize": 546,
- "deps": [
- {
- "name": "file://[WILDCARD]/subdir/subdir2/mod2.ts",
- "size": 163,
- "totalSize": 226,
- "deps": [
- {
- "name": "file://[WILDCARD]/subdir/print_hello.ts",
- "size": 63,
- "totalSize": 63,
- "deps": []
- }
- ]
- }
- ]
- }
- ]
+ "totalSize": 757,
+ "files": {
+ "file://[WILDCARD]005_more_imports.ts": {
+ "size": 211,
+ "deps": [
+ "file://[WILDCARD]/subdir/mod1.ts"
+ ]
+ },
+ "file://[WILDCARD]/subdir/mod1.ts": {
+ "size": 320,
+ "deps": [
+ "file://[WILDCARD]/subdir/subdir2/mod2.ts"
+ ]
+ },
+ "file://[WILDCARD]/subdir/print_hello.ts": {
+ "size": 63,
+ "deps": []
+ },
+ "file://[WILDCARD]/subdir/subdir2/mod2.ts": {
+ "size": 163,
+ "deps": [
+ "file://[WILDCARD]/subdir/print_hello.ts"
+ ]
+ }
}
} \ No newline at end of file