go svn文件操作

2018/04/18
实现简单的文件对比上线操作,svn自动更新操作

上代码


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

func main() {
	pwd, err := os.Getwd()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	inputReader := bufio.NewReader(os.Stdin)
	fmt.Println("请输入正确的命令例如:svnup|filename || online|filename ||quit || svn|all")
	for {

		input, _ := inputReader.ReadString('\n')
		tp := strings.Trim(input, "\r\n") //数据清洗
		if tp == "quit" {                 //系统进行退出
			break
		}
		isTrue := strings.Contains(tp, "|")
		if !isTrue {
			fmt.Println("请输入正确的命令例如:svnup|filename || online|filename ||quit || svn|all")
			continue
		}
		getInfo := strings.Split(tp, "|")
		if len(getInfo[0]) <= 0 || len(getInfo[1]) <= 0 {
			fmt.Println("请输入正确的命令例如:svnup|filename || online|filename ||quit || svn|all")
			continue
		}
		cmd := getInfo[0]
		fmt.Println(cmd)
		switch cmd {
		case "svn":
			childstart := time.Now()
			cmd := exec.Command("/usr/bin/svn", "up")
			out, err := cmd.CombinedOutput()
			if err != nil {
				fmt.Println("svn all更新失败 失败原因:", err)
				continue
			} else {
				childend := time.Now()
				childstime := childend.Sub(childstart)
				fmt.Printf("程序更新信息:%v\n", string(out))
				fmt.Printf("------svn 更新成功 程序执行时间%v------>\n", childstime)
			}
		case "svnup":
			start := time.Now()
			file := getInfo[1]
			_, err := os.Stat(file)
			if err != nil {
				fmt.Println("文件不存在请重新输入命令:svnup|filename || online|filename ||quit || svn|all")
				continue
			}
			rfile, err := os.Open(file)
			defer rfile.Close()
			if err != nil {
				fmt.Println("文件打开错误请重新输入命令:svnup|filename || online|filename ||quit || svn|all")
				continue
			}

			reader := bufio.NewReader(rfile)

			setErrorLine := 1

			for {
				childstart := time.Now()
				line, _, err := reader.ReadLine()
				if err != nil {
					if err == io.EOF {
						break
					}
					fmt.Println(err)
					break
				}
				svnFile := string(line) //从文件中读取要更新的svn文件
				svnFile = strings.TrimSpace(svnFile)

				cmd := exec.Command("/usr/bin/svn", "up", pwd+"/"+svnFile)
				_, err = cmd.CombinedOutput()
				if err != nil {
					fmt.Printf("------当前第%d行文件更新失败------>进程正在保存中...\n", setErrorLine)
					go ErrorFile(svnFile, err) //保存失败的文件名
					continue
				} else {
					childend := time.Now()
					childstime := childend.Sub(childstart)
					fmt.Printf("------当前第%d行文件为:%s 更新成功 程序执行时间%v------>\n", setErrorLine, svnFile, childstime)
				}
				setErrorLine++
			}

			end := time.Now()
			countTime := end.Sub(start)
			fmt.Printf("--------------------所有任务执行完毕总耗时:%v--------------------\n", countTime)
		case "online":
			start := time.Now()
			file := getInfo[1]
			_, err := os.Stat(file)
			if err != nil {
				fmt.Println("文件不存在请重新输入命令:svnup|filename || online|filename ||quit || svn|all")
				continue
			}
			rfile, err := os.Open(file)
			defer rfile.Close()
			if err != nil {
				fmt.Println("文件打开错误请重新输入命令:svnup|filename || online|filename ||quit || svn|all")
				continue
			}

			ch := make(chan bool)
			go onlineFile(file, pwd, ch)

			val := <-ch
			end := time.Now()
			countTime := end.Sub(start)
			if val {
				fmt.Printf("--------------------所有任务执行完毕总耗时:%v--------------------\n", countTime)
			}

		default:
			fmt.Println("请输入正确的命令例如:svnup|filename || online|filename ||quit || svn|all")
		}
	}

}

//上线复制文件
func onlineFile(file string, pwd string, ch chan bool) {

	rfile, err := os.Open(file)
	defer rfile.Close()
	if err != nil {
		panic("当前上线失败,上线包含文件异常...")
	}
	reader := bufio.NewReader(rfile)
	setErrorLine := 1
	for {
		start := time.Now()
		line, _, err := reader.ReadLine()

		if setErrorLine > 1000 {
			break
		}

		if err == io.EOF {
			break
		}

		if err != nil {
			fmt.Println(err)
			break
		}

		svnFile := string(line) //从文件中读取要更新的svn文件
		svnFile = strings.TrimSpace(svnFile)
		fileN := "/home/wwwroot/server/"

		dstFile := fileN + svnFile
		srcFile := pwd + "/" + svnFile

		if dstFile == srcFile {
			break
		}

		//判断线上文件是否存在

		_, err = os.Stat(dstFile)

		if err != nil { //文件不存在
			sliceFile := strings.Split(svnFile, "/")
			dstFile := sliceFile[len(sliceFile)-1]
			dstDir := sliceFile[:len(sliceFile)-1]
			saveDir := strings.Join(dstDir, "/")
			os.MkdirAll(fileN+"/"+saveDir, 0644)

			dstFileOpen, err := os.OpenFile(fileN+saveDir+"/"+dstFile, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
			defer dstFileOpen.Close()

			if err != nil {
				fmt.Printf("当前第%d文件上线失败------>进程正在执行中...%v\n", setErrorLine, err)
				go ErrorFile(svnFile, err) //拷贝失败
				setErrorLine++
				continue
			}

			srcFileOpen, err := os.Open(srcFile)

			if err != nil {
				fmt.Printf("当前第%d文件上线失败------>进程正在执行中...%v\n", setErrorLine, err)
				go ErrorFile(svnFile, err) //拷贝失败
				setErrorLine++
				continue
			}

			defer srcFileOpen.Close()

			_, err = io.Copy(dstFileOpen, srcFileOpen)

			if err != nil {
				fmt.Printf("当前第%d文件上线失败------>进程正在执行中...%v\n", setErrorLine, err)
				go ErrorFile(svnFile, err) //拷贝失败
				setErrorLine++
				continue
			}

		} else { //文件已存在

			dstFileOpen, _ := os.OpenFile(dstFile, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
			defer dstFileOpen.Close()
			srcFileOpen, _ := os.Open(srcFile)
			defer srcFileOpen.Close()

			_, err = io.Copy(dstFileOpen, srcFileOpen)

			if err != nil {
				fmt.Printf("当前第%d文件上线失败------>进程正在执行中...%v\n", setErrorLine, err)
				go ErrorFile(svnFile, err) //拷贝失败
				setErrorLine++
				continue
			}
		}

		end := time.Now()
		backFtime := end.Sub(start)
		fmt.Printf("当前第%d个上线完成文件名为:%s,单个任务耗时----%v\n", setErrorLine, svnFile, backFtime)
		setErrorLine++
	}
	ch <- true
}

//判断目录是否存在
func PathExists(path string) error {
	_, err := os.Stat(path)
	if err == nil {
		return err
	}
	err = os.Mkdir(path, os.ModePerm)
	return err
}

//更新之前进行备份操作
func backupFile(file string, pwd string, ch chan bool) {

	rfile, err := os.Open(file)
	filename := time.Now().Unix()
	fileN := pwd + "/" + strconv.Itoa(int(filename))
	err = PathExists(fileN) //读取的原始文件
	if err != nil {
		fmt.Println("创建备份目录失败,备份进程失败...")
		panic(err)
	}
	reader := bufio.NewReader(rfile)
	setErrorLine := 1
	for {
		start := time.Now()
		line, _, err := reader.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			fmt.Println(err)
			break
		}
		svnFile := string(line) //从文件中读取要更新的svn文件
		svnFile = strings.TrimSpace(svnFile)

		sliceFile := strings.Split(svnFile, "/")
		dstFile := sliceFile[len(sliceFile)-1]
		dstDir := sliceFile[:len(sliceFile)-1]
		saveDir := strings.Join(dstDir, "/")
		os.MkdirAll(fileN+"/"+saveDir, 0644)
		dst, _ := os.OpenFile(fileN+"/"+saveDir+"/"+dstFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
		svnFile = pwd + "/" + svnFile

		src, err := os.Open(svnFile)
		if err != nil {
			fmt.Println("文件拷贝失败------>进程正在执行中...")
			go ErrorFile(svnFile, err) //拷贝失败
			continue
		}
		_, err = io.Copy(dst, src)
		if err != nil {
			fmt.Println("文件拷贝失败------>进程正在执行中...")
			go ErrorFile(svnFile, err) //拷贝失败
			continue
		}
		end := time.Now()
		backFtime := end.Sub(start)
		fmt.Printf("当前第%d个备份完成,单个任务耗时----%v\n", setErrorLine, backFtime)
		setErrorLine++
	}
	ch <- true
}

//有错误的文件进行写操作
func ErrorFile(str_content string, err error) {
	fd, _ := os.OpenFile("svnerror.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	fd_time := time.Now().Format("2006-01-02 15:04:05")
	fd_content := strings.Join([]string{"[ ", fd_time, " ]", str_content, "--->失败原因:", fmt.Sprintf("%s", err), "\n"}, "")
	buf := []byte(fd_content)
	fd.Write(buf)
	fd.Close()
}


写的比较随意也没啥优化,慢慢进步吧


个人随笔

安静的等待,你若盛开,蝴蝶自来

承接高质量 网站开发 app开发 如有需要请点击About联系

@承鹏辉