Example #1
0
func main() {
	cmd.UnixIO("err")
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("u", "unix IO", &ux)
	opts.NewFlag("g", "get contents", &gflag)
	if cmd.Args()[0] == "gf" {
		gflag = true
	}
	args := opts.Parse()
	if ux {
		cmd.UnixIO()
	}
	if len(args) == 0 {
		args = append(args, ".,1")
	}

	var dc <-chan face{}
	if !gflag {
		dc = cmd.Dirs(args...)
	} else {
		dc = cmd.Files(args...)
	}

	out := cmd.Out("out")
	var err error
	for m := range dc {
		cmd.Dprintf("got %T\n", m)
		switch m := m.(type) {
		case error:
			err = m
			cmd.Warn("%s", m)
			if !ux {
				m := fmt.Errorf("%s: %s", cmd.Args()[0], m)
				if ok := out <- m; !ok {
					close(dc, cerror(out))
				}
			}
		case zx.Dir:
			if !ux {
				if ok := out <- m; !ok {
					close(dc, cerror(out))
				}
			} else {
				printf("%s\n", m.Fmt())
			}
		case []byte:
			if ok := out <- m; !ok {
				close(dc, cerror(out))
			}
		}
	}
	if err := cerror(dc); err != nil {
		if !ux {
			out <- fmt.Errorf("%s: %s", cmd.Args()[0], err)
		}
		cmd.Exit(err)
	}
	cmd.Exit(err)
}
Example #2
0
func find(dump, dpref, rel string, dc chan<- zx.Dir, ufile zx.Dir) {
	droot := fpath.Join(dump, dpref)
	years, err := cmd.GetDir(droot)
	if err != nil {
		cmd.Warn("%s", err)
		return
	}
	for i := len(years) - 1; i >= 0; i-- {
		year := years[i]["name"]
		if ignored(year, "") {
			continue
		}
		ypath := years[i]["path"]
		days, err := cmd.GetDir(ypath)
		if err != nil {
			cmd.Warn("%s: %s", ypath, err)
			continue
		}
		lastsz, lastmt, lastm := "", "", ""
		for j := len(days) - 1; j >= 0; j-- {
			day := days[j]["name"]
			if ignored(year, day) {
				continue
			}
			fpath := fpath.Join(days[j]["path"], rel)
			d, err := cmd.Stat(fpath)
			if err != nil {
				if !force {
					cmd.Dprintf("find: %s", err)
					return
				}
				continue
			}
			newm, newsz, newmt := d["mode"], d["size"], d["mtime"]
			if newsz == lastsz && newmt == lastmt && newm == lastm {
				continue
			}
			lastm, lastsz, lastmt = newm, newsz, newmt
			d["upath"] = ufile["path"]
			d["uupath"] = ufile["upath"]
			if ok := dc <- d; !ok {
				return
			}
			if !all {
				return
			}
		}
	}
}

func report(dc chan zx.Dir, donec chan bool) {
	last := ""
	for d := range dc {
		if last == "" {
			last = d["Upath"]
			if last == "" {
				last = d["path"]
			}
		}
		p := d["path"]
		cmd.Dprintf("found '%s'\n", p)
		var err error
		switch {
		case xcmd != "":
			_, err = cmd.Printf("%s %s %s\n", xcmd, p, last)
		case dflag:
			dcmd := fmt.Sprintf(`9 diff -n %s %s`, p, last)
			_, err = cmd.Printf("%s\n", dcmd)
			if err != nil {
				cmd.Warn("diff: %s", err)
				continue
			}
		case lflag:
			_, err = cmd.Printf("%s\n", d.Fmt())
		case cflag:
			_, err = cmd.Printf("cp %s %s\n", p, d["Upath"])
		default:
			_, err = cmd.Printf("%s\n", d["path"])
		}
		if err != nil {
			close(dc, err)
		}
		last = p
	}
	close(donec, cerror(dc))
}

func hist(in <-chan face{}) error {
	dc := make(chan zx.Dir)
	ec := make(chan bool)
	go report(dc, ec)
	var sts error
	for m := range in {
		switch m := m.(type) {
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", m, m["path"])
			file := m["path"]
			if m["upath"] == "" {
				m["upath"] = m["path"]
			}
			ddir := dump
			dpref := ""
			rel := ""
			switch {
			case zx.HasPrefix(file, "/zx"):
				if ddir == "" {
					ddir = "/dump"
				}
				dpref = "/zx"
				rel = zx.Suffix(file, "/zx")
			case zx.HasPrefix(file, "/u/gosrc/src/clive"):
				if ddir == "" {
					ddir = "/u/dump"
				}
				dpref = "clive"
				rel = zx.Suffix(file, "/u/gosrc/src/clive")
			case zx.HasPrefix(file, "/u"):
				if ddir == "" {
					ddir = "/u/dump"
				}
				els := zx.Elems(file)
				if len(els) < 3 {
					cmd.Warn("%s: too few path elements", m["upath"])
					sts = errNoDump
					continue
				}
				dpref = els[1]
				rel = zx.Path(els[2:]...)
			default:
				cmd.Warn("%s: %s", m["upath"], errNoDump)
				sts = errNoDump
				continue
			}
			find(ddir, dpref, rel, dc, m.Dup())
		default:
			cmd.Dprintf("got %T\n", m)

		}
	}
	close(dc, cerror(in))
	<-ec
	if sts == nil {
		sts = cerror(ec)
	}
	if sts == nil {
		sts = cerror(in)
	}
	return sts
}

// Run cnt in the current app context.
func main() {
	c := cmd.AppCtx()
	cmd.UnixIO("err")
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("f", "force search past file removals", &force)
	opts.NewFlag("l", "produce a long listing (or print just the name)", &lflag)
	opts.NewFlag("c", "copy the file from the dump", &cflag)
	opts.NewFlag("d", "print file differences", &dflag)
	opts.NewFlag("x", "cmd: print lines to execute this command between versions", &xcmd)
	opts.NewFlag("a", "list all copies that differ, not just the last one.", &all)
	opts.NewFlag("p", "dumpdir: path to dump (default is /dump or /u/dump)", &dump)
	t := time.Now()
	when := t
	opts.NewFlag("w", "date: backward search start time (default is now)", &when)
	ux := false
	opts.NewFlag("u", "unix IO", &ux)
	args := opts.Parse()
	if (all && cflag) || (force && !all) {
		cmd.Warn("incompatible flags")
		opts.Usage()
	}
	if ux {
		cmd.UnixIO("out")
	}
	lastyear = ""
	lastday = ""
	if !t.Equal(when) {
		y := when.Year()
		m := when.Month()
		d := when.Day()
		if y == 0 {
			y = t.Year()
		}
		lastyear = fmt.Sprintf("%04d", y)
		lastday = fmt.Sprintf("%02d%02d", m, d)
	}
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Dirs(args...))
	}
	in := cmd.In("in")
	if err := hist(in); err != nil {
		cmd.Fatal(err)
	}
}
Example #3
0
// Run rem in the current app context.
func main() {
	c := cmd.AppCtx()
	cmd.UnixIO("err")
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("v", "verbose; print the calls made in the order they are made.", &c.Verb)
	opts.NewFlag("a", "remove all", &aflag)
	opts.NewFlag("f", "quiet, called 'force' in unix", &fflag)
	opts.NewFlag("n", "dry run; report removes but do not do them", &dry)
	args := opts.Parse()
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Dirs(args...))
	}
	c.Verb = c.Verb || dry
	in := cmd.In("in")
	var err error
	for m := range in {
		switch d := m.(type) {
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", d, d["upath"])
			dirs = append(dirs, d)
		case error:
			cmd.Warn("%s", d)
		default:
			// ignored
			cmd.Dprintf("ignored %T\n", m)
		}
	}
	if aflag {
		for i := 0; i < len(dirs); i++ {
			if dirs[i] == nil {
				continue
			}
			pi := dirs[i]["path"]
			for j := 1; j < len(dirs); j++ {
				if i == j || dirs[j] == nil {
					continue
				}
				pj := dirs[j]["path"]
				if zx.HasPrefix(pj, pi) {
					dirs[j] = nil
				}
			}
		}
	}
	for i := len(dirs) - 1; i >= 0; i-- {
		if dirs[i] == nil {
			continue
		}
		if cerr := rmf(dirs[i]); cerr != nil {
			if !fflag {
				cmd.Warn("%s", cerr)
				err = cerr
			}
		}
	}
	if err == nil {
		err = cerror(in)
		if err != nil {
			cmd.Fatal(err)
		}
	}
	cmd.Exit(err)
}