blob: b527c37bc346e2945fcd3607283298f045d9735f [file] [log] [blame]
Nigel Taoa540fbc2020-02-25 15:54:53 +11001// Copyright 2020 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nigel Tao788479d2021-08-22 10:52:51 +100015//go:build ignore
Nigel Taoa540fbc2020-02-25 15:54:53 +110016// +build ignore
17
18package main
19
20// print-file-sizes-json.go prints a JSON object containing the names and sizes
21// of the files and directories under the current working directory,
22// recursively.
23//
24// A directory is printed as a JSON object whose keys are its children's names.
25// Child directories' values are also JSON objects. Child files' values are the
26// file size as a JSON number.
27//
28// A directory's JSON object also contains a key-value pair for the empty
29// string key. Its value is the sum of all children and descendent file sizes.
30// Note that this is just the total raw file size, and does not account for any
31// file system overhead for directories or for rounding up a file sizes to a
32// multiple of a disk block size.
33
34import (
35 "encoding/json"
36 "os"
37 "path/filepath"
38 "strings"
39)
40
41func main() {
42 if err := main1(); err != nil {
43 os.Stderr.WriteString(err.Error() + "\n")
44 os.Exit(1)
45 }
46}
47
48func main1() error {
49 root := dir{"": int64(0)}
50
51 if err := filepath.Walk(".", func(path string, info os.FileInfo, walkErr error) error {
52 if walkErr != nil {
53 return walkErr
54 }
55 if (path != "") && (path[0] == '.') {
56 if info.IsDir() && (path != ".") {
57 return filepath.SkipDir
58 }
59 return nil
60 }
61 path = filepath.ToSlash(path)
62
63 ancestors := []dir{}
64 d := root
65 for remaining := ""; len(path) > 0; path = remaining {
66 ancestors = append(ancestors, d)
67 if i := strings.IndexByte(path, '/'); i >= 0 {
68 path, remaining = path[:i], path[i+1:]
69 } else {
70 remaining = ""
71 }
72 if (remaining == "") && !info.IsDir() {
73 n := info.Size()
74 d[path] = n
75 for _, a := range ancestors {
76 a[""] = a[""].(int64) + n
77 }
78 } else if next, ok := d[path]; ok {
79 d = next.(dir)
80 } else {
81 next := dir{"": int64(0)}
82 d[path] = next
83 d = next
84 }
85 }
86
87 return nil
88 }); err != nil {
89 return err
90 }
91
92 if enc, err := json.Marshal(root); err != nil {
93 return err
94 } else {
95 os.Stdout.Write(enc)
96 }
97 return nil
98}
99
100type dir map[string]interface{}