mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-03-03 10:30:19 +00:00
297 lines
5.9 KiB
Go
297 lines
5.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/go-getter"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
codeProjectName string
|
|
codeGitUser string
|
|
codeVersion string
|
|
codeProjectPath string
|
|
)
|
|
|
|
var codeCmd = &cobra.Command{
|
|
Use: `code`,
|
|
Short: "Code commands",
|
|
}
|
|
|
|
var codeInitCmd = &cobra.Command{
|
|
Use: `init [name]`,
|
|
Short: "initialize podinfo code repo",
|
|
Example: ` code init demo-app --version=v1.2.0 --git-user=stefanprodan`,
|
|
RunE: runCodeInit,
|
|
}
|
|
|
|
func init() {
|
|
codeInitCmd.Flags().StringVar(&codeGitUser, "git-user", "", "GitHub user or org")
|
|
codeInitCmd.Flags().StringVar(&codeVersion, "version", "master", "podinfo repo tag or branch name")
|
|
codeInitCmd.Flags().StringVar(&codeProjectPath, "path", ".", "destination repo")
|
|
|
|
codeCmd.AddCommand(codeInitCmd)
|
|
|
|
rootCmd.AddCommand(codeCmd)
|
|
}
|
|
|
|
func runCodeInit(cmd *cobra.Command, args []string) error {
|
|
|
|
if len(codeGitUser) < 0 {
|
|
return fmt.Errorf("--git-user is required")
|
|
}
|
|
if len(args) < 1 {
|
|
return fmt.Errorf("project name is required")
|
|
}
|
|
|
|
codeProjectName = args[0]
|
|
|
|
pwd, err := os.Getwd()
|
|
if err != nil {
|
|
log.Fatalf("Error getting pwd: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
tmpPath := "/tmp/k8s-podinfo"
|
|
versionName := fmt.Sprintf("k8s-podinfo-%s", codeVersion)
|
|
|
|
downloadURL := fmt.Sprintf("https://github.com/stefanprodan/k8s-podinfo/archive/%s.zip", codeVersion)
|
|
client := &getter.Client{
|
|
Src: downloadURL,
|
|
Dst: tmpPath,
|
|
Pwd: pwd,
|
|
Mode: getter.ClientModeAny,
|
|
}
|
|
|
|
fmt.Printf("Downloading %s\n", downloadURL)
|
|
|
|
if err := client.Get(); err != nil {
|
|
log.Fatalf("Error downloading: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
pkgFrom := "github.com/stefanprodan/k8s-podinfo"
|
|
pkgTo := fmt.Sprintf("github.com/%s/%s", codeGitUser, codeProjectName)
|
|
|
|
if err := replaceImports(tmpPath, pkgFrom, pkgTo); err != nil {
|
|
log.Fatalf("Error parsing imports: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
dirs := []string{"pkg", "cmd", "ui", "vendor", ".github"}
|
|
for _, dir := range dirs {
|
|
|
|
err = os.MkdirAll(path.Join(codeProjectPath, dir), os.ModePerm)
|
|
if err != nil {
|
|
log.Fatalf("Error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
if err := copyDir(path.Join(tmpPath, versionName, dir), path.Join(codeProjectPath, dir)); err != nil {
|
|
log.Fatalf("Error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
files := []string{"Gopkg.toml", "Gopkg.lock", "Dockerfile.ci"}
|
|
for _, file := range files {
|
|
|
|
if err := copyFile(path.Join(tmpPath, versionName, file), path.Join(codeProjectPath, file)); err != nil {
|
|
log.Fatalf("Error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fileContent, err := ioutil.ReadFile(path.Join(codeProjectPath, file))
|
|
if err != nil {
|
|
log.Fatalf("Error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
newContent := strings.Replace(string(fileContent), pkgFrom, pkgTo, -1)
|
|
err = ioutil.WriteFile(path.Join(codeProjectPath, file), []byte(newContent), os.ModePerm)
|
|
if err != nil {
|
|
log.Fatalf("Error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
err = gitPush()
|
|
if err != nil {
|
|
log.Fatalf("git push error: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Println("Initialization finished")
|
|
return nil
|
|
}
|
|
|
|
func gitPush() error {
|
|
cmd := exec.Command("sh", "-c", "git add . && git commit -m \"init\" && git push")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println(string(output))
|
|
return nil
|
|
}
|
|
|
|
func replaceImports(projectPath string, pkgFrom string, pkgTo string) error {
|
|
regexImport, err := regexp.Compile(`(?s)(import(.*?)\)|import.*$)`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
regexImportedPackage, err := regexp.Compile(`"(.*?)"`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
found := []string{}
|
|
|
|
err = filepath.Walk(projectPath, func(path string, info os.FileInfo, err error) error {
|
|
if filepath.Ext(path) == ".go" {
|
|
bts, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
content := string(bts)
|
|
matches := regexImport.FindAllString(content, -1)
|
|
isExists := false
|
|
|
|
isReplaceable:
|
|
for _, each := range matches {
|
|
for _, eachLine := range strings.Split(each, "\n") {
|
|
matchesInline := regexImportedPackage.FindAllString(eachLine, -1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, eachSubline := range matchesInline {
|
|
if strings.Contains(eachSubline, pkgFrom) {
|
|
isExists = true
|
|
break isReplaceable
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if isExists {
|
|
content = strings.Replace(content, `"`+pkgFrom+`"`, `"`+pkgTo+`"`, -1)
|
|
content = strings.Replace(content, `"`+pkgFrom+`/`, `"`+pkgTo+`/`, -1)
|
|
found = append(found, path)
|
|
}
|
|
|
|
err = ioutil.WriteFile(path, []byte(content), info.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
fmt.Println("ERROR", err.Error())
|
|
}
|
|
|
|
if len(found) == 0 {
|
|
fmt.Println("Nothing replaced")
|
|
} else {
|
|
fmt.Printf("Go imports total %d file replaced\n", len(found))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func copyDir(src string, dst string) error {
|
|
si, err := os.Stat(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !si.IsDir() {
|
|
return fmt.Errorf("source is not a directory")
|
|
}
|
|
|
|
err = os.MkdirAll(dst, si.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
entries, err := ioutil.ReadDir(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
srcPath := filepath.Join(src, entry.Name())
|
|
dstPath := filepath.Join(dst, entry.Name())
|
|
|
|
if entry.IsDir() {
|
|
err = copyDir(srcPath, dstPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// Skip symlinks.
|
|
if entry.Mode()&os.ModeSymlink != 0 {
|
|
continue
|
|
}
|
|
|
|
err = copyFile(srcPath, dstPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func copyFile(src, dst string) (err error) {
|
|
in, err := os.Open(src)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer in.Close()
|
|
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
if e := out.Close(); e != nil {
|
|
err = e
|
|
}
|
|
}()
|
|
|
|
_, err = io.Copy(out, in)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = out.Sync()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
si, err := os.Stat(src)
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = os.Chmod(dst, si.Mode())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|