Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ddddddo/gtree
Using either Markdown or Programmatically to generate trees๐ณ and directories๐, and to verify directories๐. Provide CLI, Golang library and Web.
https://github.com/ddddddo/gtree
cli directory golang markdown tree tree-structure trees wasm
Last synced: about 2 hours ago
JSON representation
Using either Markdown or Programmatically to generate trees๐ณ and directories๐, and to verify directories๐. Provide CLI, Golang library and Web.
- Host: GitHub
- URL: https://github.com/ddddddo/gtree
- Owner: ddddddO
- License: bsd-2-clause
- Created: 2021-05-30T01:51:22.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-09-11T14:26:20.000Z (2 months ago)
- Last Synced: 2024-09-11T22:32:42.463Z (2 months ago)
- Topics: cli, directory, golang, markdown, tree, tree-structure, trees, wasm
- Language: Go
- Homepage: https://ddddddo.github.io/gtree/
- Size: 19.8 MB
- Stars: 216
- Watchers: 5
- Forks: 8
- Open Issues: 37
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[^1]
[![GitHub Pages](https://img.shields.io/badge/-GitHub_Pages-00A98F.svg?logo=github&style=flat)](https://ddddddo.github.io/gtree/)
[![GitHub release](https://img.shields.io/github/release/ddddddO/gtree.svg?label=Release&color=darkcyan)](https://github.com/ddddddO/gtree/releases) [![Go Reference](https://pkg.go.dev/badge/github.com/ddddddO/gtree)](https://pkg.go.dev/github.com/ddddddO/gtree)
[![License](https://img.shields.io/badge/License-BSD_2--Clause-orange.svg?color=darkcyan)](https://github.com/ddddddO/gtree/blob/master/LICENSE) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#uncategorized)
[![codecov](https://codecov.io/gh/ddddddO/gtree/branch/master/graph/badge.svg?token=JLGSLF33RH)](https://codecov.io/gh/ddddddO/gtree) [![Go Report Card](https://goreportcard.com/badge/github.com/ddddddO/gtree)](https://goreportcard.com/report/github.com/ddddddO/gtree) [![ci](https://github.com/ddddddO/gtree/actions/workflows/ci.yaml/badge.svg)](https://github.com/ddddddO/gtree/actions/workflows/ci.yaml)
Using either Markdown or Programmatically to generate directory trees๐ณ and directories๐, and to verify directories๐.
Provide CLI, Golang library and Web.# Table of Contents
- **[Acknowledgments](https://github.com/ddddddO/gtree?tab=readme-ov-file#acknowledgments)**
- Features
- **[Web](https://github.com/ddddddO/gtree?tab=readme-ov-file#web)**
- **[CLI](https://github.com/ddddddO/gtree?tab=readme-ov-file#cli)**
- Library - **[Markdown to tree structure](https://github.com/ddddddO/gtree?tab=readme-ov-file#library---markdown-to-tree-structure)**
- Library - **[Programmable tree structure](https://github.com/ddddddO/gtree?tab=readme-ov-file#library---programmable-tree-structure)**
- Recommended for developers!๐
- [Documents](https://github.com/ddddddO/gtree?tab=readme-ov-file#documents)
- [Process](https://github.com/ddddddO/gtree?tab=readme-ov-file#process)
- [Performance](https://github.com/ddddddO/gtree?tab=readme-ov-file#performance)
- [Test coverage](https://github.com/ddddddO/gtree?tab=readme-ov-file#test-coverage)# Acknowledgments
## Thanks for providing very useful CLI for cloud storage tree output๐คฉ๐
Everyone is encouraged to use them!
### โญ[_orangekame3/stree_](https://github.com/orangekame3/stree)
CLI for **Amazon S3** tree output.
[_aws s3_](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html) command does not do what `tree` command does, but [**_stree_**](https://github.com/orangekame3/stree) command can display tree!### โญ[_owlinux1000/gcstree_](https://github.com/owlinux1000/gcstree)
CLI for **Google Cloud Storage** tree output.
[_gcloud storage_](https://cloud.google.com/sdk/gcloud/reference/storage) command does not do what `tree` command does, but [**_gcstree_**](https://github.com/owlinux1000/gcstree) command can display tree!## gtree packeage has been utilized for other tools as well๐
I hope you will use these tools as well!- [Tools](https://github.com/ddddddO/gtree/network/dependents)
# Web
https://ddddddo.github.io/gtree/
This page is that converts from Markdown to tree!
This page calls a function that outputs tree. This function is a Go package compiled as WebAssembly.
The symbols that can be used in Markdown are `*`, `-`, `+`, and `#`.
Indentation represents hierarchy. The indentation can be whatever you specify, but use the same pattern.
You can change the branches like in the image below.
Also, once loaded, you can enjoy offline!![](assets/web_example.gif)
You can open it in your browser with
```console
$ gtree web
```[source code](cmd/gtree-wasm/)
# CLI
## Installation
Go (requires 1.18 or later)
$ go install github.com/ddddddO/gtree/cmd/gtree@latestHomebrew
$ brew install ddddddO/tap/gtreeScoop
$ scoop bucket add ddddddO https://github.com/ddddddO/scoop-bucket.git
$ scoop install ddddddO/gtreedeb
$ export GTREE_VERSION=X.X.X
$ curl -o gtree.deb -L https://github.com/ddddddO/gtree/releases/download/v$GTREE_VERSION/gtree_$GTREE_VERSION-1_amd64.deb
$ dpkg -i gtree.debrpm
$ export GTREE_VERSION=X.X.X
$ yum install https://github.com/ddddddO/gtree/releases/download/v$GTREE_VERSION/gtree_$GTREE_VERSION-1_amd64.rpmapk
$ export GTREE_VERSION=X.X.X
$ curl -o gtree.apk -L https://github.com/ddddddO/gtree/releases/download/v$GTREE_VERSION/gtree_$GTREE_VERSION-1_amd64.apk
$ apk add --allow-untrusted gtree.apkAUR
$ wip...Nix
$ nix-env -i gtree
or
$ nix-shell -p gtreeMacPorts
$ port install gtreeaqua
$ aqua g -i ddddddO/gtreeDocker
$ docker pull ghcr.io/ddddddo/gtree:latest
$ docker run ghcr.io/ddddddo/gtree:latest template | docker run -i ghcr.io/ddddddo/gtree:latest output
gtree
โโโ cmd
โ โโโ gtree
โ โโโ main.go
โโโ testdata
โ โโโ sample1.md
โ โโโ sample2.md
โโโ Makefile
โโโ tree.go### etc
**download binary from [here](https://github.com/ddddddO/gtree/releases).**
## Usage
```console
$ gtree --help
NAME:
gtree - This CLI uses Markdown to generate directory trees and directories itself, and also verifies directories.
The symbols that can be used in Markdown are '-', '+', '*', and '#'.
Within Markdown, indentation represents hierarchy. The indentation can be whatever you specify, but use the same pattern.USAGE:
gtree [global options] command [command options] [arguments...]VERSION:
1.10.2 / revision 85520a1COMMANDS:
output, o, out Outputs tree from markdown.
Let's try 'gtree template | gtree output'.
mkdir, m Makes directories and files from markdown. It is possible to dry run.
Let's try 'gtree template | gtree mkdir -e .go -e .md -e Makefile'.
verify, vf Verifies tree structure represented in markdown by comparing it with existing directories.
Let's try 'gtree template | gtree verify'.
template, t, tmpl Outputs markdown template. Use it to try out gtree CLI.
web, w, www Opens "Tree Maker" in your browser and shows the URL in terminal.
version, v Prints the version.
help, h Shows a list of commands or help for one commandGLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
```### *Output* subcommand
```console
$ gtree output --help
NAME:
gtree output - Outputs tree from markdown.
Let's try 'gtree template | gtree output'.USAGE:
gtree output [command options] [arguments...]OPTIONS:
--file value, -f value specify the path to markdown file. (default: stdin)
--massive, -m set this option when there are very many blocks of markdown. (default: false)
--massive-timeout value, --mt value set this option if you want to set a timeout. (default: 0s)
--format value set this option when specifying output format. "json", "yaml", "toml"
--watch, -w follow changes in markdown file. (default: false)
--help, -h show help
```#### Try it!
```console
$ gtree template
- gtree
- cmd
- gtree
- main.go
- testdata
- sample1.md
- sample2.md
- Makefile
- tree.go
$ gtree template | gtree output
gtree
โโโ cmd
โ โโโ gtree
โ โโโ main.go
โโโ testdata
โ โโโ sample1.md
โ โโโ sample2.md
โโโ Makefile
โโโ tree.go
```Other pattern.
```
โโโ gtree output -f testdata/sample1.md
โโโ cat testdata/sample1.md | gtree output -f -
โโโ cat testdata/sample1.md | gtree output
```#### Usage other than representing a directory.
```console
$ cat testdata/sample2.md | gtree output
k8s_resources
โโโ (Tier3)
โ โโโ (Tier2)
โ โโโ (Tier1)
โ โโโ (Tier0)
โโโ Deployment
โ โโโ ReplicaSet
โ โโโ Pod
โ โโโ container(s)
โโโ CronJob
โ โโโ Job
โ โโโ Pod
โ โโโ container(s)
โโโ (empty)
โโโ DaemonSet
โ โโโ Pod
โ โโโ container(s)
โโโ StatefulSet
โโโ Pod
โโโ container(s)
```#### Multiple roots
```console
$ cat testdata/sample6.md | gtree output
Artiodactyla
โโโ Artiofabula
โ โโโ Cetruminantia
โ โ โโโ Whippomorpha
โ โ โ โโโ Hippopotamidae
โ โ โ โโโ Cetacea
โ โ โโโ Ruminantia
โ โโโ Suina
โโโ Tylopoda
Carnivora
โโโ Feliformia
โโโ Caniformia
โโโ Canidae
โโโ Arctoidea
โโโ Ursidae
โโโ x
โโโ Pinnipedia
โโโ Musteloidea
โโโ Ailuridae
โโโ x
โโโ Mephitidae
โโโ x
โโโ Procyonidae
โโโ Mustelidae
```#### Output JSON
```console
$ cat testdata/sample5.md | gtree output --format json | jq
{
"value": "a",
"children": [
{
"value": "i",
"children": [
{
"value": "u",
"children": [
{
"value": "k",
"children": null
},
{
"value": "kk",
"children": null
}
]
},
{
"value": "t",
"children": null
}
]
},
{
"value": "e",
"children": [
{
"value": "o",
"children": null
}
]
},
{
"value": "g",
"children": null
}
]
}
```#### Output YAML
```console
$ cat testdata/sample5.md | gtree output --format yaml
value: a
children:
- value: i
children:
- value: u
children:
- value: k
children: []
- value: kk
children: []
- value: t
children: []
- value: e
children:
- value: o
children: []
- value: g
children: []
```#### Output TOML
```console
$ cat testdata/sample5.md | gtree output --format toml
value = 'a'
[[children]]
value = 'i'
[[children.children]]
value = 'u'
[[children.children.children]]
value = 'k'
children = []
[[children.children.children]]
value = 'kk'
children = [][[children.children]]
value = 't'
children = [][[children]]
value = 'e'
[[children.children]]
value = 'o'
children = [][[children]]
value = 'g'
children = []```
### *Mkdir* subcommand
```console
$ gtree mkdir --help
NAME:
gtree mkdir - Makes directories and files from markdown. It is possible to dry run.
Let's try 'gtree template | gtree mkdir -e .go -e .md -e Makefile'.USAGE:
gtree mkdir [command options] [arguments...]OPTIONS:
--file value, -f value specify the path to markdown file. (default: stdin)
--dry-run, -d dry run. detects node that is invalid for directory generation. the order of the output and made directories does not always match. (default: false)
--extension value, -e value [ --extension value, -e value ] set this option if you want to create file instead of directory. for example, if you want to generate files with ".go" extension: "-e .go"
--target-dir value set this option if you want to specify the directory you want to make directory. (default: current directory)
--help, -h show help
```#### Try it!
```console
$ gtree template
- gtree
- cmd
- gtree
- main.go
- testdata
- sample1.md
- sample2.md
- Makefile
- tree.go
$ gtree template | gtree mkdir
$ tree gtree/
gtree/
โโโ cmd
โ โโโ gtree
โ โโโ main.go
โโโ Makefile
โโโ testdata
โ โโโ sample1.md
โ โโโ sample2.md
โโโ tree.go8 directories, 0 files
```#### *make directories and files*
```console
$ gtree template
- gtree
- cmd
- gtree
- main.go
- testdata
- sample1.md
- sample2.md
- Makefile
- tree.go
$ gtree template | gtree mkdir -e .go -e .md -e Makefile
$ tree gtree/
gtree/
โโโ cmd
โ โโโ gtree
โ โโโ main.go
โโโ Makefile
โโโ testdata
โ โโโ sample1.md
โ โโโ sample2.md
โโโ tree.go3 directories, 5 files
```#### *dry run*
Does not create a file and directory.```console
$ gtree template | gtree mkdir --dry-run -e .go -e .md -e Makefile
gtree
โโโ cmd
โ โโโ gtree
โ โโโ main.go
โโโ testdata
โ โโโ sample1.md
โ โโโ sample2.md
โโโ Makefile
โโโ tree.go4 directories, 5 files
```![](assets/cli_mkdir_dryrun.png)
Any invalid file or directory name will result in an error.
```console
$ gtree mkdir --dry-run <WithBranchFormatLastNode
WithEncodeJSON
WithEncodeTOML
WithEncodeYAML
WithMassive|
|*[Mkdir](https://github.com/ddddddO/gtree#mkdir-func)*|can create directories|WithTargetDir
WithFileExtensions
WithDryRun
WithMassive|
|*[Verify](https://github.com/ddddddO/gtree#verify-func)*|can output the difference between markdown and directories|WithTargetDir
WithStrictVerify
WithMassive|
|*[Walk](https://github.com/ddddddO/gtree#walk-func)*|can execute user-defined function while traversing tree structure recursively|WithBranchFormatIntermedialNode
WithBranchFormatLastNode
WithMassive|### *Output* func
```go
package mainimport (
"bytes"
"fmt"
"os"
"strings""github.com/ddddddO/gtree"
)func main() {
r1 := bytes.NewBufferString(strings.TrimSpace(`
- root
- dddd
- kkkkkkk
- lllll
- ffff
- LLL
- WWWWW
- ZZZZZ
- ppppp
- KKK
- 1111111
- AAAAAAA
- eee`))
if err := gtree.Output(os.Stdout, r1); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// root
// โโโ dddd
// โ โโโ kkkkkkk
// โ โโโ lllll
// โ โโโ ffff
// โ โโโ LLL
// โ โ โโโ WWWWW
// โ โ โโโ ZZZZZ
// โ โโโ ppppp
// โ โโโ KKK
// โ โโโ 1111111
// โ โโโ AAAAAAA
// โโโ eeer2 := bytes.NewBufferString(strings.TrimSpace(`
- a
- i
- u
- k
- kk
- t
- e
- o
- g`))// You can customize branch format.
if err := gtree.Output(os.Stdout, r2,
gtree.WithBranchFormatIntermedialNode("+->", ": "),
gtree.WithBranchFormatLastNode("+->", " "),
); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// a
// +-> i
// : +-> u
// : : +-> k
// : : +-> kk
// : +-> t
// +-> e
// : +-> o
// +-> g
}```
#### You can also output JSON/YAML/TOML.
- `gtree.WithEncodeJSON()`
- `gtree.WithEncodeTOML()`
- `gtree.WithEncodeYAML()`### *Mkdir* func
#### `gtree.Mkdir` func makes directories.
You can use `gtree.WithFileExtensions` func to make specified extensions as file.
### *Verify* func
#### `gtree.Verify` func verifies directories.
You can use `gtree.WithTargetDir` func / `gtree.WithStrictVerify` func.
### *Walk* func
See sample program
```go
package mainimport (
"fmt"
"os"
"strings""github.com/ddddddO/gtree"
)func main() {
src := strings.TrimSpace(`
- a
- i
- u
- k
- kk
- t
- e
- o
- g`)callback := func(wn *gtree.WalkerNode) error {
fmt.Println(wn.Row())
return nil
}if err := gtree.Walk(strings.NewReader(src), callback); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// a
// โโโ i
// โ โโโ u
// โ โโโ k
// โโโ kk
// โโโ t
// e
// โโโ o
// โโโ gcallback2 := func(wn *gtree.WalkerNode) error {
fmt.Println("WalkerNode's methods called...")
fmt.Printf("\tName : %s\n", wn.Name())
fmt.Printf("\tBranch : %s\n", wn.Branch())
fmt.Printf("\tRow : %s\n", wn.Row())
fmt.Printf("\tLevel : %d\n", wn.Level())
fmt.Printf("\tPath : %s\n", wn.Path())
fmt.Printf("\tHasChild : %t\n", wn.HasChild())
return nil
}if err := gtree.Walk(strings.NewReader(src), callback2); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// WalkerNode's methods called...
// Name : a
// Branch :
// Row : a
// Level : 1
// Path : a
// HasChild : true
// WalkerNode's methods called...
// Name : i
// Branch : โโโ
// Row : โโโ i
// Level : 2
// Path : a/i
// HasChild : true
// WalkerNode's methods called...
// Name : u
// Branch : โ โโโ
// Row : โ โโโ u
// Level : 3
// Path : a/i/u
// HasChild : true
// WalkerNode's methods called...
// Name : k
// Branch : โ โโโ
// Row : โ โโโ k
// Level : 4
// Path : a/i/u/k
// HasChild : false
// WalkerNode's methods called...
// Name : kk
// Branch : โโโ
// Row : โโโ kk
// Level : 2
// Path : a/kk
// HasChild : true
// WalkerNode's methods called...
// Name : t
// Branch : โโโ
// Row : โโโ t
// Level : 3
// Path : a/kk/t
// HasChild : false
// WalkerNode's methods called...
// Name : e
// Branch :
// Row : e
// Level : 1
// Path : e
// HasChild : true
// WalkerNode's methods called...
// Name : o
// Branch : โโโ
// Row : โโโ o
// Level : 2
// Path : e/o
// HasChild : true
// WalkerNode's methods called...
// Name : g
// Branch : โโโ
// Row : โโโ g
// Level : 3
// Path : e/o/g
// HasChild : false
}
```inspired by [xlab/treeprint](https://github.com/xlab/treeprint#iterating-over-the-tree-nodes) !
# Library - Programmable tree structure
> [!NOTE]
> The `gonew` command can be used to set up sample project using gtree library.
> See [here](https://github.com/ddddddO/gtree/blob/master/example/README.md) for details.## Installation
Go version requires 1.18 or later.
```console
$ go get github.com/ddddddO/gtree
```## Usage
|Function|Description|Available optional functions|
|--|--|--|
|*[OutputProgrammably](https://github.com/ddddddO/gtree#outputprogrammably-func)*|can output tree|WithBranchFormatIntermedialNode
WithBranchFormatLastNode
WithEncodeJSON
WithEncodeTOML
WithEncodeYAML|
|*[MkdirProgrammably](https://github.com/ddddddO/gtree#mkdirprogrammably-func)*|can create directories|WithTargetDir
WithFileExtensions
WithDryRun|
|*[VerifyProgrammably](https://github.com/ddddddO/gtree#verifyprogrammably-func)*|can output the difference between tree you composed and directories|WithTargetDir
WithStrictVerify|
|*[WalkProgrammably](https://github.com/ddddddO/gtree#walkprogrammably-func)*|can execute user-defined function while traversing tree structure recursively|WithBranchFormatIntermedialNode
WithBranchFormatLastNode|### *OutputProgrammably* func
```go
package mainimport (
"fmt"
"os""github.com/ddddddO/gtree"
)func main() {
var root *gtree.Node = gtree.NewRoot("root")
root.Add("child 1").Add("child 2").Add("child 3")
var child4 *gtree.Node = root.Add("child 1").Add("child 2").Add("child 4")
child4.Add("child 5")
child4.Add("child 6").Add("child 7")
root.Add("child 8")
// you can customize branch format.
if err := gtree.OutputProgrammably(os.Stdout, root,
gtree.WithBranchFormatIntermedialNode("+--", ": "),
gtree.WithBranchFormatLastNode("+--", " "),
); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// root
// +-- child 1
// : +-- child 2
// : +-- child 3
// : +-- child 4
// : +-- child 5
// : +-- child 6
// : +-- child 7
// +-- child 8primate := preparePrimate()
// default branch format.
if err := gtree.OutputProgrammably(os.Stdout, primate); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// Primate
// โโโ Strepsirrhini
// โ โโโ Lemuriformes
// โ โ โโโ Lemuroidea
// โ โ โ โโโ Cheirogaleidae
// โ โ โ โโโ Indriidae
// โ โ โ โโโ Lemuridae
// โ โ โ โโโ Lepilemuridae
// โ โ โโโ Daubentonioidea
// โ โ โโโ Daubentoniidae
// โ โโโ Lorisiformes
// โ โโโ Galagidae
// โ โโโ Lorisidae
// โโโ Haplorrhini
// โโโ Tarsiiformes
// โ โโโ Tarsiidae
// โโโ Simiiformes
// โโโ Platyrrhini
// โ โโโ Ceboidea
// โ โ โโโ Atelidae
// โ โ โโโ Cebidae
// โ โโโ Pithecioidea
// โ โโโ Pitheciidae
// โโโ Catarrhini
// โโโ Cercopithecoidea
// โ โโโ Cercopithecidae
// โโโ Hominoidea
// โโโ Hylobatidae
// โโโ Hominidae
}func preparePrimate() *gtree.Node {
primate := gtree.NewRoot("Primate")
strepsirrhini := primate.Add("Strepsirrhini")
haplorrhini := primate.Add("Haplorrhini")
lemuriformes := strepsirrhini.Add("Lemuriformes")
lorisiformes := strepsirrhini.Add("Lorisiformes")lemuroidea := lemuriformes.Add("Lemuroidea")
lemuroidea.Add("Cheirogaleidae")
lemuroidea.Add("Indriidae")
lemuroidea.Add("Lemuridae")
lemuroidea.Add("Lepilemuridae")lemuriformes.Add("Daubentonioidea").Add("Daubentoniidae")
lorisiformes.Add("Galagidae")
lorisiformes.Add("Lorisidae")haplorrhini.Add("Tarsiiformes").Add("Tarsiidae")
simiiformes := haplorrhini.Add("Simiiformes")platyrrhini := haplorrhini.Add("Platyrrhini")
ceboidea := platyrrhini.Add("Ceboidea")
ceboidea.Add("Atelidae")
ceboidea.Add("Cebidae")
platyrrhini.Add("Pithecioidea").Add("Pitheciidae")catarrhini := simiiformes.Add("Catarrhini")
catarrhini.Add("Cercopithecoidea").Add("Cercopithecidae")
hominoidea := catarrhini.Add("Hominoidea")
hominoidea.Add("Hylobatidae")
hominoidea.Add("Hominidae")return primate
}```
#### The program below converts the result of `find` into a tree.
```go
package mainimport (
"bufio"
"fmt"
"os"
"strings""github.com/ddddddO/gtree"
)// Example:
// $ cd github.com/ddddddO/gtree
// $ find . -type d -name .git -prune -o -type f -print
// ./config.go
// ./node_generator_test.go
// ./example/like_cli/adapter/indentation.go
// ./example/like_cli/adapter/executor.go
// ./example/like_cli/main.go
// ./example/find_pipe_programmable-gtree/main.go
// ...
// $ find . -type d -name .git -prune -o -type f -print | go run example/find_pipe_programmable-gtree/main.go
// << See "Output:" below. >>
func main() {
var (
root *gtree.Node
node *gtree.Node
)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text() // e.g.) "./example/find_pipe_programmable-gtree/main.go"
splited := strings.Split(line, "/") // e.g.) [. example find_pipe_programmable-gtree main.go]for i, s := range splited {
if root == nil {
root = gtree.NewRoot(s) // s := "."
node = root
continue
}
if i == 0 {
continue
}tmp := node.Add(s)
node = tmp
}
node = root
}if err := gtree.OutputProgrammably(os.Stdout, root); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// .
// โโโ config.go
// โโโ node_generator_test.go
// โโโ example
// โ โโโ like_cli
// โ โ โโโ adapter
// โ โ โ โโโ indentation.go
// โ โ โ โโโ executor.go
// โ โ โโโ main.go
// โ โโโ find_pipe_programmable-gtree
// โ โ โโโ main.go
// โ โโโ go-list_pipe_programmable-gtree
// โ โ โโโ main.go
// โ โโโ programmable
// โ โโโ main.go
// โโโ file_considerer.go
// โโโ node.go
// โโโ node_generator.go
// โโโ .gitignore
// ...
}
```### *MkdirProgrammably* func
```go
package mainimport (
"fmt""github.com/ddddddO/gtree"
)func main() {
primate := preparePrimate()
if err := gtree.MkdirProgrammably(primate); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output(using Linux 'tree' command):
// 22:20:43 > tree Primate/
// Primate/
// โโโ Haplorrhini
// โ โโโ Simiiformes
// โ โ โโโ Catarrhini
// โ โ โ โโโ Cercopithecoidea
// โ โ โ โ โโโ Cercopithecidae
// โ โ โ โโโ Hominoidea
// โ โ โ โโโ Hominidae
// โ โ โ โโโ Hylobatidae
// โ โ โโโ Platyrrhini
// โ โ โโโ Ceboidea
// โ โ โ โโโ Atelidae
// โ โ โ โโโ Cebidae
// โ โ โโโ Pithecioidea
// โ โ โโโ Pitheciidae
// โ โโโ Tarsiiformes
// โ โโโ Tarsiidae
// โโโ Strepsirrhini
// โโโ Lemuriformes
// โ โโโ Daubentonioidea
// โ โ โโโ Daubentoniidae
// โ โโโ Lemuroidea
// โ โโโ Cheirogaleidae
// โ โโโ Indriidae
// โ โโโ Lemuridae
// โ โโโ Lepilemuridae
// โโโ Lorisiformes
// โโโ Galagidae
// โโโ Lorisidae
//
// 28 directories, 0 files
}
```[details](https://github.com/ddddddO/gtree/blob/master/example/programmable/main.go#L354)
#### Make directories and files with specific extensions.
```go
package mainimport (
"fmt""github.com/ddddddO/gtree"
)func main() {
gtreeDir := gtree.NewRoot("gtree")
gtreeDir.Add("cmd").Add("gtree").Add("main.go")
gtreeDir.Add("Makefile")
testdataDir := gtreeDir.Add("testdata")
testdataDir.Add("sample1.md")
testdataDir.Add("sample2.md")
gtreeDir.Add("tree.go")// make directories and files with specific extensions.
if err := gtree.MkdirProgrammably(
gtreeDir,
gtree.WithFileExtensions([]string{".go", ".md", "Makefile"}),
); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output(using Linux 'tree' command):
// 09:44:50 > tree gtree/
// gtree/
// โโโ cmd
// โ โโโ gtree
// โ โโโ main.go
// โโโ Makefile
// โโโ testdata
// โ โโโ sample1.md
// โ โโโ sample2.md
// โโโ tree.go
//
// 3 directories, 5 files
}
```### *VerifyProgrammably* func
You can use `gtree.WithTargetDir` func / `gtree.WithStrictVerify` func.
### *WalkProgrammably* func
```go
package mainimport (
"fmt"
"os""github.com/ddddddO/gtree"
)func main() {
root := gtree.NewRoot("root")
root.Add("child 1").Add("child 2").Add("child 3")
root.Add("child 5")
root.Add("child 1").Add("child 2").Add("child 4")callback := func(wn *gtree.WalkerNode) error {
fmt.Println(wn.Row())
return nil
}if err := gtree.WalkProgrammably(root, callback); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// root
// โโโ child 1
// โ โโโ child 2
// โ โโโ child 3
// โ โโโ child 4
// โโโ child 5callback2 := func(wn *gtree.WalkerNode) error {
fmt.Println("WalkerNode's methods called...")
fmt.Printf("\tName : %s\n", wn.Name())
fmt.Printf("\tBranch : %s\n", wn.Branch())
fmt.Printf("\tRow : %s\n", wn.Row())
fmt.Printf("\tLevel : %d\n", wn.Level())
fmt.Printf("\tPath : %s\n", wn.Path())
fmt.Printf("\tHasChild : %t\n", wn.HasChild())
return nil
}if err := gtree.WalkProgrammably(root, callback2); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Output:
// WalkerNode's methods called...
// Name : root
// Branch :
// Row : root
// Level : 1
// Path : root
// HasChild : true
// WalkerNode's methods called...
// Name : child 1
// Branch : โโโ
// Row : โโโ child 1
// Level : 2
// Path : root/child 1
// HasChild : true
// WalkerNode's methods called...
// Name : child 2
// Branch : โ โโโ
// Row : โ โโโ child 2
// Level : 3
// Path : root/child 1/child 2
// HasChild : true
// WalkerNode's methods called...
// Name : child 3
// Branch : โ โโโ
// Row : โ โโโ child 3
// Level : 4
// Path : root/child 1/child 2/child 3
// HasChild : false
// WalkerNode's methods called...
// Name : child 4
// Branch : โ โโโ
// Row : โ โโโ child 4
// Level : 4
// Path : root/child 1/child 2/child 4
// HasChild : false
// WalkerNode's methods called...
// Name : child 5
// Branch : โโโ
// Row : โโโ child 5
// Level : 2
// Path : root/child 5
// HasChild : false
}
```# Process
> [!NOTE]
> This process is for the Massive Roots mode.## e.g. [*gtree/pipeline_tree.go*](https://github.com/ddddddO/gtree/blob/master/pipeline_tree.go)
# Performance
> [!WARNING]
> Depends on the environment.- Comparison simple implementation and pipeline implementation.
- In the case of few Roots, simple implementation is faster in execution!
- Use this one by default.
- However, for multiple Roots, pipeline implementation execution speed tends to be faster๐ชโจ
- In the CLI, it is available by specifying `--massive`.
- In the Go program, it is available by specifying `WithMassive` func.Benchmark log
## Simple implementation
```console
11:19:22 > go test -benchmem -bench Benchmark -benchtime 100x benchmark_simple_test.go
goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
BenchmarkOutput_singleRoot-4 100 35375 ns/op 13856 B/op 171 allocs/op
BenchmarkOutput_tenRoots-4 100 200540 ns/op 72920 B/op 1597 allocs/op
BenchmarkOutput_fiftyRoots-4 100 730156 ns/op 569851 B/op 7919 allocs/op
BenchmarkOutput_hundredRoots-4 100 1706493 ns/op 1714260 B/op 15820 allocs/op
BenchmarkOutput_fiveHundredsRoots-4 100 16412090 ns/op 32245140 B/op 79022 allocs/op
BenchmarkOutput_thousandRoots-4 100 55142492 ns/op 120929674 B/op 158025 allocs/op
BenchmarkOutput_3000Roots-4 100 489121246 ns/op 1035617527 B/op 474029 allocs/op
BenchmarkOutput_6000Roots-4 100 1613641261 ns/op 4087694372 B/op 948033 allocs/op
BenchmarkOutput_10000Roots-4 100 3913090646 ns/op 11293191221 B/op 1580035 allocs/op
PASS
ok command-line-arguments 614.944s
```## Pipeline implementation
```console
11:29:43 > go test -benchmem -bench Benchmark -benchtime 100x benchmark_pipeline_test.go
goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
BenchmarkOutput_pipeline_singleRoot-4 100 188706 ns/op 24236 B/op 300 allocs/op
BenchmarkOutput_pipeline_tenRoots-4 100 367758 ns/op 115970 B/op 2186 allocs/op
BenchmarkOutput_pipeline_fiftyRoots-4 100 947879 ns/op 542188 B/op 10592 allocs/op
BenchmarkOutput_pipeline_hundredRoots-4 100 1711537 ns/op 1099636 B/op 21094 allocs/op
BenchmarkOutput_pipeline_fiveHundredsRoots-4 100 6892261 ns/op 5524905 B/op 105107 allocs/op
BenchmarkOutput_pipeline_thousandRoots-4 100 13100335 ns/op 11225942 B/op 210115 allocs/op
BenchmarkOutput_pipeline_3000Roots-4 100 40694497 ns/op 33399766 B/op 630142 allocs/op
BenchmarkOutput_pipeline_6000Roots-4 100 85807944 ns/op 66974524 B/op 1260171 allocs/op
BenchmarkOutput_pipeline_10000Roots-4 100 151486713 ns/op 113908462 B/op 2100208 allocs/op
PASS
ok command-line-arguments 30.670s
```# Documents
- [GoDoc](https://pkg.go.dev/github.com/ddddddO/gtree)## English
- [Want to output a tree in Go?](https://medium.com/@allowing_whip_guineapig_430/want-to-output-a-tree-in-go-1851f9fc9900)
- [Generate directory trees๐ณ and the directories itself๐ using Markdown or Programmatically.](https://www.reddit.com/r/commandline/comments/146nk54/generate_directory_trees_and_the_directories/)## Japanese
- [Goใงtreeใ่กจ็พใใ](https://zenn.dev/ddddddo/articles/8cd85c68763f2e)
- [Markdownๅฝขๅผใฎๅ ฅๅใใtreeใๅบๅใใCLI/Web](https://zenn.dev/ddddddo/articles/ad97623a004496)
- [Markdownๅฝขๅผใฎๅ ฅๅใใใใกใคใซ/ใใฃใฌใฏใใชใ็ๆใใCLI/Goใใใฑใผใธ](https://zenn.dev/ddddddo/articles/460d12e8c07763)
- [็ๆ ฝ (็ฏ็ฎใฎ่จไบ)](https://zenn.dev/openlogi/articles/f6cc91ac413c8f)
- [ๆๆณ](https://scrapbox.io/ddddddo/useful_tools)# Test coverage
![treemap](/assets/test_treemap.svg)...generated by [nikolaydubina/go-cover-treemap](https://github.com/nikolaydubina/go-cover-treemap) !
# Stargazers over time
[![Stargazers over time](https://starchart.cc/ddddddO/gtree.svg?variant=adaptive)](https://starchart.cc/ddddddO/gtree)[^1]: Gopher retrieved from [egonelbre/gophers](https://github.com/egonelbre/gophers) !