# Package pretty tree

**URL:** <https://discourse.julialang.org/t/package-pretty-tree/118578>\
**Category:** General Usage\
**Created:** [August 24, 2024, 9:33pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578 "2024-08-24T21:33:35Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 24, 2024, 9:33pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/1 "2024-08-24T21:33:35Z")

</div>

Hello,

So I may be wrong, but I have been looking and asking around, and I found no package that builds a pretty tree of a package content.

Something like this:

```julia
ClimaLand
├─ Artifacts
├─ Bucket
├─ Canopy
│ └─ PlantHydraulics
├─ Diagnostics
├─ Domains
├─ Parameters
├─ Pond
├─ Snow
└─ Soil
   ├─ Biogeochemistry
   └─ Runoff

```

that display the package main Module and submodules  
and hopefully it’d be even better if you’d see functions and struct exported from the module, in different colors (e.g., red for functions, blue for struct), with the possibility to expand or collapse…

To get a list of the modules of the package ClimaLand I did:

```jl
function get_module_hierarchy(mod::Module, prefix="")
    result = String[]
    mod_name = string(nameof(mod))
    full_prefix = isempty(prefix) ? mod_name : "$prefix.$mod_name"
    
    for name in names(mod, all=true)
        if !startswith(string(name), "#")
            obj = getproperty(mod, name)
            if obj isa Module && obj != mod
                full_name = "$full_prefix.$name"
                push!(result, full_name)
                append!(result, get_module_hierarchy(obj, full_prefix))
            end
        end
    end
    return sort(result)
end

```

and to build the tree:

```jl
using AbstractTrees
# Define a simple tree node type
struct ModuleNode
    name::String
    children::Vector{ModuleNode}
end
# Implement the required methods for AbstractTrees
AbstractTrees.children(node::ModuleNode) = node.children
AbstractTrees.printnode(io::IO, node::ModuleNode) = print(io, node.name)
# Create your tree structure
climatree = ModuleNode("ClimaLand", [
    ModuleNode("Artifacts", []),
    ModuleNode("Bucket", []),
    ModuleNode("Canopy", [
        ModuleNode("PlantHydraulics", [])
    ]),
    ModuleNode("Diagnostics", []),
    ModuleNode("Domains", []),
    ModuleNode("Parameters", []),
    ModuleNode("Pond", []),
    ModuleNode("Snow", []),
    ModuleNode("Soil", [
        ModuleNode("Biogeochemistry", []),
        ModuleNode("Runoff", [])
    ])
])

```

But I wish there was a package that you just do e.g., `PackageTree(nameofpackage)`

and you’d have a beautiful tree… If it doesn’t exist, I am surprised, I think it would be amazing to have it in docs etc.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 24, 2024, 9:37pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/2 "2024-08-24T21:37:57Z")

</div>

PkgDependency.jl provides a tree of dependencies, which is the not the same concept, but very useful. Sharing it here for future readers.

---

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 24, 2024, 9:40pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/3 "2024-08-24T21:40:48Z")

</div>

That is neat.  
To me such tree (dependencies or submodules + exported abstractions of a package) is so essential that it belongs in Main.  
I am surprised it doesn’t exist yet. But sounds like a good package writing opportunity.

the closest we have is `names()` which is great but not complete

---

<div class="post-metadata">

**Author:** ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)\
**Post date:** [August 26, 2024, 12:12am UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/4 "2024-08-26T00:12:12Z")

</div>

Maybe that’s something that could be part of @tecosaur’s [About.jl](https://github.com/tecosaur/About.jl)?

---

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 26, 2024, 1:55am UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/5 "2024-08-26T01:55:05Z")

</div>

About.jl seems very nice and it would indeed be a great fit!

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [August 26, 2024, 5:27am UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/6 "2024-08-26T05:27:49Z")

</div>

I think the current display for `about(::Module)` should be pretty close to what you mention wanting, it displays submodules, macros, types, functions, variables in different colours, and tells you what’s exported/public.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/9/994d4b1a6f81680328feb9ee66575c2a59bd5f98.png)

It would mention the submodules, but they’re neither exported nor public.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 26, 2024, 7:29am UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/7 "2024-08-26T07:29:33Z")

</div>

> [@tecosaur](#):
>
> It would mention the submodules, but they’re neither exported nor public

Would it be possible/beneficial to compose About.jl with MethodAnalysis.jl?  
[Home · MethodAnalysis.jl (timholy.github.io)](https://timholy.github.io/MethodAnalysis.jl/stable/)

---

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 26, 2024, 6:02pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/8 "2024-08-26T18:02:51Z")

</div>

This is great!

We are not exporting submodules because they have a lot of functions and struct and we don’t want to crowd the namespace (does that make sense?) but a user can still do import ClimaLand.Soil.Biogeochemistry, for example.

But to be honest, we haven’t thought much about the structure, what to export or not, etc. There’s work to do.

But I think if a functionality like about or a tree of a package was more in our mind during development, we would’ve paid more attention to it. My point is, in general, such functionality could help tidy development and discoverability (again, does that make sense?)

I’d love to add in the first two pages of our docs a table or tree of our package that give a broad vision of the structure / organization of the package, maybe with or without exported modules/functions/structs as an option, and maybe with foldables (but I understand folding may not be ideal in the REPL).

We should keep this discussion going! And I am happy to contribute to an effort.

---

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 26, 2024, 6:09pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/9 "2024-08-26T18:09:11Z")

</div>

Looks like child\_modules is pretty close to what I wanted!

I agree child\_modules + about would be close to deliver everything

---

<div class="post-metadata">

**Author:** ![AlexisRenchon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexisrenchon/32/13328_2.png) [@AlexisRenchon](https://discourse.julialang.org/u/AlexisRenchon)\
**Post date:** [August 29, 2024, 10:56pm UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/10 "2024-08-29T22:56:04Z")

</div>

@tecosaur did you do anything special to have types printed in different colors? (maybe this not the latest release?) when I use `about(::Module)` I get the same output, but submodules, macros, types, functions, … are all printed in the same color.

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [August 30, 2024, 12:09am UTC](https://discourse.julialang.org/t/package-pretty-tree/118578/11 "2024-08-30T00:09:13Z")

</div>

For me this is a difference between using Julia 1.10 (no colors) and 1.11 (colors).
