blob: 5de1e44062d49c9bf64df5c94cc3cbf4c96ba787 [file] [log] [blame]
Michael Matloob796e50b2014-12-20 15:33:48 -08001// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
Rebecca Stamblerd33bae42021-01-07 22:36:26 -05003// license that can be found in the LICENSE file.
Michael Matloob796e50b2014-12-20 15:33:48 -08004
5// The gomvpkg command moves go packages, updating import declarations.
6// See the -help message or Usage constant for details.
7package main
8
9import (
10 "flag"
11 "fmt"
12 "go/build"
13 "os"
14
Alan Donovanee9a07d2015-04-21 14:00:20 -040015 "golang.org/x/tools/go/buildutil"
Michael Matloob796e50b2014-12-20 15:33:48 -080016 "golang.org/x/tools/refactor/rename"
17)
18
19var (
20 fromFlag = flag.String("from", "", "Import path of package to be moved")
21 toFlag = flag.String("to", "", "Destination import path for package")
Sebastien Binet1937f902018-05-22 16:52:10 +020022 vcsMvCmdFlag = flag.String("vcs_mv_cmd", "", `A template for the version control system's "move directory" command, e.g. "git mv {{.Src}} {{.Dst}}"`)
Michael Matloob796e50b2014-12-20 15:33:48 -080023 helpFlag = flag.Bool("help", false, "show usage message")
24)
25
Alan Donovanee9a07d2015-04-21 14:00:20 -040026func init() {
27 flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
28}
29
Michael Matloob796e50b2014-12-20 15:33:48 -080030const Usage = `gomvpkg: moves a package, updating import declarations
31
32Usage:
33
34 gomvpkg -from <path> -to <path> [-vcs_mv_cmd <template>]
35
36Flags:
37
38-from specifies the import path of the package to be moved
39
40-to specifies the destination import path
41
42-vcs_mv_cmd specifies a shell command to inform the version control system of a
43 directory move. The argument is a template using the syntax of the
44 text/template package. It has two fields: Src and Dst, the absolute
45 paths of the directories.
46
47 For example: "git mv {{.Src}} {{.Dst}}"
48
49gomvpkg determines the set of packages that might be affected, including all
50packages importing the 'from' package and any of its subpackages. It will move
51the 'from' package and all its subpackages to the destination path and update all
52imports of those packages to point to its new import path.
53
54gomvpkg rejects moves in which a package already exists at the destination import
55path, or in which a directory already exists at the location the package would be
56moved to.
57
58gomvpkg will not always be able to rename imports when a package's name is changed.
59Import statements may want further cleanup.
60
61gomvpkg's behavior is not defined if any of the packages to be moved are
62imported using dot imports.
63
64Examples:
65
66% gomvpkg -from myproject/foo -to myproject/bar
67
68 Move the package with import path "myproject/foo" to the new path
69 "myproject/bar".
70
71% gomvpkg -from myproject/foo -to myproject/bar -vcs_mv_cmd "git mv {{.Src}} {{.Dst}}"
72
73 Move the package with import path "myproject/foo" to the new path
74 "myproject/bar" using "git mv" to execute the directory move.
75`
76
77func main() {
78 flag.Parse()
79
80 if len(flag.Args()) > 0 {
81 fmt.Fprintln(os.Stderr, "gomvpkg: surplus arguments.")
82 os.Exit(1)
83 }
84
85 if *helpFlag || *fromFlag == "" || *toFlag == "" {
Zvonimir Pavlinovic2cdcc602021-11-05 11:42:54 -070086 fmt.Print(Usage)
Michael Matloob796e50b2014-12-20 15:33:48 -080087 return
88 }
89
90 if err := rename.Move(&build.Default, *fromFlag, *toFlag, *vcsMvCmdFlag); err != nil {
91 fmt.Fprintf(os.Stderr, "gomvpkg: %s.\n", err)
92 os.Exit(1)
93 }
94}