Skip to content

Instantly share code, notes, and snippets.

@mikedanese
Last active May 14, 2020 02:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikedanese/085817670b09eff6a05260e03e61a633 to your computer and use it in GitHub Desktop.
Save mikedanese/085817670b09eff6a05260e03e61a633 to your computer and use it in GitHub Desktop.
migrate
module k8s.io/kubectx/migrate
go 1.13
require golang.org/x/tools v0.0.0-20200206010605-531cc8856e55
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200206010605-531cc8856e55 h1:kDk+lF3Oi/w2ujHLfJ8PCevhlfj7GFgH9A0dpxaJvYA=
golang.org/x/tools v0.0.0-20200206010605-531cc8856e55/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
// Command migrate moves imports to the deprecated paths.
//
// Run with:
//
// migrate **/*.go
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
"golang.org/x/tools/go/ast/astutil"
)
var migratedPkgs = map[string]string{
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset": "k8s.io/apiextensions-apiserver/pkg/client/clientset/deprecated",
"k8s.io/client-go/kubernetes": "k8s.io/client-go/deprecated",
"k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset": "k8s.io/kube-aggregator/pkg/client/clientset_generated/deprecated",
"k8s.io/metrics/pkg/client/clientset/versioned": "k8s.io/metrics/pkg/client/clientset/deprecated",
}
func main() {
paths := os.Args[1:]
for _, path := range paths {
if err := migrate(path); err != nil {
}
}
}
type edit struct {
start, end int
data []byte
}
func migrate(path string) error {
src, err := ioutil.ReadFile(path)
if err != nil {
return err
}
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, src, parser.ImportsOnly)
if err != nil {
return err
}
var edits []edit
for _, group := range astutil.Imports(fset, f) {
for _, imp := range group {
to, ok := toPath(fset, imp)
if !ok {
continue
}
var buf bytes.Buffer
if err := format.Node(&buf, fset, to); err != nil {
return err
}
edits = append(edits, edit{
start: fset.File(f.Pos()).Offset(imp.Pos()),
end: fset.File(f.Pos()).Offset(imp.End()),
data: buf.Bytes(),
})
}
}
return applyEdits(path, src, edits)
}
func toPath(fset *token.FileSet, from *ast.ImportSpec) (*ast.ImportSpec, bool) {
fromPath, err := strconv.Unquote(from.Path.Value)
if err != nil {
panic(err)
}
for src, target := range migratedPkgs {
if strings.HasPrefix(fromPath, src) {
base := strings.TrimPrefix(fromPath, src)
toPath := path.Join(target, base)
to := &ast.ImportSpec{
Doc: from.Doc,
Name: from.Name,
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote(toPath),
},
Comment: from.Comment,
}
if to.Name == nil && fromPath == src {
to.Name = &ast.Ident{
Name: path.Base(fromPath),
}
}
fmt.Printf("%v: from=%q to=%q\n", fset.Position(from.Pos()), fromPath, toPath)
return to, true
}
}
return nil, false
}
func applyEdits(path string, src []byte, edits []edit) error {
if len(edits) == 0 {
return nil
}
var last int
var buf bytes.Buffer
for _, e := range edits {
buf.Write(src[last:e.start])
buf.Write(e.data)
last = e.end
}
buf.Write(src[last:len(src)])
return ioutil.WriteFile(path, buf.Bytes(), 0666)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment