Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • bazel/git
1 result
Show changes
Commits on Source (5)
# [1.0.0-alpha.2](https://git.gitlab.arm.com/bazel/git/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2024-04-09)
### Features
- accept `bazel-git fetch --negotation-tip` ([40dd662](https://git.gitlab.arm.com/bazel/git/commit/40dd662557969cbdece99608b8e0a187fdbe9ff6))
- implement `git cat-file -e $COMMIT` ([61ad69d](https://git.gitlab.arm.com/bazel/git/commit/61ad69d28eabe84e1d07cac6de0e75abc3f28a86))
- implement `git config $NAME $VALUE` ([5dcce02](https://git.gitlab.arm.com/bazel/git/commit/5dcce02a3af17000e71521a0c0ca82456e6c47be))
# 1.0.0-alpha.1 (2024-04-04)
### Bug Fixes
......
module(
name = "bazel-git",
version = "1.0.0-alpha.1",
version = "1.0.0-alpha.2",
bazel_compatibility = [
">=7.0.0",
],
......
......@@ -4,7 +4,9 @@ load("@rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "bazel-git_lib",
srcs = [
"cat-file.go",
"checkout.go",
"config.go",
"error.go",
"fetch.go",
"init.go",
......@@ -15,6 +17,7 @@ go_library(
visibility = ["//visibility:private"],
deps = [
"//checkout",
"//config",
"//fetch",
"//object",
"//reference",
......
package main
import (
"errors"
"log/slog"
"github.com/jessevdk/go-flags"
"gitlab.arm.com/bazel/git/v1/object"
)
type CatFileCommand struct {
ExitCode bool `short:"e" description:"Exit with zero status if <object> exists and is a valid object. If <object> is of an invalid format, exit with non-zero status and emit an error on stderr." required:"yes"`
Args struct {
Object object.Id `positional-arg-name:"<object>" description:"The object to check for existence."`
} `positional-args:"yes" required:"yes"`
}
var catFileCommand CatFileCommand
func (x *CatFileCommand) Execute(rest []string) error {
if len(rest) != 0 {
return &flags.Error{flags.ErrDuplicatedFlag, "only one object can be specified"}
}
if !x.ExitCode {
// TODO: remove when we support more flags
return errors.New("Must provide the `-e` flag")
}
log := slog.With("object", x.Args.Object)
log.Debug("cat-file")
found, err := object.Exists(object.ExistsOptions{Object: x.Args.Object, GitDir: options.Dir})
if err != nil {
return err
}
if !found {
return NewExitCodeError(1, "Not found")
}
return nil
}
func init() {
parser.AddCommand("cat-file",
"Check for existence of an object.",
`Detemines if a commit or tag object is availble in the repository.`,
&catFileCommand)
}
package main
import (
"log/slog"
"github.com/jessevdk/go-flags"
"gitlab.arm.com/bazel/git/v1/config"
)
type ConfigCommand struct {
Args struct {
Name string `positional-arg-name:"<name>" description:"The configuration option name." required:"yes"`
Value string `positional-arg-name:"<value>" description:"The configuration option value." required:"yes"`
} `positional-args:"yes"`
}
var configCommand ConfigCommand
func (x *ConfigCommand) Execute(rest []string) error {
if len(rest) != 0 {
return &flags.Error{flags.ErrDuplicatedFlag, "unsupported number of positional arguments"}
}
log := slog.With("name", x.Args.Name, "value", x.Args.Value)
log.Debug("set")
err := config.Set(config.SetOptions{
GitDir: options.Dir,
Name: x.Args.Name,
Value: x.Args.Value,
})
if err != nil {
return err
}
return nil
}
func init() {
parser.AddCommand("config",
"Set repository options.",
`Sets repository options using a dot-separated key and value pair.`,
&configCommand)
}
......@@ -9,8 +9,9 @@ import (
)
type FetchCommand struct {
Depth int `long:"depth" value-name:"<depth>" description:"Limit fetching the specified number of commits from the tip of each remote branch history." require:"yes"`
NoWriteFetchHead bool `long:"no-write-fetch-head" description:"Does not write **FETCH_HEAD**." required:"yes"`
Depth int `long:"depth" value-name:"<depth>" description:"Limit fetching the specified number of commits from the tip of each remote branch history." require:"yes"`
NoWriteFetchHead bool `long:"no-write-fetch-head" description:"Does not write **FETCH_HEAD**." required:"yes"`
NegotiationTips []reference.Commitish `long:"negotiation-tip" value-name:"<commit>" description:"Determines the tips to use in negoatiating a smaller packfile transfer. Can be defined multiple times."`
Args struct {
Remote remote.URL `positional-arg-name:"repository" description:"The remote to retrieve objects from."`
Commitishes []reference.Commitish `positional-arg-name:"refspec" description:"The committish to retrieve from the server. Usually a commit SHA but can be a resolvable reference."`
......@@ -20,8 +21,13 @@ type FetchCommand struct {
var fetchCommand FetchCommand
func (x *FetchCommand) Execute(_ []string) error {
log := slog.With("namespace", "fetch")
log := slog.With("namespace", "fetch", "remote", x.Args.Remote)
log.Debug("fetching", "commitishes", x.Args.Commitishes)
if len(x.NegotiationTips) > 0 {
log.Warn("Negotiation tips are not currently supported. A large packfile may be transferred", "negotiation-tips", x.NegotiationTips)
}
err := fetch.Commitishes(fetch.CommitishesOptions{
Remote: x.Args.Remote,
Commitishes: x.Args.Commitishes,
......
load("@rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "config",
srcs = ["set.go"],
importpath = "gitlab.arm.com/bazel/git/v1/config",
visibility = ["//visibility:public"],
deps = ["@com_github_go_git_go_git_v5//:go_default_library"],
)
go_test(
name = "config_test",
srcs = ["set_test.go"],
embed = [":config"],
deps = [
"@com_github_go_git_go_git_v5//:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
],
)
package config
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/go-git/go-git/v5"
)
type SetOptions struct {
GitDir string
Name string
Value string
}
func Set(options SetOptions) (err error) {
log := slog.With("namespace", "config.Set", "name", options.Name, "value", options.Value)
log.Debug("open", "git-dir", options.GitDir)
repo, err := git.PlainOpen(options.GitDir)
if err != nil {
log.Error("open", "err", err)
return err
}
config, err := repo.Config()
if err != nil {
log.Error("config", "err", err)
return err
}
if config.Raw == nil {
return errors.New("Unexpected empty raw configuration value")
}
parts := strings.Split(options.Name, ".")
log.Debug("split", "parts", parts)
if len(parts) != 2 {
return fmt.Errorf("Invalid configuration value name: %s", options.Name)
}
section, name := parts[0], parts[1]
if !config.Raw.HasSection(section) {
return fmt.Errorf("`%s` section not found: %s", options.Name, section)
}
s := config.Raw.Section(section)
s.SetOption(name, options.Value)
return repo.SetConfig(config)
}
package config
import (
"github.com/go-git/go-git/v5"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
func TestSet(t *testing.T) {
assert := assert.New(t)
dir, err := os.MkdirTemp("", "bazel-git-config-set-dir-")
assert.Nil(err)
defer os.RemoveAll(dir)
repo, err := git.PlainInitWithOptions(dir, &git.PlainInitOptions{
Bare: true,
})
assert.Nil(err)
err = Set(SetOptions{
GitDir: dir,
Name: "user.name",
Value: "Jango Fett",
})
assert.Nil(err)
config, err := repo.Config()
assert.Nil(err)
assert.Equal(config.User.Name, "Jango Fett")
}
......@@ -2,15 +2,29 @@ load("@rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "object",
srcs = ["id.go"],
srcs = [
"exists.go",
"id.go",
],
importpath = "gitlab.arm.com/bazel/git/v1/object",
visibility = ["//visibility:public"],
deps = [
"@com_github_go_git_go_git_v5//:go_default_library",
"@com_github_go_git_go_git_v5//plumbing:go_default_library",
],
)
go_test(
name = "object_test",
size = "small",
srcs = ["id_test.go"],
srcs = [
"exists_test.go",
"id_test.go",
],
embed = [":object"],
deps = ["@com_github_stretchr_testify//assert:go_default_library"],
deps = [
"@com_github_go_git_go_git_v5//:go_default_library",
"@com_github_go_git_go_git_v5//config:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
],
)
package object
import (
"log/slog"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
)
type ExistsOptions struct {
Object Id
GitDir string
}
func Exists(options ExistsOptions) (exists bool, err error) {
log := slog.With("namespace", "object.Exists", "object", options.Object)
log.Debug("open", "git-dir", options.GitDir)
repo, err := git.PlainOpen(options.GitDir)
if err != nil {
log.Error("open", "err", err)
return false, err
}
log.Debug("exists")
kinds := []plumbing.ObjectType{plumbing.CommitObject, plumbing.TagObject}
hash := plumbing.NewHash(options.Object.String())
for _, kind := range kinds {
_, err := repo.Object(kind, hash)
if err == plumbing.ErrObjectNotFound {
continue
}
if err != nil {
log.Error("exists", "err", err)
return false, err
}
log.Debug("found", "kind", kind.String())
return true, nil
}
log.Debug("not found")
return false, nil
}
package object
import (
"os"
"testing"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/stretchr/testify/assert"
)
func TestExists(t *testing.T) {
assert := assert.New(t)
dir, err := os.MkdirTemp("", "bazel-git-object-exists-")
assert.Nil(err)
defer os.RemoveAll(dir)
repo, err := git.PlainInitWithOptions(dir, &git.PlainInitOptions{
Bare: true,
})
assert.Nil(err)
remote, err := repo.CreateRemoteAnonymous(&config.RemoteConfig{
Name: "anonymous",
URLs: []string{"https://github.com/git/git.git"},
})
assert.Nil(err)
err = remote.Fetch(&git.FetchOptions{
RemoteURL: "https://github.com/git/git.git",
RefSpecs: []config.RefSpec{"refs/tags/v1.7.9:refs/tags/v1.7.9"},
Depth: 1,
})
assert.Nil(err)
id, err := NewId("828ea97de486c1693d6e4f2c7347acb50235a85d")
assert.Nil(err)
exists, err := Exists(ExistsOptions{
GitDir: dir,
Object: id,
})
assert.Nil(err)
assert.Equal(exists, true)
id, err = NewId("badc0de1badc0de1badc0de1badc0de1badc0de1")
assert.Nil(err)
exists, err = Exists(ExistsOptions{
GitDir: dir,
Object: id,
})
assert.Nil(err)
assert.Equal(exists, false)
}