You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							264 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
	
	
							264 lines
						
					
					
						
							6.7 KiB
						
					
					
				| package main
 | |
| 
 | |
| /*
 | |
| Checkout a PR and load the tests data into sqlite database
 | |
| */
 | |
| 
 | |
| import (
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"log"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"os"
 | |
| 	"os/exec"
 | |
| 	"os/user"
 | |
| 	"path"
 | |
| 	"path/filepath"
 | |
| 	"runtime"
 | |
| 	"strconv"
 | |
| 	"time"
 | |
| 
 | |
| 	"code.gitea.io/gitea/models"
 | |
| 	"code.gitea.io/gitea/modules/markup"
 | |
| 	"code.gitea.io/gitea/modules/markup/external"
 | |
| 	"code.gitea.io/gitea/modules/setting"
 | |
| 	"code.gitea.io/gitea/routers"
 | |
| 	"code.gitea.io/gitea/routers/routes"
 | |
| 
 | |
| 	"github.com/Unknwon/com"
 | |
| 	"github.com/go-xorm/xorm"
 | |
| 	context2 "github.com/gorilla/context"
 | |
| 	"gopkg.in/src-d/go-git.v4"
 | |
| 	"gopkg.in/src-d/go-git.v4/config"
 | |
| 	"gopkg.in/src-d/go-git.v4/plumbing"
 | |
| 	"gopkg.in/testfixtures.v2"
 | |
| )
 | |
| 
 | |
| var codeFilePath = "contrib/pr/checkout.go"
 | |
| 
 | |
| func runPR() {
 | |
| 	log.Printf("[PR] Starting gitea ...\n")
 | |
| 	curDir, err := os.Getwd()
 | |
| 	if err != nil {
 | |
| 		log.Fatal(err)
 | |
| 	}
 | |
| 	setting.SetCustomPathAndConf("", "", "")
 | |
| 	setting.NewContext()
 | |
| 
 | |
| 	setting.RepoRootPath, err = ioutil.TempDir(os.TempDir(), "repos")
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("TempDir: %v\n", err)
 | |
| 	}
 | |
| 	setting.AppDataPath, err = ioutil.TempDir(os.TempDir(), "appdata")
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("TempDir: %v\n", err)
 | |
| 	}
 | |
| 	setting.AppWorkPath = curDir
 | |
| 	setting.StaticRootPath = curDir
 | |
| 	setting.GravatarSourceURL, err = url.Parse("https://secure.gravatar.com/avatar/")
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("url.Parse: %v\n", err)
 | |
| 	}
 | |
| 
 | |
| 	setting.AppURL = "http://localhost:8080/"
 | |
| 	setting.HTTPPort = "8080"
 | |
| 	setting.SSH.Domain = "localhost"
 | |
| 	setting.SSH.Port = 3000
 | |
| 	setting.InstallLock = true
 | |
| 	setting.SecretKey = "9pCviYTWSb"
 | |
| 	setting.InternalToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTI3OTU5ODN9.OQkH5UmzID2XBdwQ9TAI6Jj2t1X-wElVTjbE7aoN4I8"
 | |
| 	curUser, err := user.Current()
 | |
| 	if err != nil {
 | |
| 		log.Fatal(err)
 | |
| 	}
 | |
| 	setting.RunUser = curUser.Username
 | |
| 
 | |
| 	log.Printf("[PR] Loading fixtures data ...\n")
 | |
| 	setting.CheckLFSVersion()
 | |
| 	//models.LoadConfigs()
 | |
| 	/*
 | |
| 		models.DbCfg.Type = "sqlite3"
 | |
| 		models.DbCfg.Path = ":memory:"
 | |
| 		models.DbCfg.Timeout = 500
 | |
| 	*/
 | |
| 	db := setting.Cfg.Section("database")
 | |
| 	db.NewKey("DB_TYPE", "sqlite3")
 | |
| 	db.NewKey("PATH", ":memory:")
 | |
| 	setting.LogSQL = true
 | |
| 	models.LoadConfigs()
 | |
| 	routers.NewServices()
 | |
| 	//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
 | |
| 
 | |
| 	var helper testfixtures.Helper = &testfixtures.SQLite{}
 | |
| 	models.NewEngine(func(_ *xorm.Engine) error {
 | |
| 		return nil
 | |
| 	})
 | |
| 	models.HasEngine = true
 | |
| 	//x.ShowSQL(true)
 | |
| 	err = models.InitFixtures(
 | |
| 		helper,
 | |
| 		path.Join(curDir, "models/fixtures/"),
 | |
| 	)
 | |
| 	if err != nil {
 | |
| 		fmt.Printf("Error initializing test database: %v\n", err)
 | |
| 		os.Exit(1)
 | |
| 	}
 | |
| 	models.LoadFixtures()
 | |
| 	os.RemoveAll(setting.RepoRootPath)
 | |
| 	os.RemoveAll(models.LocalCopyPath())
 | |
| 	com.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath)
 | |
| 
 | |
| 	log.Printf("[PR] Setting up router\n")
 | |
| 	//routers.GlobalInit()
 | |
| 	external.RegisterParsers()
 | |
| 	markup.Init()
 | |
| 	m := routes.NewMacaron()
 | |
| 	routes.RegisterRoutes(m)
 | |
| 
 | |
| 	log.Printf("[PR] Ready for testing !\n")
 | |
| 	log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n")
 | |
| 	/*
 | |
| 		log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
 | |
| 
 | |
| 		if setting.LFS.StartServer {
 | |
| 			log.Info("LFS server enabled")
 | |
| 		}
 | |
| 
 | |
| 		if setting.EnablePprof {
 | |
| 			go func() {
 | |
| 				log.Info("Starting pprof server on localhost:6060")
 | |
| 				log.Info("%v", http.ListenAndServe("localhost:6060", nil))
 | |
| 			}()
 | |
| 		}
 | |
| 	*/
 | |
| 
 | |
| 	//Start the server
 | |
| 	http.ListenAndServe(":8080", context2.ClearHandler(m))
 | |
| 
 | |
| 	log.Printf("[PR] Cleaning up ...\n")
 | |
| 	/*
 | |
| 		if err = os.RemoveAll(setting.Indexer.IssuePath); err != nil {
 | |
| 			fmt.Printf("os.RemoveAll: %v\n", err)
 | |
| 			os.Exit(1)
 | |
| 		}
 | |
| 		if err = os.RemoveAll(setting.Indexer.RepoPath); err != nil {
 | |
| 			fmt.Printf("Unable to remove repo indexer: %v\n", err)
 | |
| 			os.Exit(1)
 | |
| 		}
 | |
| 	*/
 | |
| 	if err = os.RemoveAll(setting.RepoRootPath); err != nil {
 | |
| 		log.Fatalf("os.RemoveAll: %v\n", err)
 | |
| 	}
 | |
| 	if err = os.RemoveAll(setting.AppDataPath); err != nil {
 | |
| 		log.Fatalf("os.RemoveAll: %v\n", err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	var runPRFlag = flag.Bool("run", false, "Run the PR code")
 | |
| 	flag.Parse()
 | |
| 	if *runPRFlag {
 | |
| 		runPR()
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// To force checkout (e.g. Windows complains about unclean work tree) set env variable FORCE=true
 | |
| 	force, err := strconv.ParseBool(os.Getenv("FORCE"))
 | |
| 	if err != nil {
 | |
| 		force = false
 | |
| 	}
 | |
| 
 | |
| 	//Otherwise checkout PR
 | |
| 	if len(os.Args) != 2 {
 | |
| 		log.Fatal("Need only one arg: the PR number")
 | |
| 	}
 | |
| 	pr := os.Args[1]
 | |
| 
 | |
| 	codeFilePath = filepath.FromSlash(codeFilePath) //Convert to running OS
 | |
| 
 | |
| 	//Copy this file if it will not exist in the PR branch
 | |
| 	dat, err := ioutil.ReadFile(codeFilePath)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to cache this code file : %v", err)
 | |
| 	}
 | |
| 
 | |
| 	repo, err := git.PlainOpen(".")
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to open the repo : %v", err)
 | |
| 	}
 | |
| 
 | |
| 	//Find remote upstream
 | |
| 	remotes, err := repo.Remotes()
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to list remotes of repo : %v", err)
 | |
| 	}
 | |
| 	remoteUpstream := "origin" //Default
 | |
| 	for _, r := range remotes {
 | |
| 		if r.Config().URLs[0] == "https://github.com/go-gitea/gitea" || r.Config().URLs[0] == "git@github.com:go-gitea/gitea.git" { //fetch at index 0
 | |
| 			remoteUpstream = r.Config().Name
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	branch := fmt.Sprintf("pr-%s-%d", pr, time.Now().Unix())
 | |
| 	branchRef := plumbing.NewBranchReferenceName(branch)
 | |
| 
 | |
| 	log.Printf("Fetching PR #%s in %s\n", pr, branch)
 | |
| 	if runtime.GOOS == "windows" {
 | |
| 		//Use git cli command for windows
 | |
| 		runCmd("git", "fetch", remoteUpstream, fmt.Sprintf("pull/%s/head:%s", pr, branch))
 | |
| 	} else {
 | |
| 		ref := fmt.Sprintf("refs/pull/%s/head:%s", pr, branchRef)
 | |
| 		err = repo.Fetch(&git.FetchOptions{
 | |
| 			RemoteName: remoteUpstream,
 | |
| 			RefSpecs: []config.RefSpec{
 | |
| 				config.RefSpec(ref),
 | |
| 			},
 | |
| 		})
 | |
| 		if err != nil {
 | |
| 			log.Fatalf("Failed to fetch %s from %s : %v", ref, remoteUpstream, err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	tree, err := repo.Worktree()
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to parse git tree : %v", err)
 | |
| 	}
 | |
| 	log.Printf("Checkout PR #%s in %s\n", pr, branch)
 | |
| 	err = tree.Checkout(&git.CheckoutOptions{
 | |
| 		Branch: branchRef,
 | |
| 		Force:  force,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to checkout %s : %v", branch, err)
 | |
| 	}
 | |
| 
 | |
| 	//Copy this file if not exist
 | |
| 	if _, err := os.Stat(codeFilePath); os.IsNotExist(err) {
 | |
| 		err = os.MkdirAll(filepath.Dir(codeFilePath), 0755)
 | |
| 		if err != nil {
 | |
| 			log.Fatalf("Failed to duplicate this code file in PR : %v", err)
 | |
| 		}
 | |
| 		err = ioutil.WriteFile(codeFilePath, dat, 0644)
 | |
| 		if err != nil {
 | |
| 			log.Fatalf("Failed to duplicate this code file in PR : %v", err)
 | |
| 		}
 | |
| 	}
 | |
| 	time.Sleep(5 * time.Second)
 | |
| 	//Start with integration test
 | |
| 	runCmd("go", "run", "-tags", "sqlite sqlite_unlock_notify", codeFilePath, "-run")
 | |
| }
 | |
| func runCmd(cmd ...string) {
 | |
| 	log.Printf("Executing : %s ...\n", cmd)
 | |
| 	c := exec.Command(cmd[0], cmd[1:]...)
 | |
| 	c.Stdout = os.Stdout
 | |
| 	c.Stderr = os.Stderr
 | |
| 	if err := c.Start(); err != nil {
 | |
| 		log.Panicln(err)
 | |
| 	}
 | |
| 	if err := c.Wait(); err != nil {
 | |
| 		log.Panicln(err)
 | |
| 	}
 | |
| }
 | |
| 
 |