Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(unstable): deno info --json output #7417

Merged
merged 20 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from 4 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
93 changes: 92 additions & 1 deletion cli/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::msg;
use crate::ModuleSpecifier;
use crate::Permissions;
use deno_core::ErrBox;
use serde::ser::{SerializeMap, Serializer};
use serde::Serialize;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
Expand All @@ -19,15 +20,17 @@ pub struct ModuleDepInfo {
compiled: Option<String>,
map: Option<String>,
dep_count: usize,
#[serde(skip_serializing)]
deps: FileInfoDepTree,
files: FileInfoDepFlatGraph,
}

impl ModuleDepInfo {
/// Creates a new `ModuleDepInfo` struct for the module with the provided `ModuleSpecifier`.
pub async fn new(
global_state: &Arc<GlobalState>,
module_specifier: ModuleSpecifier,
) -> Result<ModuleDepInfo, ErrBox> {
) -> Result<Self, ErrBox> {
// First load module as if it was to be executed by worker
// including compilation step
let mut module_graph_loader = ModuleGraphLoader::new(
Expand Down Expand Up @@ -60,6 +63,7 @@ impl ModuleDepInfo {

let deps = FileInfoDepTree::new(&module_graph, &module_specifier);
let dep_count = get_unique_dep_count(&module_graph) - 1;
let files = FileInfoDepFlatGraph::new(&deps);

let info = Self {
local: local_filename,
Expand All @@ -68,6 +72,7 @@ impl ModuleDepInfo {
map: map_filename,
dep_count,
deps,
files,
};

Ok(info)
Expand Down Expand Up @@ -221,6 +226,92 @@ impl FileInfoDepTree {
deps,
}
}

/// Flattens dependencies
///
/// Returns flat graph structure with dependencies list per module file
fn flatten_to_graph(&self) -> HashMap<String, FileInfoVertex> {
let mut flat_graph = HashMap::new();
dig_out_nested_deps(&self, &mut flat_graph);
flat_graph
}
}

/// Digs out dependencies recursively from nested structure
fn dig_out_nested_deps(
deps_tree: &FileInfoDepTree,
flat_graph: &mut HashMap<String, FileInfoVertex>,
) -> HashSet<String> {
let mut shallow_nested = HashSet::new();
let mut deep_nested = HashSet::new();
deps_tree.deps.iter().for_each(|_deps_tree| {
shallow_nested.insert(_deps_tree.name.clone());
deep_nested = deep_nested
.union(&dig_out_nested_deps(_deps_tree, flat_graph))
.cloned()
.collect();
});
deep_nested = deep_nested.union(&shallow_nested).cloned().collect();
if let Some(vertex) = flat_graph.get_mut(&deps_tree.name) {
vertex.size = deps_tree.size;
vertex.total_size = deps_tree.total_size;
vertex.deps = deep_nested.clone();
} else {
let deps = deep_nested.clone();
let vertex =
FileInfoVertex::new(deps_tree.size, deps_tree.total_size, deps);
flat_graph.insert(deps_tree.name.clone(), vertex);
}
deep_nested
}

/// Flat graph vertex with all its unique dependencies
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct FileInfoVertex {
size: usize,
total_size: Option<usize>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't show total size of vertex in terminal output and I think we should skip it in JSON as well. It's useful to have total size of all dependencies in top level structure, but calculating sizes of subdependencies should be left to implementors. @lucacasonato WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I agree

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bartossh let's remove total_size then. Otherwise LGTM and we can land this PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bartlomieju Curious about this. I requested the original feature and noticed that the total size of each dependency was left out in the end. I thought this a useful feature to see how big your dependencies were. Of course, you can compute this manually by running deno info against each dependency but that's a bit of a pain. I agree that these should be consistent, just curious about the reasoning behind leaving out the total size of dependencies.

Copy link
Contributor Author

@bartossh bartossh Sep 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have implemented the change for total_size that @bartlomieju and @lucacasonato agreed on, removing it from vertex of a flat graph, and added total_sizeto module info on the top level so only total size of module will be shown.
But if you think @cknight suggestion should be applied I will cherry pic previous implementation and push changes back again.

this will look like this

Thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that these should be consistent, just curious about the reasoning behind leaving out the total size of dependencies.

Circular dependencies can be really confusing, especially if they show up multiple times. Showing only the size of singular dependency is what browsers do. If there will be huge demand for "total" size we can revisit the topic, but for now I think we should go only with size of the concrete module without it's deps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @bartlomieju, makes sense

deps: HashSet<String>,
}

impl FileInfoVertex {
/// Creates single module vertex
fn new(
size: usize,
total_size: Option<usize>,
deps: HashSet<String>,
) -> Self {
Self {
size,
total_size,
deps,
}
}
}

struct FileInfoDepFlatGraph(HashMap<String, FileInfoVertex>);

impl FileInfoDepFlatGraph {
/// Creates flat graf of module dependencies where each greph vertex holds all its unique dependencies
///
/// Graph is created by flattening tree like dependencies structure
fn new(deps: &FileInfoDepTree) -> Self {
let inner = deps.flatten_to_graph();
Self(inner)
}
}

impl Serialize for FileInfoDepFlatGraph {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(self.0.len()))?;
for (k, v) in &self.0 {
map.serialize_entry(&k.to_string(), &v)?;
}
map.end()
}
}

/// Returns a `ModuleGraphFile` associated to the provided `ModuleSpecifier`.
Expand Down
58 changes: 31 additions & 27 deletions cli/tests/055_info_file_json.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,35 @@
"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": []
}
]
}
]
}
]
"files": {
"file://[WILDCARD]/subdir/mod1.ts": {
"size": 320,
"totalSize": 546,
"deps": [
"file://[WILDCARD]/subdir/subdir2/mod2.ts",
"file://[WILDCARD]/subdir/print_hello.ts"
]
},
"file://[WILDCARD]/005_more_imports.ts": {
"size": 211,
"totalSize": 757,
"deps": [
"file://[WILDCARD]/subdir/print_hello.ts",
"file://[WILDCARD]/subdir/subdir2/mod2.ts",
"file://[WILDCARD]/subdir/mod1.ts"
]
},
"file://[WILDCARD]/subdir/print_hello.ts": {
"size": 63,
"totalSize": 63,
"deps": []
},
"file://[WILDCARD]/subdir/subdir2/mod2.ts": {
"size": 163,
"totalSize": 226,
"deps": [
"file://[WILDCARD]/subdir/print_hello.ts"
]
}
}
}
}