mirror of https://github.com/databricks/cli.git
Compare commits
4 Commits
ad1359c1eb
...
e39e94b12f
Author | SHA1 | Date |
---|---|---|
|
e39e94b12f | |
|
8d5351c1c3 | |
|
4236e7122f | |
|
67f08ba924 |
|
@ -16,9 +16,11 @@ linters-settings:
|
|||
replacement: 'a[b:]'
|
||||
- pattern: 'interface{}'
|
||||
replacement: 'any'
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- (*github.com/spf13/cobra.Command).RegisterFlagCompletionFunc
|
||||
- (*github.com/spf13/cobra.Command).MarkFlagRequired
|
||||
- (*github.com/spf13/pflag.FlagSet).MarkDeprecated
|
||||
- (*github.com/spf13/pflag.FlagSet).MarkHidden
|
||||
issues:
|
||||
exclude-dirs-use-default: false # recommended by docs https://golangci-lint.run/usage/false-positives/
|
||||
exclude-rules:
|
||||
- path-except: (_test\.go|internal)
|
||||
linters:
|
||||
- errcheck
|
||||
|
|
10
Makefile
10
Makefile
|
@ -7,13 +7,13 @@ fmt:
|
|||
@gofmt -w $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
||||
|
||||
lint: vendor
|
||||
@echo "✓ Linting source code with https://golangci-lint.run/ (with --fix)..."
|
||||
@golangci-lint run --fix ./...
|
||||
|
||||
lintcheck: vendor
|
||||
@echo "✓ Linting source code with https://golangci-lint.run/ ..."
|
||||
@golangci-lint run ./...
|
||||
|
||||
lintfix: vendor
|
||||
@echo "✓ Linting source code with 'golangci-lint run --fix' ..."
|
||||
@golangci-lint run --fix ./...
|
||||
|
||||
test: lint testonly
|
||||
|
||||
testonly:
|
||||
|
@ -39,4 +39,4 @@ vendor:
|
|||
integration:
|
||||
gotestsum --format github-actions --rerun-fails --jsonfile output.json --packages "./internal/..." -- -run "TestAcc.*" -parallel 4 -timeout=2h
|
||||
|
||||
.PHONY: fmt lint lintfix test testonly coverage build snapshot vendor integration
|
||||
.PHONY: fmt lint lintcheck test testonly coverage build snapshot vendor integration
|
||||
|
|
|
@ -28,7 +28,7 @@ func (m *expandWorkspaceRoot) Apply(ctx context.Context, b *bundle.Bundle) diag.
|
|||
}
|
||||
|
||||
currentUser := b.Config.Workspace.CurrentUser
|
||||
if currentUser == nil || currentUser.UserName == "" {
|
||||
if currentUser == nil || currentUser.User == nil || currentUser.UserName == "" {
|
||||
return diag.Errorf("unable to expand workspace root: current user not set")
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,10 @@ func (m *initializeURLs) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagn
|
|||
}
|
||||
orgId := strconv.FormatInt(workspaceId, 10)
|
||||
host := b.WorkspaceClient().Config.CanonicalHostName()
|
||||
initializeForWorkspace(b, orgId, host)
|
||||
err = initializeForWorkspace(b, orgId, host)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ package mutator
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/databricks/cli/bundle"
|
||||
|
@ -24,8 +26,10 @@ func (m *loadGitDetails) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagn
|
|||
var diags diag.Diagnostics
|
||||
info, err := git.FetchRepositoryInfo(ctx, b.BundleRoot.Native(), b.WorkspaceClient())
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
diags = append(diags, diag.WarningFromErr(err)...)
|
||||
}
|
||||
}
|
||||
|
||||
if info.WorktreeRoot == "" {
|
||||
b.WorktreeRoot = b.BundleRoot
|
||||
|
|
|
@ -36,8 +36,7 @@ func (m *resolveResourceReferences) Apply(ctx context.Context, b *bundle.Bundle)
|
|||
return fmt.Errorf("failed to resolve %s, err: %w", v.Lookup, err)
|
||||
}
|
||||
|
||||
v.Set(id)
|
||||
return nil
|
||||
return v.Set(id)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,14 @@ func (s *statePull) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostic
|
|||
}
|
||||
|
||||
// Truncating the file before writing
|
||||
local.Truncate(0)
|
||||
local.Seek(0, 0)
|
||||
err = local.Truncate(0)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = local.Seek(0, 0)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
// Write file to disk.
|
||||
log.Infof(ctx, "Writing remote deployment state file to local cache directory")
|
||||
|
|
|
@ -171,10 +171,16 @@ func RenderDiagnostics(out io.Writer, b *bundle.Bundle, diags diag.Diagnostics,
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to render summary: %w", err)
|
||||
}
|
||||
io.WriteString(out, "\n")
|
||||
_, err = io.WriteString(out, "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
trailer := buildTrailer(diags)
|
||||
io.WriteString(out, trailer)
|
||||
_, err = io.WriteString(out, trailer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -141,7 +141,10 @@ func render(ctx context.Context, cmd *cobra.Command, status *authStatus, templat
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(buf)
|
||||
_, err = cmd.OutOrStdout().Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ func newEnvCommand() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(raw)
|
||||
_, _ = cmd.OutOrStdout().Write(raw)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ func newTokenCommand(persistentAuth *auth.PersistentAuth) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(raw)
|
||||
_, _ = cmd.OutOrStdout().Write(raw)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -60,13 +60,13 @@ For more information about filesystem mirrors, see the Terraform documentation:
|
|||
}
|
||||
switch root.OutputType(cmd) {
|
||||
case flags.OutputText:
|
||||
cmdio.Render(cmd.Context(), dependencies.Terraform)
|
||||
_ = cmdio.Render(cmd.Context(), dependencies.Terraform)
|
||||
case flags.OutputJSON:
|
||||
buf, err := json.MarshalIndent(dependencies, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(buf)
|
||||
_, _ = cmd.OutOrStdout().Write(buf)
|
||||
default:
|
||||
return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
|
||||
}
|
||||
|
|
|
@ -159,13 +159,19 @@ task or a Python wheel task, the second example applies.
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write([]byte(resultString))
|
||||
_, err = cmd.OutOrStdout().Write([]byte(resultString))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case flags.OutputJSON:
|
||||
b, err := json.MarshalIndent(output, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(b)
|
||||
_, err = cmd.OutOrStdout().Write(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ func newSummaryCommand() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(buf)
|
||||
_, _ = cmd.OutOrStdout().Write(buf)
|
||||
default:
|
||||
return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ func renderJsonOutput(cmd *cobra.Command, b *bundle.Bundle, diags diag.Diagnosti
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.OutOrStdout().Write(buf)
|
||||
_, _ = cmd.OutOrStdout().Write(buf)
|
||||
return diags.Error()
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ func initOutputFlag(cmd *cobra.Command) *outputFlag {
|
|||
// Configure defaults from environment, if applicable.
|
||||
// If the provided value is invalid it is ignored.
|
||||
if v, ok := env.Lookup(cmd.Context(), envOutputFormat); ok {
|
||||
f.output.Set(v)
|
||||
f.output.Set(v) //nolint:errcheck
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().VarP(&f.output, "output", "o", "output type: text or json")
|
||||
|
|
|
@ -45,7 +45,10 @@ func (f *logFlags) makeLogHandler(opts slog.HandlerOptions) (slog.Handler, error
|
|||
|
||||
func (f *logFlags) initializeContext(ctx context.Context) (context.Context, error) {
|
||||
if f.debug {
|
||||
f.level.Set("debug")
|
||||
err := f.level.Set("debug")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
opts := slog.HandlerOptions{}
|
||||
|
@ -81,13 +84,13 @@ func initLogFlags(cmd *cobra.Command) *logFlags {
|
|||
// Configure defaults from environment, if applicable.
|
||||
// If the provided value is invalid it is ignored.
|
||||
if v, ok := env.Lookup(cmd.Context(), envLogFile); ok {
|
||||
f.file.Set(v)
|
||||
f.file.Set(v) //nolint:errcheck
|
||||
}
|
||||
if v, ok := env.Lookup(cmd.Context(), envLogLevel); ok {
|
||||
f.level.Set(v)
|
||||
f.level.Set(v) //nolint:errcheck
|
||||
}
|
||||
if v, ok := env.Lookup(cmd.Context(), envLogFormat); ok {
|
||||
f.output.Set(v)
|
||||
f.output.Set(v) //nolint:errcheck
|
||||
}
|
||||
|
||||
flags := cmd.PersistentFlags()
|
||||
|
|
|
@ -59,7 +59,7 @@ func initProgressLoggerFlag(cmd *cobra.Command, logFlags *logFlags) *progressLog
|
|||
// Configure defaults from environment, if applicable.
|
||||
// If the provided value is invalid it is ignored.
|
||||
if v, ok := env.Lookup(cmd.Context(), envProgressFormat); ok {
|
||||
f.Set(v)
|
||||
_ = f.Set(v)
|
||||
}
|
||||
|
||||
flags := cmd.PersistentFlags()
|
||||
|
|
|
@ -18,8 +18,8 @@ import (
|
|||
"github.com/databricks/cli/libs/env"
|
||||
"github.com/databricks/cli/libs/filer"
|
||||
"github.com/databricks/cli/libs/flags"
|
||||
"github.com/databricks/cli/libs/folders"
|
||||
"github.com/databricks/cli/libs/template"
|
||||
"github.com/databricks/cli/libs/vfs"
|
||||
"github.com/databricks/databricks-sdk-go"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -144,15 +144,14 @@ func getBundleRemoteRootPath(w *databricks.WorkspaceClient, t *testing.T, unique
|
|||
}
|
||||
|
||||
func blackBoxRun(t *testing.T, root string, args ...string) (stdout string, stderr string) {
|
||||
cwd := vfs.MustNew(".")
|
||||
gitRoot, err := vfs.FindLeafInTree(cwd, ".git")
|
||||
gitRoot, err := folders.FindDirWithLeaf(".", ".git")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Setenv("BUNDLE_ROOT", root)
|
||||
|
||||
// Create the command
|
||||
cmd := exec.Command("go", append([]string{"run", "main.go"}, args...)...)
|
||||
cmd.Dir = gitRoot.Native()
|
||||
cmd.Dir = gitRoot
|
||||
|
||||
// Create buffers to capture output
|
||||
var outBuffer, errBuffer bytes.Buffer
|
||||
|
|
|
@ -101,7 +101,7 @@ func TestAccFetchRepositoryInfoAPI_FromNonRepo(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), test.msg)
|
||||
assert.ErrorContains(t, err, test.msg)
|
||||
}
|
||||
assertEmptyGitInfo(t, info)
|
||||
})
|
||||
|
@ -151,7 +151,7 @@ func TestAccFetchRepositoryInfoDotGit_FromNonGitRepo(t *testing.T) {
|
|||
for _, input := range tests {
|
||||
t.Run(input, func(t *testing.T) {
|
||||
info, err := git.FetchRepositoryInfo(ctx, input, wt.W)
|
||||
assert.NoError(t, err)
|
||||
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||
assertEmptyGitInfo(t, info)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -53,7 +53,9 @@ func newCallback(ctx context.Context, a *PersistentAuth) (*callbackServer, error
|
|||
a: a,
|
||||
}
|
||||
cb.srv.Handler = cb
|
||||
go cb.srv.Serve(cb.ln)
|
||||
go func() {
|
||||
_ = cb.srv.Serve(cb.ln)
|
||||
}()
|
||||
return cb, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -188,29 +188,29 @@ func (l *Logger) writeJson(event Event) {
|
|||
// we panic because there we cannot catch this in jobs.RunNowAndWait
|
||||
panic(err)
|
||||
}
|
||||
l.Writer.Write([]byte(b))
|
||||
l.Writer.Write([]byte("\n"))
|
||||
_, _ = l.Writer.Write([]byte(b))
|
||||
_, _ = l.Writer.Write([]byte("\n"))
|
||||
}
|
||||
|
||||
func (l *Logger) writeAppend(event Event) {
|
||||
l.Writer.Write([]byte(event.String()))
|
||||
l.Writer.Write([]byte("\n"))
|
||||
_, _ = l.Writer.Write([]byte(event.String()))
|
||||
_, _ = l.Writer.Write([]byte("\n"))
|
||||
}
|
||||
|
||||
func (l *Logger) writeInplace(event Event) {
|
||||
if l.isFirstEvent {
|
||||
// save cursor location
|
||||
l.Writer.Write([]byte("\033[s"))
|
||||
_, _ = l.Writer.Write([]byte("\033[s"))
|
||||
}
|
||||
|
||||
// move cursor to saved location
|
||||
l.Writer.Write([]byte("\033[u"))
|
||||
_, _ = l.Writer.Write([]byte("\033[u"))
|
||||
|
||||
// clear from cursor to end of screen
|
||||
l.Writer.Write([]byte("\033[0J"))
|
||||
_, _ = l.Writer.Write([]byte("\033[0J"))
|
||||
|
||||
l.Writer.Write([]byte(event.String()))
|
||||
l.Writer.Write([]byte("\n"))
|
||||
_, _ = l.Writer.Write([]byte(event.String()))
|
||||
_, _ = l.Writer.Write([]byte("\n"))
|
||||
l.isFirstEvent = false
|
||||
}
|
||||
|
||||
|
|
|
@ -361,7 +361,9 @@ func renderUsingTemplate(ctx context.Context, r templateRenderer, w io.Writer, h
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tw.Write([]byte("\n"))
|
||||
if _, err := tw.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
// Do not flush here. Instead, allow the first 100 resources to determine the initial spacing of the header columns.
|
||||
}
|
||||
t, err := base.Parse(tmpl)
|
||||
|
|
|
@ -126,7 +126,7 @@ func fromTypedStruct(src reflect.Value, ref dyn.Value, options ...fromTypedOptio
|
|||
|
||||
// Either if the key was set in the reference or the field is not zero-valued, we include it.
|
||||
if ok || nv.Kind() != dyn.KindNil {
|
||||
out.Set(refk, nv)
|
||||
out.Set(refk, nv) // nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ func fromTypedMap(src reflect.Value, ref dyn.Value) (dyn.Value, error) {
|
|||
|
||||
// Every entry is represented, even if it is a nil.
|
||||
// Otherwise, a map with zero-valued structs would yield a nil as well.
|
||||
out.Set(refk, nv)
|
||||
out.Set(refk, nv) //nolint:errcheck
|
||||
}
|
||||
|
||||
return dyn.V(out), nil
|
||||
|
|
|
@ -116,7 +116,7 @@ func (n normalizeOptions) normalizeStruct(typ reflect.Type, src dyn.Value, seen
|
|||
}
|
||||
}
|
||||
|
||||
out.Set(pk, nv)
|
||||
out.Set(pk, nv) //nolint:errcheck
|
||||
}
|
||||
|
||||
// Return the normalized value if missing fields are not included.
|
||||
|
@ -162,7 +162,7 @@ func (n normalizeOptions) normalizeStruct(typ reflect.Type, src dyn.Value, seen
|
|||
continue
|
||||
}
|
||||
if v.IsValid() {
|
||||
out.Set(dyn.V(k), v)
|
||||
out.Set(dyn.V(k), v) // nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ func (n normalizeOptions) normalizeMap(typ reflect.Type, src dyn.Value, seen []r
|
|||
}
|
||||
}
|
||||
|
||||
out.Set(pk, nv)
|
||||
out.Set(pk, nv) //nolint:errcheck
|
||||
}
|
||||
|
||||
return dyn.NewValue(out, src.Locations()), diags
|
||||
|
|
|
@ -70,7 +70,7 @@ func decodeValue(decoder *json.Decoder, o *Offset) (dyn.Value, error) {
|
|||
return invalidValueWithLocation(decoder, o), err
|
||||
}
|
||||
|
||||
obj.Set(keyVal, val)
|
||||
obj.Set(keyVal, val) //nolint:errcheck
|
||||
}
|
||||
// Consume the closing '}'
|
||||
if _, err := decoder.Token(); err != nil {
|
||||
|
|
|
@ -41,7 +41,7 @@ func newMappingWithSize(size int) Mapping {
|
|||
func newMappingFromGoMap(vin map[string]Value) Mapping {
|
||||
m := newMappingWithSize(len(vin))
|
||||
for k, v := range vin {
|
||||
m.Set(V(k), v)
|
||||
m.Set(V(k), v) //nolint:errcheck
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
@ -144,6 +144,6 @@ func (m Mapping) Clone() Mapping {
|
|||
// Merge merges the key-value pairs from another Mapping into the current Mapping.
|
||||
func (m *Mapping) Merge(n Mapping) {
|
||||
for _, p := range n.pairs {
|
||||
m.Set(p.Key, p.Value)
|
||||
m.Set(p.Key, p.Value) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,10 +88,10 @@ func mergeMap(a, b dyn.Value) (dyn.Value, error) {
|
|||
if err != nil {
|
||||
return dyn.InvalidValue, err
|
||||
}
|
||||
out.Set(pk, merged)
|
||||
out.Set(pk, merged) //nolint:errcheck
|
||||
} else {
|
||||
// Otherwise, just set the value.
|
||||
out.Set(pk, pv)
|
||||
out.Set(pk, pv) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ func (c anyKeyComponent) visit(v Value, prefix Path, suffix Pattern, opts visitO
|
|||
return InvalidValue, err
|
||||
}
|
||||
|
||||
m.Set(pk, nv)
|
||||
m.Set(pk, nv) //nolint:errcheck
|
||||
}
|
||||
|
||||
return NewValue(m, v.Locations()), nil
|
||||
|
|
|
@ -122,7 +122,7 @@ func (component pathComponent) visit(v Value, prefix Path, suffix Pattern, opts
|
|||
|
||||
// Return an updated map value.
|
||||
m = m.Clone()
|
||||
m.Set(V(component.key), nv)
|
||||
m.Set(V(component.key), nv) //nolint:errcheck
|
||||
return Value{
|
||||
v: m,
|
||||
k: KindMap,
|
||||
|
|
|
@ -25,7 +25,7 @@ func Foreach(fn MapFunc) MapFunc {
|
|||
if err != nil {
|
||||
return InvalidValue, err
|
||||
}
|
||||
m.Set(pk, nv)
|
||||
m.Set(pk, nv) //nolint:errcheck
|
||||
}
|
||||
return NewValue(m, v.Locations()), nil
|
||||
case KindSequence:
|
||||
|
|
|
@ -41,7 +41,7 @@ func SetByPath(v Value, p Path, nv Value) (Value, error) {
|
|||
|
||||
// Return an updated map value.
|
||||
m = m.Clone()
|
||||
m.Set(V(component.key), nv)
|
||||
m.Set(V(component.key), nv) //nolint:errcheck
|
||||
return Value{
|
||||
v: m,
|
||||
k: KindMap,
|
||||
|
|
|
@ -45,7 +45,7 @@ func walk(v Value, p Path, fn func(p Path, v Value) (Value, error)) (Value, erro
|
|||
if err != nil {
|
||||
return InvalidValue, err
|
||||
}
|
||||
out.Set(pk, nv)
|
||||
out.Set(pk, nv) //nolint:errcheck
|
||||
}
|
||||
v.v = out
|
||||
case KindSequence:
|
||||
|
|
|
@ -129,7 +129,7 @@ func (d *loader) loadMapping(node *yaml.Node, loc dyn.Location) (dyn.Value, erro
|
|||
return dyn.InvalidValue, err
|
||||
}
|
||||
|
||||
acc.Set(k, v)
|
||||
acc.Set(k, v) //nolint:errcheck
|
||||
}
|
||||
|
||||
if merge == nil {
|
||||
|
|
|
@ -43,7 +43,9 @@ func (le *configLoader) Configure(cfg *config.Config) error {
|
|||
if v == "" {
|
||||
continue
|
||||
}
|
||||
a.Set(cfg, v)
|
||||
if err := a.Set(cfg, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -9,6 +9,10 @@ import (
|
|||
// FindDirWithLeaf returns the first directory that holds `leaf`,
|
||||
// traversing up to the root of the filesystem, starting at `dir`.
|
||||
func FindDirWithLeaf(dir string, leaf string) (string, error) {
|
||||
dir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for {
|
||||
_, err := os.Stat(filepath.Join(dir, leaf))
|
||||
|
||||
|
|
|
@ -155,8 +155,8 @@ func globalGitConfig() (*config, error) {
|
|||
// > are missing or unreadable they will be ignored.
|
||||
//
|
||||
// We therefore ignore the error return value for the calls below.
|
||||
config.loadFile(vfs.MustNew(xdgConfigHome), "git/config")
|
||||
config.loadFile(vfs.MustNew(config.home), ".gitconfig")
|
||||
_ = config.loadFile(vfs.MustNew(xdgConfigHome), "git/config")
|
||||
_ = config.loadFile(vfs.MustNew(config.home), ".gitconfig")
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
@ -2,15 +2,12 @@ package git
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/databricks/cli/libs/dbr"
|
||||
"github.com/databricks/cli/libs/folders"
|
||||
"github.com/databricks/cli/libs/log"
|
||||
"github.com/databricks/cli/libs/vfs"
|
||||
"github.com/databricks/databricks-sdk-go"
|
||||
|
@ -105,7 +102,7 @@ func ensureWorkspacePrefix(p string) string {
|
|||
func fetchRepositoryInfoDotGit(ctx context.Context, path string) (RepositoryInfo, error) {
|
||||
result := RepositoryInfo{}
|
||||
|
||||
rootDir, err := findLeafInTree(path, GitDirectoryName)
|
||||
rootDir, err := folders.FindDirWithLeaf(path, GitDirectoryName)
|
||||
if rootDir == "" {
|
||||
return result, err
|
||||
}
|
||||
|
@ -134,28 +131,3 @@ func fetchRepositoryInfoDotGit(ctx context.Context, path string) (RepositoryInfo
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func findLeafInTree(p string, leafName string) (string, error) {
|
||||
var err error
|
||||
for i := 0; i < 10000; i++ {
|
||||
_, err = os.Stat(filepath.Join(p, leafName))
|
||||
|
||||
if err == nil {
|
||||
// Found [leafName] in p
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ErrNotExist means we continue traversal up the tree.
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
parent := filepath.Dir(p)
|
||||
if parent == p {
|
||||
return "", nil
|
||||
}
|
||||
p = parent
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -148,13 +148,20 @@ func (s *processStub) run(cmd *exec.Cmd) error {
|
|||
if !re.MatchString(norm) {
|
||||
continue
|
||||
}
|
||||
err := resp.err
|
||||
if resp.stdout != "" {
|
||||
cmd.Stdout.Write([]byte(resp.stdout))
|
||||
_, err1 := cmd.Stdout.Write([]byte(resp.stdout))
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
}
|
||||
if resp.stderr != "" {
|
||||
cmd.Stderr.Write([]byte(resp.stderr))
|
||||
_, err1 := cmd.Stderr.Write([]byte(resp.stderr))
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
return resp.err
|
||||
}
|
||||
return err
|
||||
}
|
||||
if s.callback != nil {
|
||||
return s.callback(cmd)
|
||||
|
@ -163,8 +170,12 @@ func (s *processStub) run(cmd *exec.Cmd) error {
|
|||
if s.reponseStub == zeroStub {
|
||||
return fmt.Errorf("no default process stub")
|
||||
}
|
||||
err := s.reponseStub.err
|
||||
if s.reponseStub.stdout != "" {
|
||||
cmd.Stdout.Write([]byte(s.reponseStub.stdout))
|
||||
_, err1 := cmd.Stdout.Write([]byte(s.reponseStub.stdout))
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
return s.reponseStub.err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -43,9 +43,9 @@ func TextOutput(ctx context.Context, ch <-chan Event, w io.Writer) {
|
|||
// Log only if something actually happened.
|
||||
// Sync events produce an empty string if nothing happened.
|
||||
if str := e.String(); str != "" {
|
||||
bw.WriteString(str)
|
||||
bw.WriteString("\n")
|
||||
bw.Flush()
|
||||
_, _ = bw.WriteString(str)
|
||||
_, _ = bw.WriteString("\n")
|
||||
_ = bw.Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package vfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
// FindLeafInTree returns the first path that holds `name`,
|
||||
// traversing up to the root of the filesystem, starting at `p`.
|
||||
func FindLeafInTree(p Path, name string) (Path, error) {
|
||||
for p != nil {
|
||||
_, err := fs.Stat(p, name)
|
||||
|
||||
// No error means we found the leaf in p.
|
||||
if err == nil {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ErrNotExist means we continue traversal up the tree.
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
p = p.Parent()
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, fs.ErrNotExist
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package vfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFindLeafInTree(t *testing.T) {
|
||||
wd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
root := filepath.Join(wd, "..", "..")
|
||||
|
||||
// Find from working directory should work.
|
||||
{
|
||||
out, err := FindLeafInTree(MustNew(wd), ".git")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, root, out.Native())
|
||||
}
|
||||
|
||||
// Find from project root itself should work.
|
||||
{
|
||||
out, err := FindLeafInTree(MustNew(root), ".git")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, root, out.Native())
|
||||
}
|
||||
|
||||
// Find for something that doesn't exist should work.
|
||||
{
|
||||
out, err := FindLeafInTree(MustNew(root), "this-leaf-doesnt-exist-anywhere")
|
||||
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||
assert.Equal(t, nil, out)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue