Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI command for reflog #7032

Merged
merged 13 commits into from
Dec 2, 2023
30 changes: 15 additions & 15 deletions go/cmd/dolt/commands/reflog.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ type ReflogInfo struct {
func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int {
var reflogInfo []ReflogInfo

// Get the current branch
curBranch := ""
res, err := GetRowsForSql(queryist, sqlCtx, "SELECT active_branch()")
// Get the hash of HEAD for the `HEAD ->` decoration
headHash := ""
res, err := GetRowsForSql(queryist, sqlCtx, "SELECT hashof('HEAD')")
if err == nil {
// still print the reflog even if we can't get the current branch
curBranch = res[0][0].(string)
// still print the reflog even if we can't get the hash
headHash = res[0][0].(string)
}

for _, row := range rows {
Expand All @@ -151,13 +151,13 @@ func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int
reflogInfo = append(reflogInfo, ReflogInfo{ref, commitHash, commitMessage})
}

reflogToStdOut(reflogInfo, curBranch)
reflogToStdOut(reflogInfo, headHash)

return 0
}

// reflogToStdOut takes a list of ReflogInfo and prints the reflog to stdout
func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) {
func reflogToStdOut(reflogInfo []ReflogInfo, headHash string) {
if cli.ExecuteWithStdioRestored == nil {
return
}
Expand All @@ -169,22 +169,22 @@ func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) {
// TODO: use short hash instead
line := []string{fmt.Sprintf("\033[33m%s\033[0m", info.commitHash)} // commit hash in yellow (33m)

processedRef := processRefForReflog(info.ref, curBranch)
line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m)
processedRef := processRefForReflog(info.ref)
if headHash != "" && headHash == info.commitHash {
line = append(line, fmt.Sprintf("\033[33m(\033[36;1mHEAD -> %s\033[33m)\033[0m", processedRef)) // HEAD in cyan (36;1)
} else {
line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m)
}
line = append(line, fmt.Sprintf("%s\n", info.commitMessage))
pager.Writer.Write([]byte(strings.Join(line, " ")))
}
})
}

// processRefForReflog takes a full ref (e.g. refs/heads/master) or tag name and returns the ref name (e.g. master) with relevant decoration.
func processRefForReflog(fullRef string, curBranch string) string {
func processRefForReflog(fullRef string) string {
if strings.HasPrefix(fullRef, "refs/heads/") {
branch := strings.TrimPrefix(fullRef, "refs/heads/")
if curBranch != "" && branch == curBranch {
return fmt.Sprintf("\033[36;1mHEAD -> \033[32;1m%s\033[0m", branch) // HEAD in cyan (36;1), branch in green (32;1m)
}
return fmt.Sprintf("\033[32;1m%s\033[0m", branch) // branch in green (32;1m)
return fmt.Sprintf("\033[32;1m%s\033[0m", strings.TrimPrefix(fullRef, "refs/heads/")) // branch in green (32;1m)
} else if strings.HasPrefix(fullRef, "refs/tags/") {
return fmt.Sprintf("\033[33mtag: %s\033[0m", strings.TrimPrefix(fullRef, "refs/tags/")) // tag in yellow (33m)
} else if strings.HasPrefix(fullRef, "refs/remotes/") {
Expand Down
68 changes: 31 additions & 37 deletions go/libraries/doltcore/sqle/reflog_table_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ import (
)

type ReflogTableFunction struct {
ctx *sql.Context
database sql.Database
refExpr sql.Expression
showAll bool
ctx *sql.Context
database sql.Database
refAndArgExprs []sql.Expression
tabId sql.TableId
colset sql.ColSet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two members don't seem to be used anywhere, so should be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were added in a separate PR, looks like they're being used a couple lines down.

}

var _ sql.TableFunction = (*ReflogTableFunction)(nil)
Expand Down Expand Up @@ -86,17 +87,30 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row
}

var refName string
if rltf.refExpr != nil {
target, err := rltf.refExpr.Eval(ctx, row)
showAll := false
for _, expr := range rltf.refAndArgExprs {
target, err := expr.Eval(ctx, row)
if err != nil {
return nil, fmt.Errorf("error evaluating expression (%s): %s",
rltf.refExpr.String(), err.Error())
expr.String(), err.Error())
}

refName, ok = target.(string)
targetStr, ok := target.(string)
if !ok {
return nil, fmt.Errorf("argument (%v) is not a string value, but a %T", target, target)
}

if targetStr == "--all" {
if showAll {
return nil, fmt.Errorf("error: multiple values provided for `all`")
}
showAll = true
} else {
if refName != "" {
return nil, fmt.Errorf("error: %s has too many positional arguments. Expected at most %d, found %d: %s",
rltf.Name(), 1, 2, rltf.refAndArgExprs)
}
refName = targetStr
}
}

ddb := sqlDb.DbData().Ddb
Expand Down Expand Up @@ -132,7 +146,7 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row
}
// skip workspace refs by default
if doltRef.GetType() == ref.WorkspaceRefType {
if !rltf.showAll {
if !showAll {
return nil
}
}
Expand Down Expand Up @@ -199,19 +213,17 @@ func (rltf *ReflogTableFunction) Schema() sql.Schema {
}

func (rltf *ReflogTableFunction) Resolved() bool {
if rltf.refExpr != nil {
return rltf.refExpr.Resolved()
for _, expr := range rltf.refAndArgExprs {
return expr.Resolved()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't want to always return on the first expression – you need to check that all the expressions are resolved.

You probably want something like if expr.Resolved() == false { return false } instead.

}
return true
}

func (rltf *ReflogTableFunction) String() string {
var args []string
if rltf.showAll {
args = append(args, "'--all'")
}
if rltf.refExpr != nil {
args = append(args, rltf.refExpr.String())

for _, expr := range rltf.refAndArgExprs {
args = append(args, expr.String())
}
return fmt.Sprintf("DOLT_REFLOG(%s)", strings.Join(args, ", "))
}
Expand All @@ -238,10 +250,7 @@ func (rltf *ReflogTableFunction) IsReadOnly() bool {
}

func (rltf *ReflogTableFunction) Expressions() []sql.Expression {
if rltf.refExpr != nil {
return []sql.Expression{rltf.refExpr}
}
return []sql.Expression{}
return rltf.refAndArgExprs
}

func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) (sql.Node, error) {
Expand All @@ -250,22 +259,7 @@ func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) (
}

new := *rltf

if len(expression) == 2 {
if expression[0].String() == "'--all'" && expression[1].String() == "'--all'" {
return nil, fmt.Errorf("error: multiple values provided for `all`")
}
if expression[0].String() != "'--all'" && expression[1].String() != "'--all'" {
return nil, fmt.Errorf("error: %s has too many positional arguments. Expected at most %d, found %d: %s", rltf.Name(), 1, 2, expression)
}
}
for _, expr := range expression {
if expr.String() != "'--all'" {
new.refExpr = expr
} else {
new.showAll = true
}
}
new.refAndArgExprs = expression

return &new, nil
}
Expand Down
17 changes: 17 additions & 0 deletions integration-tests/bats/reflog.bats
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,20 @@ SQL
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 0 ]
}

@test "reflog: 'HEAD -> ' decoration only appears on HEAD entries" {
setup_common

dolt sql -q "create table t (i int primary key, j int);"
dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)";
dolt commit -Am "initial commit"

run dolt reflog
[ "$status" -eq 0 ]
[ "${#lines[@]}" -eq 2 ]
line1=$(echo "${lines[0]}" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color
line2=$(echo "${lines[1]}" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color
[[ "$line1" =~ "(HEAD -> main) initial commit" ]] || false
[[ "$line2" =~ "Initialize data repository" ]] || false
[[ ! "$line2" =~ "HEAD" ]] || false
}
Loading