diff options
author | bartOssh <lenart.consulting@gmail.com> | 2020-09-16 15:38:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-16 15:38:38 +0200 |
commit | 81ca7096c5e8830cf8707c77fd244672e7e67c79 (patch) | |
tree | ff73340eb97b2601b41903a641b4cb99911f8aa5 | |
parent | d4a24c870e87b55dab425bc2c320aa88a6224030 (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.rs | 2 | ||||
-rw-r--r-- | cli/info.rs | 62 | ||||
-rw-r--r-- | cli/main.rs | 4 | ||||
-rw-r--r-- | cli/tests/055_info_file_json.out | 50 |
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 |