| // Copyright 2020 The Wuffs Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| //go:build ignore |
| // +build ignore |
| |
| package main |
| |
| // print-file-sizes-json.go prints a JSON object containing the names and sizes |
| // of the files and directories under the current working directory, |
| // recursively. |
| // |
| // A directory is printed as a JSON object whose keys are its children's names. |
| // Child directories' values are also JSON objects. Child files' values are the |
| // file size as a JSON number. |
| // |
| // A directory's JSON object also contains a key-value pair for the empty |
| // string key. Its value is the sum of all children and descendent file sizes. |
| // Note that this is just the total raw file size, and does not account for any |
| // file system overhead for directories or for rounding up a file sizes to a |
| // multiple of a disk block size. |
| |
| import ( |
| "encoding/json" |
| "os" |
| "path/filepath" |
| "strings" |
| ) |
| |
| func main() { |
| if err := main1(); err != nil { |
| os.Stderr.WriteString(err.Error() + "\n") |
| os.Exit(1) |
| } |
| } |
| |
| func main1() error { |
| root := dir{"": int64(0)} |
| |
| if err := filepath.Walk(".", func(path string, info os.FileInfo, walkErr error) error { |
| if walkErr != nil { |
| return walkErr |
| } |
| if (path != "") && (path[0] == '.') { |
| if info.IsDir() && (path != ".") { |
| return filepath.SkipDir |
| } |
| return nil |
| } |
| path = filepath.ToSlash(path) |
| |
| ancestors := []dir{} |
| d := root |
| for remaining := ""; len(path) > 0; path = remaining { |
| ancestors = append(ancestors, d) |
| if i := strings.IndexByte(path, '/'); i >= 0 { |
| path, remaining = path[:i], path[i+1:] |
| } else { |
| remaining = "" |
| } |
| if (remaining == "") && !info.IsDir() { |
| n := info.Size() |
| d[path] = n |
| for _, a := range ancestors { |
| a[""] = a[""].(int64) + n |
| } |
| } else if next, ok := d[path]; ok { |
| d = next.(dir) |
| } else { |
| next := dir{"": int64(0)} |
| d[path] = next |
| d = next |
| } |
| } |
| |
| return nil |
| }); err != nil { |
| return err |
| } |
| |
| if enc, err := json.Marshal(root); err != nil { |
| return err |
| } else { |
| os.Stdout.Write(enc) |
| } |
| return nil |
| } |
| |
| type dir map[string]interface{} |