Пример #1
0
// Rewrite rewrites files to the local path.
func (ctx *Context) rewrite() error {
	if !ctx.rewriteImports {
		return nil
	}
	if ctx.dirty {
		ctx.loadPackage()
	}
	ctx.dirty = true

	fileImports := make(map[string]map[string]*File) // map[ImportPath]map[FilePath]File
	for _, pkg := range ctx.Package {
		for _, f := range pkg.Files {
			for _, imp := range f.Imports {
				fileList := fileImports[imp]
				if fileList == nil {
					fileList = make(map[string]*File, 1)
					fileImports[imp] = fileList
				}
				fileList[f.Path] = f
			}
		}
	}
	filePaths := make(map[string]*File, len(ctx.RewriteRule))
	for from, to := range ctx.RewriteRule {
		// Add files that contain an import path to rewrite.
		for _, f := range fileImports[from] {
			filePaths[f.Path] = f
		}

		// Add files that contain import comments to remove.
		if pkg := ctx.Package[from]; pkg != nil {
			for _, f := range pkg.Files {
				if len(f.ImportComment) != 0 {
					filePaths[f.Path] = f
				}
			}
		}
		if pkg := ctx.Package[to]; pkg != nil {
			for _, f := range pkg.Files {
				if len(f.ImportComment) != 0 {
					filePaths[f.Path] = f
				}
			}
		}
	}

	/*
		RULE: co2/internal/co3/pk3 -> co1/internal/co3/pk3

		i co1/internal/co2/pk2 [co2/pk2] < ["co1/pk1"]
		i co1/internal/co3/pk3 [co3/pk3] < ["co1/pk1"]
		e co2/internal/co3/pk3 [co3/pk3] < ["co1/internal/co2/pk2"]
		l co1/pk1 < []
		s strings < ["co1/internal/co3/pk3" "co2/internal/co3/pk3"]

		Rewrite the package "co1/internal/co2/pk2" because it references a package with a rewrite.from package.
	*/
	ctx.updatePackageReferences()
	for from := range ctx.RewriteRule {
		pkg := ctx.Package[from]
		if pkg == nil {
			continue
		}
		for _, ref := range pkg.referenced {
			for _, f := range ref.Files {
				dprintf("REF RW %s\n", f.Path)
				filePaths[f.Path] = f
			}
		}
	}

	defer func() {
		ctx.RewriteRule = make(map[string]string, 3)
	}()

	if len(ctx.RewriteRule) == 0 {
		return nil
	}
	goprint := &printer.Config{
		Mode:     printer.TabIndent | printer.UseSpaces,
		Tabwidth: 8,
	}
	for _, fileInfo := range filePaths {
		if pathos.FileHasPrefix(fileInfo.Path, ctx.RootDir) == false {
			continue
		}

		// Read the file into AST, modify the AST.
		fileset := token.NewFileSet()
		f, err := parser.ParseFile(fileset, fileInfo.Path, nil, parser.ParseComments)
		if err != nil {
			return err
		}

		dprintf("RW:: File: %s\n", fileInfo.Path)

		for _, impNode := range f.Imports {
			imp, err := strconv.Unquote(impNode.Path.Value)
			if err != nil {
				return err
			}
			for from, to := range ctx.RewriteRule {
				if imp != from {
					continue
				}
				impNode.Path.Value = strconv.Quote(to)
				for i, metaImport := range fileInfo.Imports {
					if from == metaImport {
						dprintf("\tImport: %s -> %s\n", from, to)
						fileInfo.Imports[i] = to
					}
				}
				break
			}
		}

		// Remove import comment.
		st := fileInfo.Package.Status
		if fileInfo.Package.inVendor || st == StatusUnused || st == StatusExternal {
			var ic *ast.Comment
			if f.Name != nil {
				pos := f.Name.Pos()
			big:
				// Find the next comment after the package name.
				for _, cblock := range f.Comments {
					for _, c := range cblock.List {
						if c.Pos() > pos {
							ic = c
							break big
						}
					}
				}
			}
			if ic != nil {
				// If it starts with the import text, assume it is the import comment and remove.
				if index := strings.Index(ic.Text, " import "); index > 0 && index < 5 {
					ic.Text = strings.Repeat(" ", len(ic.Text))
				}
			}
		}

		// Don't sort or modify the imports to minimize diffs.

		// Write the AST back to disk.
		fi, err := os.Stat(fileInfo.Path)
		if err != nil {
			return err
		}
		w, err := safefile.Create(fileInfo.Path, fi.Mode())
		if err != nil {
			return err
		}
		err = goprint.Fprint(w, fileset, f)
		if err != nil {
			w.Close()
			return err
		}
		err = w.Commit()
		if err != nil {
			return err
		}
	}
	return nil
}
Пример #2
0
func main() {
	flag.Parse()
	defer func() {
		if err := recover(); err != nil {
			panic(err)
		}
	}()
	if *boxName == "" {
		log.Fatal("boxName parameter required")
	}

	db := GetDatabase()

	// Query deleted datasets
	deletedQuery := bson.M{
		"$and": []bson.M{
			bson.M{"state": "deleted"},
			bson.M{"boxServer": *boxName}}}

	// Query all deleted dataset box names along with the view box names
	q := db.C("datasets").Find(deletedQuery).Select(bson.M{})
	q = q.Select(bson.M{"box": 1, "views.box": 1, "views.boxServer": 1})

	var datasets []Dataset
	err := q.All(&datasets)
	check(err)

	// Build map of deleted boxes, looking through all dataset.Views
	badBoxes := map[string]struct{}{}
	for _, dataset := range datasets {
		badBoxes[dataset.Box] = struct{}{}
		for _, view := range dataset.Views {
			badBoxes[view.Box] = struct{}{}
		}
	}

	q = db.C("boxes").Find(bson.M{"server": *boxName})
	q = q.Select(bson.M{"name": 1, "uid": 1})

	var boxes []Box
	err = q.All(&boxes)
	check(err)

	goodBoxes := []Box{}
	for _, box := range boxes {
		if _, deleted := badBoxes[box.Name]; deleted {
			continue
		}
		goodBoxes = append(goodBoxes, box)
	}

	passwd, err := safefile.Create("passwd", 0666)
	check(err)
	defer passwd.Close()
	for _, box := range boxes {
		fmt.Fprintf(passwd, "%v:x:%v:10000::/home:/bin/bash\n", box.Name, box.Uid)
	}

	shadow, err := safefile.Create("shadow", 0666)
	check(err)
	defer shadow.Close()
	for _, box := range boxes {
		fmt.Fprintf(shadow, "%v:x:15607:0:99999:7:::\n", box.Name)
	}

	err = passwd.Commit()
	check(err)
	err = shadow.Commit()
	check(err)

	log.Printf("Generated len(%v) passwd file (%v deleted)", len(goodBoxes), len(boxes)-len(goodBoxes))
}