blob: 89e3c7b34cdf9f9d8a05d067e75c1cf15d7043ee [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
15// +build ignore
16
17package main
18
19// print-file-sizes-json.go prints a JSON object containing the names and sizes
20// of the files and directories under the current working directory,
21// recursively.
22//
23// A directory is printed as a JSON object whose keys are its children's names.
24// Child directories' values are also JSON objects. Child files' values are the
25// file size as a JSON number.
26//
27// A directory's JSON object also contains a key-value pair for the empty
28// string key. Its value is the sum of all children and descendent file sizes.
29// Note that this is just the total raw file size, and does not account for any
30// file system overhead for directories or for rounding up a file sizes to a
31// multiple of a disk block size.
32
33import (
34 "encoding/json"
35 "os"
36 "path/filepath"
37 "strings"
38)
39
40func main() {
41 if err := main1(); err != nil {
42 os.Stderr.WriteString(err.Error() + "\n")
43 os.Exit(1)
44 }
45}
46
47func main1() error {
48 root := dir{"": int64(0)}
49
50 if err := filepath.Walk(".", func(path string, info os.FileInfo, walkErr error) error {
51 if walkErr != nil {
52 return walkErr
53 }
54 if (path != "") && (path[0] == '.') {
55 if info.IsDir() && (path != ".") {
56 return filepath.SkipDir
57 }
58 return nil
59 }
60 path = filepath.ToSlash(path)
61
62 ancestors := []dir{}
63 d := root
64 for remaining := ""; len(path) > 0; path = remaining {
65 ancestors = append(ancestors, d)
66 if i := strings.IndexByte(path, '/'); i >= 0 {
67 path, remaining = path[:i], path[i+1:]
68 } else {
69 remaining = ""
70 }
71 if (remaining == "") && !info.IsDir() {
72 n := info.Size()
73 d[path] = n
74 for _, a := range ancestors {
75 a[""] = a[""].(int64) + n
76 }
77 } else if next, ok := d[path]; ok {
78 d = next.(dir)
79 } else {
80 next := dir{"": int64(0)}
81 d[path] = next
82 d = next
83 }
84 }
85
86 return nil
87 }); err != nil {
88 return err
89 }
90
91 if enc, err := json.Marshal(root); err != nil {
92 return err
93 } else {
94 os.Stdout.Write(enc)
95 }
96 return nil
97}
98
99type dir map[string]interface{}