mirror of
https://github.com/iLoveElysia/openbilibili.git
synced 2026-03-14 05:46:26 -05:00
147 lines
4.7 KiB
Go
147 lines
4.7 KiB
Go
|
|
/*
|
||
|
|
Copyright 2018 The Kubernetes Authors.
|
||
|
|
|
||
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
you may not use this file except in compliance with the License.
|
||
|
|
You may obtain a copy of the License at
|
||
|
|
|
||
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
|
||
|
|
Unless required by applicable law or agreed to in writing, software
|
||
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
See the License for the specific language governing permissions and
|
||
|
|
limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
package clone
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"fmt"
|
||
|
|
"os/exec"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"github.com/sirupsen/logrus"
|
||
|
|
"k8s.io/test-infra/prow/kube"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Run clones the refs under the prescribed directory and optionally
|
||
|
|
// configures the git username and email in the repository as well.
|
||
|
|
func Run(refs kube.Refs, dir, gitUserName, gitUserEmail, cookiePath string, env []string) Record {
|
||
|
|
logrus.WithFields(logrus.Fields{"refs": refs}).Info("Cloning refs")
|
||
|
|
record := Record{Refs: refs}
|
||
|
|
for _, command := range commandsForRefs(refs, dir, gitUserName, gitUserEmail, cookiePath, env) {
|
||
|
|
formattedCommand, output, err := command.run()
|
||
|
|
logrus.WithFields(logrus.Fields{"command": formattedCommand, "output": output, "error": err}).Info("Ran command")
|
||
|
|
message := ""
|
||
|
|
if err != nil {
|
||
|
|
message = err.Error()
|
||
|
|
record.Failed = true
|
||
|
|
}
|
||
|
|
record.Commands = append(record.Commands, Command{Command: formattedCommand, Output: output, Error: message})
|
||
|
|
if err != nil {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return record
|
||
|
|
}
|
||
|
|
|
||
|
|
// PathForRefs determines the full path to where
|
||
|
|
// refs should be cloned
|
||
|
|
func PathForRefs(baseDir string, refs kube.Refs) string {
|
||
|
|
var clonePath string
|
||
|
|
if refs.PathAlias != "" {
|
||
|
|
clonePath = refs.PathAlias
|
||
|
|
} else {
|
||
|
|
clonePath = fmt.Sprintf("github.com/%s/%s", refs.Org, refs.Repo)
|
||
|
|
}
|
||
|
|
return fmt.Sprintf("%s/src/%s", baseDir, clonePath)
|
||
|
|
}
|
||
|
|
|
||
|
|
func commandsForRefs(refs kube.Refs, dir, gitUserName, gitUserEmail, cookiePath string, env []string) []cloneCommand {
|
||
|
|
repositoryURI := fmt.Sprintf("https://github.com/%s/%s.git", refs.Org, refs.Repo)
|
||
|
|
if refs.CloneURI != "" {
|
||
|
|
repositoryURI = refs.CloneURI
|
||
|
|
}
|
||
|
|
cloneDir := PathForRefs(dir, refs)
|
||
|
|
|
||
|
|
commands := []cloneCommand{{"/", env, "mkdir", []string{"-p", cloneDir}}}
|
||
|
|
|
||
|
|
gitCommand := func(args ...string) cloneCommand {
|
||
|
|
return cloneCommand{dir: cloneDir, env: env, command: "git", args: args}
|
||
|
|
}
|
||
|
|
commands = append(commands, gitCommand("init"))
|
||
|
|
if gitUserName != "" {
|
||
|
|
commands = append(commands, gitCommand("config", "user.name", gitUserName))
|
||
|
|
}
|
||
|
|
if gitUserEmail != "" {
|
||
|
|
commands = append(commands, gitCommand("config", "user.email", gitUserEmail))
|
||
|
|
}
|
||
|
|
if cookiePath != "" {
|
||
|
|
commands = append(commands, gitCommand("config", "http.cookiefile", cookiePath))
|
||
|
|
}
|
||
|
|
commands = append(commands, gitCommand("fetch", repositoryURI, "--tags", "--prune"))
|
||
|
|
commands = append(commands, gitCommand("fetch", repositoryURI, refs.BaseRef))
|
||
|
|
|
||
|
|
// unless the user specifically asks us not to, init submodules
|
||
|
|
if !refs.SkipSubmodules {
|
||
|
|
commands = append(commands, gitCommand("submodule", "update", "--init", "--recursive"))
|
||
|
|
}
|
||
|
|
|
||
|
|
var target string
|
||
|
|
if refs.BaseSHA != "" {
|
||
|
|
target = refs.BaseSHA
|
||
|
|
} else {
|
||
|
|
target = "FETCH_HEAD"
|
||
|
|
}
|
||
|
|
// we need to be "on" the target branch after the sync
|
||
|
|
// so we need to set the branch to point to the base ref,
|
||
|
|
// but we cannot update a branch we are on, so in case we
|
||
|
|
// are on the branch we are syncing, we check out the SHA
|
||
|
|
// first and reset the branch second, then check out the
|
||
|
|
// branch we just reset to be in the correct final state
|
||
|
|
commands = append(commands, gitCommand("checkout", target))
|
||
|
|
commands = append(commands, gitCommand("branch", "--force", refs.BaseRef, target))
|
||
|
|
commands = append(commands, gitCommand("checkout", refs.BaseRef))
|
||
|
|
|
||
|
|
for _, prRef := range refs.Pulls {
|
||
|
|
ref := fmt.Sprintf("pull/%d/head", prRef.Number)
|
||
|
|
if prRef.Ref != "" {
|
||
|
|
ref = prRef.Ref
|
||
|
|
}
|
||
|
|
commands = append(commands, gitCommand("fetch", repositoryURI, ref))
|
||
|
|
var prCheckout string
|
||
|
|
if prRef.SHA != "" {
|
||
|
|
prCheckout = prRef.SHA
|
||
|
|
} else {
|
||
|
|
prCheckout = "FETCH_HEAD"
|
||
|
|
}
|
||
|
|
commands = append(commands, gitCommand("merge", prCheckout))
|
||
|
|
}
|
||
|
|
return commands
|
||
|
|
}
|
||
|
|
|
||
|
|
type cloneCommand struct {
|
||
|
|
dir string
|
||
|
|
env []string
|
||
|
|
command string
|
||
|
|
args []string
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *cloneCommand) run() (string, string, error) {
|
||
|
|
output := bytes.Buffer{}
|
||
|
|
cmd := exec.Command(c.command, c.args...)
|
||
|
|
cmd.Dir = c.dir
|
||
|
|
cmd.Env = append(cmd.Env, c.env...)
|
||
|
|
cmd.Stdout = &output
|
||
|
|
cmd.Stderr = &output
|
||
|
|
err := cmd.Run()
|
||
|
|
return strings.Join(append([]string{c.command}, c.args...), " "), output.String(), err
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *cloneCommand) String() string {
|
||
|
|
return fmt.Sprintf("PWD=%s %s %s %s", c.dir, strings.Join(c.env, " "), c.command, strings.Join(c.env, " "))
|
||
|
|
}
|