提交 #1
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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 gitee
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fotff/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type BranchResp struct {
|
||||
Name string `json:"name"`
|
||||
Commit *Commit `json:"commit"`
|
||||
}
|
||||
|
||||
func GetBranch(owner, repo, branch string) (*BranchResp, error) {
|
||||
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/%s/branches/%s", owner, repo, branch)
|
||||
resp, err := utils.DoSimpleHttpReq(http.MethodGet, url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var branchResp BranchResp
|
||||
if err := json.Unmarshal(resp, &branchResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &branchResp, nil
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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 gitee
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fotff/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetCommit(owner, repo, id string) (*Commit, error) {
|
||||
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/%s/commits/%s", owner, repo, id)
|
||||
var resp []byte
|
||||
if c, found := utils.CacheGet("gitee", url); found {
|
||||
resp = c.([]byte)
|
||||
} else {
|
||||
var err error
|
||||
resp, err = utils.DoSimpleHttpReq(http.MethodGet, url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utils.CacheSet("gitee", url, resp)
|
||||
}
|
||||
var commitResp Commit
|
||||
if err := json.Unmarshal(resp, &commitResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commitResp.Owner = owner
|
||||
commitResp.Repo = repo
|
||||
return &commitResp, nil
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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 gitee
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fotff/utils"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CompareParam struct {
|
||||
Head string
|
||||
Base string
|
||||
Repo string
|
||||
Owner string
|
||||
}
|
||||
|
||||
type CompareResp struct {
|
||||
Commits []*Commit `json:"commits"`
|
||||
}
|
||||
|
||||
type Commit struct {
|
||||
CommitExtend `json:"-"`
|
||||
URL string `json:"url"`
|
||||
SHA string `json:"sha"`
|
||||
Commit struct {
|
||||
Committer struct {
|
||||
Date string `json:"date"`
|
||||
} `json:"committer"`
|
||||
Message string `json:"message"`
|
||||
} `json:"commit"`
|
||||
Parents []struct {
|
||||
SHA string `json:"sha"`
|
||||
URL string `json:"url"`
|
||||
} `json:"parents"`
|
||||
Files []struct {
|
||||
Filename string `json:"filename"`
|
||||
Status string `json:"status"`
|
||||
Patch string `json:"patch,omitempty"`
|
||||
} `json:"files,omitempty"`
|
||||
}
|
||||
|
||||
type CommitExtend struct {
|
||||
Owner string
|
||||
Repo string
|
||||
}
|
||||
|
||||
func GetLatestMRBefore(owner, repo, branch string, before string) (ret *Commit, err error) {
|
||||
branchResp, err := GetBranch(owner, repo, branch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
head := branchResp.Commit
|
||||
head.Owner = owner
|
||||
head.Repo = repo
|
||||
for head.Commit.Committer.Date > before {
|
||||
if head, err = GetCommit(owner, repo, head.Parents[0].SHA); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return head, nil
|
||||
}
|
||||
|
||||
func GetBetweenTimeMRs(owner, repo, branch string, from, to time.Time) (ret []*Commit, err error) {
|
||||
branchResp, err := GetBranch(owner, repo, branch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fromStr := from.UTC().Format(time.RFC3339)
|
||||
toStr := to.UTC().Format(time.RFC3339)
|
||||
head := branchResp.Commit
|
||||
head.Owner = owner
|
||||
head.Repo = repo
|
||||
for head.Commit.Committer.Date > fromStr {
|
||||
if head.Commit.Committer.Date < toStr {
|
||||
ret = append(ret, head)
|
||||
}
|
||||
if head, err = GetCommit(owner, repo, head.Parents[0].SHA); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func GetBetweenMRs(param CompareParam) ([]*Commit, error) {
|
||||
commits, err := GetBetweenCommits(param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ret []*Commit
|
||||
head := param.Head
|
||||
for head != param.Base {
|
||||
for _, commit := range commits {
|
||||
if commit.SHA != head {
|
||||
continue
|
||||
}
|
||||
commit.Owner = param.Owner
|
||||
commit.Repo = param.Repo
|
||||
ret = append(ret, commit)
|
||||
head = commit.Parents[0].SHA
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func GetBetweenCommits(param CompareParam) ([]*Commit, error) {
|
||||
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/%s/compare/%s...%s", param.Owner, param.Repo, param.Base, param.Head)
|
||||
var resp []byte
|
||||
if c, found := utils.CacheGet("gitee", url); found {
|
||||
resp = c.([]byte)
|
||||
} else {
|
||||
var err error
|
||||
resp, err = utils.DoSimpleHttpReq(http.MethodGet, url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utils.CacheSet("gitee", url, resp)
|
||||
}
|
||||
var compareResp CompareResp
|
||||
if err := json.Unmarshal(resp, &compareResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return compareResp.Commits, nil
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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 gitee
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fotff/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type PRIssueResp struct {
|
||||
URL string `json:"html_url"`
|
||||
}
|
||||
|
||||
func GetMRIssueURL(owner string, repo string, num int) ([]string, error) {
|
||||
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/%s/pulls/%d/issues", owner, repo, num)
|
||||
var resp []byte
|
||||
if c, found := utils.CacheGet("gitee", url); found {
|
||||
resp = c.([]byte)
|
||||
} else {
|
||||
var err error
|
||||
resp, err = utils.DoSimpleHttpReq(http.MethodGet, url, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utils.CacheSet("gitee", url, resp)
|
||||
}
|
||||
var prIssues []PRIssueResp
|
||||
if err := json.Unmarshal(resp, &prIssues); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]string, len(prIssues))
|
||||
for i, issue := range prIssues {
|
||||
ret[i] = issue.URL
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* 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 vcs
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Manifest struct {
|
||||
XMLName xml.Name `xml:"manifest"`
|
||||
Remote Remote `xml:"remote"`
|
||||
Default Default `xml:"default"`
|
||||
Projects []Project `xml:"project"`
|
||||
}
|
||||
|
||||
type Remote struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Fetch string `xml:"fetch,attr"`
|
||||
Review string `xml:"review,attr"`
|
||||
}
|
||||
|
||||
type Default struct {
|
||||
Remote string `xml:"remote,attr"`
|
||||
Revision string `xml:"revision,attr"`
|
||||
SyncJ string `xml:"sync-j,attr"`
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
XMLName xml.Name `xml:"project"`
|
||||
Name string `xml:"name,attr"`
|
||||
Path string `xml:"path,attr,omitempty"`
|
||||
Revision string `xml:"revision,attr"`
|
||||
Remote string `xml:"remote,attr,omitempty"`
|
||||
CloneDepth string `xml:"clone-depth,attr,omitempty"`
|
||||
LinkFile []LinkFile `xml:"linkfile,omitempty"`
|
||||
}
|
||||
|
||||
type LinkFile struct {
|
||||
Src string `xml:"src,attr"`
|
||||
Dest string `xml:"dest,attr"`
|
||||
}
|
||||
|
||||
type ProjectUpdate struct {
|
||||
P1, P2 *Project
|
||||
}
|
||||
|
||||
func (p *Project) String() string {
|
||||
if p == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("<%s>", p.Name)
|
||||
}
|
||||
|
||||
func (p *Project) StructureDiff(p2 *Project) bool {
|
||||
if p == nil && p2 != nil || p != nil && p2 == nil {
|
||||
return true
|
||||
}
|
||||
if p == nil && p2 == nil {
|
||||
return false
|
||||
}
|
||||
return p.Name != p2.Name || p.Path != p2.Path || p.Remote != p2.Remote
|
||||
}
|
||||
|
||||
func (p *Project) Equals(p2 *Project) bool {
|
||||
return p.Name == p2.Name && p.Path == p2.Path && p.Remote == p2.Remote && p.Revision == p2.Revision
|
||||
}
|
||||
|
||||
func ParseManifestFile(file string) (*Manifest, error) {
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var m Manifest
|
||||
err = xml.Unmarshal(data, &m)
|
||||
return &m, err
|
||||
}
|
||||
|
||||
func (m *Manifest) WriteFile(filePath string) error {
|
||||
data, err := xml.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data = append([]byte(xml.Header), data...)
|
||||
return os.WriteFile(filePath, data, 0640)
|
||||
}
|
||||
|
||||
func GetRepoUpdates(m1, m2 *Manifest) (updates []ProjectUpdate, err error) {
|
||||
if _, err := m1.Standardize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := m2.Standardize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var j int
|
||||
for i := 0; i < len(m1.Projects); {
|
||||
if m2.Projects[j].Name == m1.Projects[i].Name {
|
||||
if !m1.Projects[i].Equals(&m2.Projects[j]) {
|
||||
logrus.Infof("%v changes", &m1.Projects[i])
|
||||
updates = append(updates, ProjectUpdate{
|
||||
P1: &m1.Projects[i],
|
||||
P2: &m2.Projects[j],
|
||||
})
|
||||
}
|
||||
i++
|
||||
j++
|
||||
} else if m2.Projects[j].Name > m1.Projects[i].Name {
|
||||
logrus.Infof("%v removed", &m1.Projects[i])
|
||||
updates = append(updates, ProjectUpdate{
|
||||
P1: &m1.Projects[i],
|
||||
P2: nil,
|
||||
})
|
||||
i++
|
||||
} else { // m2.Projects[j].Name < m1.Projects[i].Name
|
||||
logrus.Infof("%v added", &m2.Projects[j])
|
||||
updates = append(updates, ProjectUpdate{
|
||||
P1: nil,
|
||||
P2: &m2.Projects[j],
|
||||
})
|
||||
j++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Manifest) UpdateManifestProject(name, path, remote, revision string, add bool) {
|
||||
if name == "manifest" {
|
||||
return
|
||||
}
|
||||
for i, p := range m.Projects {
|
||||
if p.Name == name {
|
||||
if path != "" {
|
||||
m.Projects[i].Path = path
|
||||
}
|
||||
if remote != "" {
|
||||
m.Projects[i].Remote = remote
|
||||
}
|
||||
if revision != "" {
|
||||
m.Projects[i].Revision = revision
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if add {
|
||||
m.Projects = append(m.Projects, Project{Name: name, Path: path, Revision: revision, Remote: remote})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manifest) RemoveManifestProject(name string) {
|
||||
for i, p := range m.Projects {
|
||||
if p.Name == name {
|
||||
m.Projects = append(m.Projects[:i], m.Projects[i:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manifest) Standardize() (string, error) {
|
||||
sort.Slice(m.Projects, func(i, j int) bool {
|
||||
return m.Projects[i].Name < m.Projects[j].Name
|
||||
})
|
||||
data, err := xml.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data = append([]byte(xml.Header), data...)
|
||||
sumByte := md5.Sum(data)
|
||||
return fmt.Sprintf("%X", sumByte), nil
|
||||
}
|
||||
Reference in New Issue
Block a user