github.com/mncinnovation/ponzu@v0.11.1-0.20200102001432-9bc41b703131/cmd/ponzu/upgrade.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"time"
     9  
    10  	"github.com/spf13/cobra"
    11  )
    12  
    13  var upgradeCmd = &cobra.Command{
    14  	Use:   "upgrade",
    15  	Short: "upgrades your project to the current ponzu version",
    16  	Long: `Will backup your own custom project code (like content, addons, uploads, etc)
    17  if necessary. Before running '$ ponzu upgrade', you should update the 'ponzu'
    18  package by running '$ go get -u github.com/ponzu-cms/ponzu/...'`,
    19  	Example: `$ ponzu upgrade`,
    20  	RunE: func(cmd *cobra.Command, args []string) error {
    21  		// confirm since upgrade will replace Ponzu core files
    22  		path, err := os.Getwd()
    23  		if err != nil {
    24  			return fmt.Errorf("Failed to find current directory: %s", err)
    25  		}
    26  
    27  		fmt.Println("Only files you added to this directory, 'addons' and 'content' will be preserved.")
    28  		fmt.Println("Changes you made to Ponzu's internal code will be overwritten.")
    29  		fmt.Println("Upgrade this project? (y/N):")
    30  
    31  		answer, err := getAnswer()
    32  		if err != nil {
    33  			return err
    34  		}
    35  
    36  		switch answer {
    37  		case "n", "no", "\r\n", "\n", "":
    38  			fmt.Println("")
    39  
    40  		case "y", "yes":
    41  			err := upgradePonzuProjectDir(path)
    42  			if err != nil {
    43  				return err
    44  			}
    45  
    46  		default:
    47  			fmt.Println("Input not recognized. No upgrade made. Answer as 'y' or 'n' only.")
    48  		}
    49  		return nil
    50  	},
    51  }
    52  
    53  func upgradePonzuProjectDir(path string) error {
    54  	core := []string{
    55  		".gitattributes",
    56  		"LICENSE",
    57  		"ponzu-banner.png",
    58  		"README.md",
    59  		"cmd",
    60  		"deployment",
    61  		"management",
    62  		"system",
    63  		"docs",
    64  		"CONTRIBUTING.md",
    65  		"examples",
    66  	}
    67  
    68  	stamp := fmt.Sprintf("ponzu-%d.bak", time.Now().Unix())
    69  	temp := filepath.Join(os.TempDir(), stamp)
    70  	err := os.Mkdir(temp, os.ModeDir|os.ModePerm)
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	// track non-Ponzu core items (added by user)
    76  	var user []os.FileInfo
    77  	list, err := ioutil.ReadDir(path)
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	for _, item := range list {
    83  		// check if in core
    84  		var isCore bool
    85  		for _, name := range core {
    86  			if item.Name() == name {
    87  				isCore = true
    88  				break
    89  			}
    90  		}
    91  
    92  		if !isCore {
    93  			user = append(user, item)
    94  		}
    95  	}
    96  
    97  	// move non-Ponzu files to temp location
    98  	fmt.Println("Preserving files to be restored after upgrade...")
    99  	for _, item := range user {
   100  		src := filepath.Join(path, item.Name())
   101  		if item.IsDir() {
   102  			err := os.Mkdir(filepath.Join(temp, item.Name()), os.ModeDir|os.ModePerm)
   103  			if err != nil {
   104  				return err
   105  			}
   106  		}
   107  
   108  		err := copyAll(src, temp)
   109  		if err != nil {
   110  			return err
   111  		}
   112  
   113  		fmt.Println(" [-]", item.Name())
   114  
   115  	}
   116  
   117  	// remove all files in path
   118  	for _, item := range list {
   119  		err := os.RemoveAll(filepath.Join(path, item.Name()))
   120  		if err != nil {
   121  			return fmt.Errorf("Failed to remove old Ponzu files.\n%s", err)
   122  		}
   123  	}
   124  
   125  	// development upgrade?
   126  	if dev {
   127  		if fork != "" {
   128  			fmt.Println("Upgrading from " + fork)
   129  		} else {
   130  			fmt.Println("Upgrading from 'ponzu-dev' branch")
   131  		}
   132  	}
   133  	err = createProjectInDir(path)
   134  	if err != nil {
   135  		fmt.Println("")
   136  		fmt.Println("Upgrade failed...")
   137  		fmt.Println("Your code is backed up at the following location:")
   138  		fmt.Println(temp)
   139  		fmt.Println("")
   140  		fmt.Println("Manually create a new Ponzu project here and copy those files within it to fully restore.")
   141  		fmt.Println("")
   142  		return err
   143  	}
   144  
   145  	// move non-Ponzu files from temp location backed
   146  	restore, err := ioutil.ReadDir(temp)
   147  	if err != nil {
   148  		return err
   149  	}
   150  
   151  	fmt.Println("Restoring files preserved before upgrade...")
   152  	for _, r := range restore {
   153  		p := filepath.Join(temp, r.Name())
   154  		err = copyAll(p, path)
   155  		if err != nil {
   156  			fmt.Println("Couldn't merge your previous project files with upgraded one.")
   157  			fmt.Println("Manually copy your files from the following directory:")
   158  			fmt.Println(temp)
   159  			return err
   160  		}
   161  
   162  		fmt.Println(" [+]", r.Name())
   163  	}
   164  
   165  	// clean-up
   166  	backups := []string{filepath.Join(path, stamp), temp}
   167  	for _, bak := range backups {
   168  		err := os.RemoveAll(bak)
   169  		if err != nil {
   170  			return err
   171  		}
   172  	}
   173  
   174  	return nil
   175  }
   176  
   177  func init() {
   178  	upgradeCmd.Flags().StringVar(&fork, "fork", "", "modify repo source for Ponzu core development")
   179  	upgradeCmd.Flags().BoolVar(&dev, "dev", false, "modify environment for Ponzu core development")
   180  	RegisterCmdlineCommand(upgradeCmd)
   181  }