2014-04-30 06:23:43 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2014-05-02 05:21:46 +04:00
package cmd
2014-04-30 06:23:43 +04:00
import (
2014-06-11 03:11:53 +04:00
"bufio"
2014-04-30 06:23:43 +04:00
"fmt"
2014-06-11 03:11:53 +04:00
"io"
"io/ioutil"
2014-04-30 06:23:43 +04:00
"os"
2014-06-11 03:11:53 +04:00
"path"
"strings"
2014-04-30 06:23:43 +04:00
"github.com/codegangsta/cli"
2014-06-11 03:11:53 +04:00
2014-04-30 06:23:43 +04:00
"github.com/gogits/gogs/models"
2014-05-26 04:11:25 +04:00
"github.com/gogits/gogs/modules/setting"
2014-04-30 06:23:43 +04:00
)
var CmdFix = cli . Command {
2014-05-05 08:55:17 +04:00
Name : "fix" ,
Usage : "This command for upgrade from old version" ,
Action : runFix ,
2014-06-11 03:11:53 +04:00
Subcommands : fixCommands ,
2014-05-05 08:55:17 +04:00
Flags : [ ] cli . Flag { } ,
2014-04-30 06:23:43 +04:00
}
2014-06-11 03:11:53 +04:00
func runFix ( ctx * cli . Context ) {
}
2014-04-30 06:23:43 +04:00
2014-06-11 03:11:53 +04:00
var fixCommands = [ ] cli . Command {
{
Name : "location" ,
Usage : "Change Gogs app location" ,
Description : ` Command location fixes location change of Gogs
gogs fix location < old Gogs path >
` ,
Action : runFixLocation ,
} ,
}
// rewriteAuthorizedKeys replaces old Gogs path to the new one.
func rewriteAuthorizedKeys ( sshPath , oldPath , newPath string ) error {
fr , err := os . Open ( sshPath )
if err != nil {
return err
}
defer fr . Close ( )
tmpPath := sshPath + ".tmp"
fw , err := os . Create ( tmpPath )
if err != nil {
return err
}
defer fw . Close ( )
oldPath = "command=\"" + oldPath + " serv"
newPath = "command=\"" + newPath + " serv"
buf := bufio . NewReader ( fr )
for {
line , errRead := buf . ReadString ( '\n' )
line = strings . TrimSpace ( line )
if errRead != nil {
if errRead != io . EOF {
return errRead
}
// Reached end of file, if nothing to read then break,
// otherwise handle the last line.
if len ( line ) == 0 {
break
}
}
// Still finding the line, copy the line that currently read.
if _ , err = fw . WriteString ( strings . Replace ( line , oldPath , newPath , 1 ) + "\n" ) ; err != nil {
return err
}
2014-04-30 06:23:43 +04:00
2014-06-11 03:11:53 +04:00
if errRead == io . EOF {
break
}
2014-04-30 06:23:43 +04:00
}
2014-06-11 03:11:53 +04:00
if err = os . Remove ( sshPath ) ; err != nil {
return err
}
return os . Rename ( tmpPath , sshPath )
}
func rewriteUpdateHook ( path , appPath string ) error {
rp := strings . NewReplacer ( "\\" , "/" , " " , "\\ " )
if err := ioutil . WriteFile ( path , [ ] byte ( fmt . Sprintf ( models . TPL_UPDATE_HOOK ,
setting . ScriptType , rp . Replace ( appPath ) ) ) , os . ModePerm ) ; err != nil {
return err
}
return nil
}
2014-04-30 06:23:43 +04:00
2014-06-11 03:11:53 +04:00
func walkDir ( rootPath , recPath , appPath string , depth int ) error {
depth ++
if depth > 3 {
return nil
} else if depth == 3 {
if err := rewriteUpdateHook ( path . Join ( rootPath , "hooks/update" ) , appPath ) ; err != nil {
return err
}
}
dir , err := os . Open ( rootPath )
if err != nil {
return err
}
defer dir . Close ( )
fis , err := dir . Readdir ( 0 )
2014-04-30 06:23:43 +04:00
if err != nil {
2014-06-11 03:11:53 +04:00
return err
}
for _ , fi := range fis {
if strings . Contains ( fi . Name ( ) , ".DS_Store" ) {
continue
}
relPath := path . Join ( recPath , fi . Name ( ) )
curPath := path . Join ( rootPath , fi . Name ( ) )
if fi . IsDir ( ) {
if err = walkDir ( curPath , relPath , appPath , depth ) ; err != nil {
return err
}
}
}
return nil
}
func runFixLocation ( ctx * cli . Context ) {
if len ( ctx . Args ( ) ) != 1 {
fmt . Println ( "Incorrect arguments number, expect 1" )
os . Exit ( 2 )
}
execPath , _ := setting . ExecPath ( )
oldPath := ctx . Args ( ) . First ( )
fmt . Printf ( "Old location: %s\n" , oldPath )
fmt . Println ( "This command should be executed in the new Gogs path" )
fmt . Printf ( "Do you want to change Gogs app path from old location to:\n" )
fmt . Printf ( "-> %s?\n" , execPath )
fmt . Print ( "Press <enter> to continue, use <Ctrl+c> to exit." )
fmt . Scanln ( )
// Fix in authorized_keys file.
sshPath := path . Join ( models . SshPath , "authorized_keys" )
fmt . Printf ( "Fixing pathes in file: %s\n" , sshPath )
if err := rewriteAuthorizedKeys ( sshPath , oldPath , execPath ) ; err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
// Fix position in gogs-repositories.
setting . NewConfigContext ( )
fmt . Printf ( "Fixing pathes in repositories: %s\n" , setting . RepoRootPath )
if err := walkDir ( setting . RepoRootPath , "" , execPath , 0 ) ; err != nil {
2014-04-30 06:23:43 +04:00
fmt . Println ( err )
2014-06-11 03:11:53 +04:00
os . Exit ( 1 )
2014-04-30 06:23:43 +04:00
}
2014-06-11 03:11:53 +04:00
fmt . Println ( "Fix position finished!" )
2014-04-30 06:23:43 +04:00
}