Last active
December 11, 2015 18:09
-
-
Save pcarrier/4639579 to your computer and use it in GitHub Desktop.
"Hardlink" a tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "flag" | |
| "log" | |
| "os" | |
| "path" | |
| ) | |
| var src = flag.String("src", "/usr", "source path") | |
| var dst = flag.String("dst", "/usr.copy", "destination path") | |
| func copyEntries(src string, dst string) error { | |
| f, err := os.Open(src) | |
| if err != nil { | |
| f.Close() | |
| return err | |
| } | |
| infos, err := f.Readdir(-1) | |
| f.Close() | |
| if err != nil { | |
| return err | |
| } | |
| errs := make(chan error, len(infos)) | |
| for _, info := range infos { | |
| go func(info os.FileInfo) { | |
| csrc := path.Join(src, info.Name()) | |
| cdst := path.Join(dst, info.Name()) | |
| errs <- copy(csrc, cdst, info) | |
| }(info) | |
| } | |
| for i := 0; i < len(infos); i++ { | |
| if err := <-errs; err != nil { | |
| return err | |
| } | |
| } | |
| return nil | |
| } | |
| func copy(src string, dst string, fi os.FileInfo) error { | |
| mod := fi.Mode() | |
| switch { | |
| case mod&os.ModeSymlink != 0: | |
| if tgt, err := os.Readlink(src); err != nil { | |
| return err | |
| } else { | |
| if err := os.Symlink(tgt, dst); err != nil { | |
| return err | |
| } | |
| } | |
| case mod&os.ModeDir != 0: | |
| if err := os.Mkdir(dst, mod); err != nil { | |
| return err | |
| } | |
| if err := copyEntries(src, dst); err != nil { | |
| return err | |
| } | |
| default: | |
| if err := os.Link(src, dst); err != nil { | |
| return err | |
| } | |
| } | |
| return nil | |
| } | |
| func main() { | |
| flag.Parse() | |
| if err := os.Mkdir(*dst, 0755); err != nil && !os.IsExist(err) { | |
| log.Fatal(err) | |
| } | |
| if err := copyEntries(*src, *dst); err != nil { | |
| log.Fatal(err) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| require 'find' | |
| exit 1 unless ARGV.length == 2 | |
| SRC, DST = ARGV | |
| def clone_dir srcdir, dstdir | |
| Dir.entries(srcdir).each do |e| | |
| next if %w[. ..].include? e | |
| src = File.join srcdir, e | |
| dst = File.join dstdir, e | |
| stat = File::lstat src | |
| case true | |
| when stat.directory? | |
| Dir.mkdir dst | |
| clone_dir src, dst | |
| when stat.file? | |
| File.link src, dst | |
| when stat.symlink? | |
| File.symlink File.readlink(src), dst | |
| end | |
| end | |
| end | |
| Dir.mkdir DST | |
| clone_dir SRC, DST |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env coffee | |
| fs = require 'fs' | |
| path = require 'path' | |
| copyEntries = (src, dst) -> | |
| fs.readdir src, (err, files) -> | |
| for file in files | |
| s = path.join src, file | |
| d = path.join dst, file | |
| copy s, d | |
| copy = (src, dst) -> | |
| fs.lstat src, (err, stat) -> | |
| switch true | |
| when stat.isFile() | |
| fs.link src, dst, (err) -> | |
| if err? and err.code != 'EEXIST' | |
| console.log err.stack | |
| when stat.isDirectory() | |
| fs.mkdir dst, 0o0755, (err) -> | |
| if err? and err.code != 'EEXIST' | |
| console.log err.stack | |
| else | |
| copyEntries src, dst | |
| when stat.isSymbolicLink() | |
| fs.readlink src, (err, lsrc) -> | |
| if err? and err.code != 'EEXIST' | |
| console.log err.stack | |
| else | |
| fs.symlink lsrc, dst | |
| else | |
| console.log "#{src} not handled (#{stat})" | |
| return null # tiny optimization | |
| if require.main is module | |
| args = process.argv[2..] | |
| if args.length != 2 | |
| console.log "invalid usage!" | |
| process.exit 1 | |
| else | |
| fs.mkdir args[1], 0o0755, (err) -> | |
| if err and err.code != 'EEXIST' | |
| console.log err.stack | |
| else | |
| copy args... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment