summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2021-02-01 15:55:03 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2021-02-01 17:23:29 -0700
commit01ed9a06b20d32b148446d715d6e1beb3050d069 (patch)
tree8b0ef328859804e7b6bafb8f1495817fc31bb756
parent328f9cc1ac0ebee9499dc8d50bd84f71897d4df7 (diff)
Tidy up cmdClass
-rw-r--r--backend.go16
-rw-r--r--cmd.go13
-rw-r--r--cmd_command.go4
-rw-r--r--cmd_comment.go24
-rw-r--r--cmd_incommit.go (renamed from cmd_commit.go)18
-rw-r--r--parse_fastimport.go25
6 files changed, 46 insertions, 54 deletions
diff --git a/backend.go b/backend.go
index 0486e98..c91d0ac 100644
--- a/backend.go
+++ b/backend.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -89,17 +89,11 @@ func (b *Backend) Do(cmd Cmd) error {
return b.err
}
- switch cmd.fiCmdClass() {
- case cmdClassCommand:
+ switch {
+ case !cmdIs(cmd, cmdClassInCommit):
_, b.inCommit = cmd.(CmdCommit)
- case cmdClassCommit:
- if !b.inCommit {
- panic(errors.Errorf("Cannot issue commit sub-command outside of a commit: %[1]T(%#[1]v)", cmd))
- }
- case cmdClassComment:
- /* do nothing */
- default:
- panic(errors.Errorf("invalid cmdClass: %d", cmd.fiCmdClass()))
+ case !b.inCommit && !cmdIs(cmd, cmdClassCommand):
+ panic(errors.Errorf("Cannot issue commit sub-command outside of a commit: %[1]T(%#[1]v)", cmd))
}
err := cmd.fiCmdWrite(b.fastImportWrite)
diff --git a/cmd.go b/cmd.go
index 1665081..d1358a8 100644
--- a/cmd.go
+++ b/cmd.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -41,10 +41,11 @@ type fiWriter interface {
type cmdClass int
const (
- cmdClassCommand cmdClass = 1 // may be a top-level command
- cmdClassCommit cmdClass = 2 // may be used within in a commit
+ cmdClassCommand cmdClass = 1 << iota // can be a top-level command
+ cmdClassInCommit // can be used within in a commit
+ cmdClassInCommand // can be used in-between lines of another multi-line command
- cmdClassComment cmdClass = cmdClassCommand | cmdClassCommit
+ cmdClassComment = cmdClassCommand | cmdClassInCommit | cmdClassInCommand // "can be used anywhere in the stream that comments are accepted"
)
// Cmd is a command that may be found in a fast-import stream.
@@ -53,3 +54,7 @@ type Cmd interface {
fiCmdWrite(fiWriter) error
fiCmdClass() cmdClass
}
+
+func cmdIs(cmd Cmd, class cmdClass) bool {
+ return cmd.fiCmdClass()&class != 0
+}
diff --git a/cmd_command.go b/cmd_command.go
index ff74f80..a958b60 100644
--- a/cmd_command.go
+++ b/cmd_command.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -119,7 +119,7 @@ func (CmdCommit) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
// Backend.
type CmdCommitEnd struct{}
-func (CmdCommitEnd) fiCmdClass() cmdClass { return cmdClassCommit }
+func (CmdCommitEnd) fiCmdClass() cmdClass { return cmdClassInCommit }
func (CmdCommitEnd) fiCmdWrite(fiw fiWriter) error { return nil }
func (CmdCommitEnd) fiCmdRead(fir fiReader) (Cmd, error) { panic("not reached") }
diff --git a/cmd_comment.go b/cmd_comment.go
index c0325b4..2124c8e 100644
--- a/cmd_comment.go
+++ b/cmd_comment.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,6 +22,10 @@ import (
"github.com/pkg/errors"
)
+// This file deals with comments, and with commands for which the
+// specification says (or said) that the command "can be used anywhere
+// in the stream that comments are accepted".
+
// comment /////////////////////////////////////////////////////////////////////
// CmdComment is a comment line; not a real command.
@@ -105,19 +109,17 @@ type CmdLs struct {
Path Path
}
-// If you're thinking "but wait, parser_registerCmd will see CmdLs as
-// cmdClassCommit, not cmdClassComment, that means it won't be allowed
-// embedded inside other commands! (while still allowing it both
-// inside and outside of a commit)", you're absolutely correct.
-// That's the desired behavior. It's a happy accident that the little
-// fiCmdClass hack works out that way, instead of having to add even
-// more complexity.
-
func (c CmdLs) fiCmdClass() cmdClass {
+ // As of git v2.21, the docs say this is cmdClassComment, but
+ // the actual code disagrees.
if c.DataRef == "" {
- return cmdClassCommit
+ // Yeah, this will give slightly misleading info to
+ // parser_registerCmd(), but that's OK,
+ // parser_registerCmd() only really cares about the
+ // cmdClassInCommand bit.
+ return cmdClassInCommit
}
- return cmdClassComment
+ return cmdClassCommand | cmdClassInCommit
}
func (c CmdLs) fiCmdWrite(fiw fiWriter) error {
if c.DataRef == "" {
diff --git a/cmd_commit.go b/cmd_incommit.go
index 170c511..f58e59f 100644
--- a/cmd_commit.go
+++ b/cmd_incommit.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -37,7 +37,7 @@ type FileModify struct {
DataRef string
}
-func (o FileModify) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileModify) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileModify) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("M", o.Mode, o.DataRef, o.Path)
}
@@ -98,7 +98,7 @@ type FileModifyInline struct {
Data string
}
-func (o FileModifyInline) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileModifyInline) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileModifyInline) fiCmdWrite(fiw fiWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("M", o.Mode, "inline", o.Path)
@@ -115,7 +115,7 @@ type FileDelete struct {
Path Path
}
-func (o FileDelete) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileDelete) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileDelete) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("D", o.Path)
}
@@ -138,7 +138,7 @@ type FileCopy struct {
Dst Path
}
-func (o FileCopy) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileCopy) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileCopy) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("C", o.Src, o.Dst)
}
@@ -158,7 +158,7 @@ type FileRename struct {
Dst string
}
-func (o FileRename) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileRename) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileRename) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("R", o.Src, o.Dst)
}
@@ -175,7 +175,7 @@ func (FileRename) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
// CmdCommit.
type FileDeleteAll struct{}
-func (o FileDeleteAll) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o FileDeleteAll) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o FileDeleteAll) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("deleteall")
}
@@ -203,7 +203,7 @@ type NoteModify struct {
DataRef string
}
-func (o NoteModify) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o NoteModify) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o NoteModify) fiCmdWrite(fiw fiWriter) error {
return fiw.WriteLine("N", o.DataRef, o.CommitIsh)
}
@@ -257,7 +257,7 @@ type NoteModifyInline struct {
Data string
}
-func (o NoteModifyInline) fiCmdClass() cmdClass { return cmdClassCommit }
+func (o NoteModifyInline) fiCmdClass() cmdClass { return cmdClassInCommit }
func (o NoteModifyInline) fiCmdWrite(fiw fiWriter) error {
ez := &ezfiw{fiw: fiw}
ez.WriteLine("N", "inline", o.CommitIsh)
diff --git a/parse_fastimport.go b/parse_fastimport.go
index 491788b..7f84dfd 100644
--- a/parse_fastimport.go
+++ b/parse_fastimport.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017-2018, 2020 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2017-2018, 2020-2021 Luke Shumaker <lukeshu@lukeshu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -27,13 +27,10 @@ var parser_regularCmds = make(map[string]Cmd)
var parser_commentCmds = make(map[string]Cmd)
func parser_registerCmd(prefix string, cmd Cmd) {
- switch cmd.fiCmdClass() {
- case cmdClassCommand, cmdClassCommit:
- parser_regularCmds[prefix] = cmd
- case cmdClassComment:
+ if cmdIs(cmd, cmdClassInCommand) {
parser_commentCmds[prefix] = cmd
- default:
- panic(errors.Errorf("invalid cmdClass: %d", cmd.fiCmdClass()))
+ } else {
+ parser_regularCmds[prefix] = cmd
}
}
@@ -133,20 +130,14 @@ func (p *parser) parse() error {
return err
}
- switch cmd.fiCmdClass() {
- case cmdClassCommand:
+ switch {
+ case !cmdIs(cmd, cmdClassInCommit):
if p.inCommit {
p.ret_cmd <- CmdCommitEnd{}
}
_, p.inCommit = cmd.(CmdCommit)
- case cmdClassCommit:
- if !p.inCommit {
- return errors.Errorf("Got in-commit-only command outside of a commit: %[1]T(%#[1]v)", cmd)
- }
- case cmdClassComment:
- /* do nothing */
- default:
- panic(errors.Errorf("invalid cmdClass: %d", cmd.fiCmdClass()))
+ case !p.inCommit && !cmdIs(cmd, cmdClassCommand):
+ return errors.Errorf("Got in-commit-only command outside of a commit: %[1]T(%#[1]v)", cmd)
}
p.ret_cmd <- cmd