mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-20 02:24:58 -05:00
Starting to rip out regular expression code for refs / paths
This commit is contained in:
@@ -216,7 +216,7 @@ func (ddb *DoltDB) WriteEmptyRepoWithCommitTimeAndDefaultBranch(
|
||||
}
|
||||
|
||||
func getCommitValForRefStr(ctx context.Context, db datas.Database, vrw types.ValueReadWriter, ref string) (*datas.Commit, error) {
|
||||
if !datas.DatasetFullRe.MatchString(ref) {
|
||||
if err := datas.ValidateDatasetId(ref); err != nil {
|
||||
return nil, fmt.Errorf("invalid ref format: %s", ref)
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,8 @@ import (
|
||||
)
|
||||
|
||||
var commands = []*util.Command{
|
||||
nomsCommit,
|
||||
nomsConfig,
|
||||
nomsDiff,
|
||||
nomsDs,
|
||||
nomsLog,
|
||||
nomsMerge,
|
||||
nomsRoot,
|
||||
nomsShow,
|
||||
nomsSync,
|
||||
|
||||
0
go/store/cmd/noms/noms_commit.go
Normal file → Executable file
0
go/store/cmd/noms/noms_commit.go
Normal file → Executable file
0
go/store/cmd/noms/noms_commit_test.go
Normal file → Executable file
0
go/store/cmd/noms/noms_commit_test.go
Normal file → Executable file
0
go/store/cmd/noms/noms_diff.go
Normal file → Executable file
0
go/store/cmd/noms/noms_diff.go
Normal file → Executable file
0
go/store/cmd/noms/noms_diff_test.go
Normal file → Executable file
0
go/store/cmd/noms/noms_diff_test.go
Normal file → Executable file
16
go/store/cmd/noms/noms_log.go
Normal file → Executable file
16
go/store/cmd/noms/noms_log.go
Normal file → Executable file
@@ -24,7 +24,6 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -412,17 +411,4 @@ func min(i, j int) int {
|
||||
return i
|
||||
}
|
||||
return j
|
||||
}
|
||||
|
||||
func locationFromTimezoneArg(tz string, defaultTZ *time.Location) (*time.Location, error) {
|
||||
switch tz {
|
||||
case "local":
|
||||
return time.Local, nil
|
||||
case "utc":
|
||||
return time.UTC, nil
|
||||
case "":
|
||||
return defaultTZ, nil
|
||||
default:
|
||||
return nil, errors.New("value must be: local or utc")
|
||||
}
|
||||
}
|
||||
}
|
||||
18
go/store/cmd/noms/noms_log_test.go
Normal file → Executable file
18
go/store/cmd/noms/noms_log_test.go
Normal file → Executable file
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/datas"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/spec"
|
||||
@@ -127,23 +126,6 @@ func mustHead(ds datas.Dataset) types.Value {
|
||||
return s
|
||||
}
|
||||
|
||||
func mustHeadAddr(ds datas.Dataset) hash.Hash {
|
||||
addr, ok := ds.MaybeHeadAddr()
|
||||
d.PanicIfFalse(ok)
|
||||
return addr
|
||||
}
|
||||
|
||||
func mustHeadValue(ds datas.Dataset) types.Value {
|
||||
val, ok, err := ds.MaybeHeadValue()
|
||||
d.PanicIfError(err)
|
||||
|
||||
if !ok {
|
||||
panic("no head")
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func (s *nomsLogTestSuite) TestNArg() {
|
||||
dsName := "nArgTest"
|
||||
|
||||
|
||||
0
go/store/cmd/noms/noms_merge.go
Normal file → Executable file
0
go/store/cmd/noms/noms_merge.go
Normal file → Executable file
0
go/store/cmd/noms/noms_merge_test.go
Normal file → Executable file
0
go/store/cmd/noms/noms_merge_test.go
Normal file → Executable file
@@ -24,9 +24,11 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
flag "github.com/juju/gnuflag"
|
||||
|
||||
@@ -211,3 +213,16 @@ func outputEncodedValue(ctx context.Context, w io.Writer, value types.Value) err
|
||||
return types.WriteEncodedValue(ctx, w, value)
|
||||
}
|
||||
}
|
||||
|
||||
func locationFromTimezoneArg(tz string, defaultTZ *time.Location) (*time.Location, error) {
|
||||
switch tz {
|
||||
case "local":
|
||||
return time.Local, nil
|
||||
case "utc":
|
||||
return time.UTC, nil
|
||||
case "":
|
||||
return defaultTZ, nil
|
||||
default:
|
||||
return nil, errors.New("value must be: local or utc")
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/utils/file"
|
||||
@@ -208,3 +210,20 @@ func (s *nomsSyncTestSuite) TestRewind() {
|
||||
s.True(types.Float(42).Equals(mustHeadValue(dest)))
|
||||
db.Close()
|
||||
}
|
||||
|
||||
func mustHeadValue(ds datas.Dataset) types.Value {
|
||||
val, ok, err := ds.MaybeHeadValue()
|
||||
d.PanicIfError(err)
|
||||
|
||||
if !ok {
|
||||
panic("no head")
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func mustHeadAddr(ds datas.Dataset) hash.Hash {
|
||||
addr, ok := ds.MaybeHeadAddr()
|
||||
d.PanicIfFalse(ok)
|
||||
return addr
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
@@ -34,11 +33,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
// DatasetRe is a regexp that matches a legal Dataset name anywhere within the target string.
|
||||
// This regular expression isn't enough by itself, additional patterns are forbidden as well.
|
||||
// See ValidateDatasetId.
|
||||
var DatasetRe = regexp.MustCompile(`[^\:\?\[\\\^~ \t\*/]+`)
|
||||
|
||||
type refnameAction byte
|
||||
const (
|
||||
refnameOk refnameAction = 0
|
||||
@@ -48,6 +42,39 @@ const (
|
||||
refnameIllegal refnameAction = 4
|
||||
)
|
||||
|
||||
// ValidateDatasetId returns ErrInvalidDatasetID if the given dataset ID is invalid
|
||||
func ValidateDatasetId(refname string) error {
|
||||
var componentCount int
|
||||
|
||||
if refname == "@" {
|
||||
// Refname is a single character '@'.
|
||||
return ErrInvalidDatasetID
|
||||
}
|
||||
|
||||
if strings.HasSuffix(refname, "/") || strings.HasSuffix(refname, ".") {
|
||||
return ErrInvalidDatasetID
|
||||
}
|
||||
|
||||
for len(refname) > 0 {
|
||||
componentLen, err := validateDatasetIdComponent(refname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
componentCount++
|
||||
|
||||
// Next component
|
||||
refname = refname[componentLen:]
|
||||
}
|
||||
|
||||
// if componentCount < 2 {
|
||||
// // Refname has only one component
|
||||
// return ErrInvalidDatasetID
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// How to handle various characters in refnames:
|
||||
// 0: An acceptable character for refs
|
||||
// 1: End-of-component
|
||||
@@ -120,42 +147,6 @@ func validateDatasetIdComponent(refname string) (int, error) {
|
||||
return numChars, nil
|
||||
}
|
||||
|
||||
func ValidateDatasetId(refname string) error {
|
||||
var componentCount int
|
||||
|
||||
if refname == "@" {
|
||||
// Refname is a single character '@'.
|
||||
return ErrInvalidDatasetID
|
||||
}
|
||||
|
||||
if strings.HasSuffix(refname, "/") || strings.HasSuffix(refname, ".") {
|
||||
return ErrInvalidDatasetID
|
||||
}
|
||||
|
||||
for len(refname) > 0 {
|
||||
componentLen, err := validateDatasetIdComponent(refname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
componentCount++
|
||||
|
||||
// Next component
|
||||
refname = refname[componentLen:]
|
||||
}
|
||||
|
||||
if componentCount < 2 {
|
||||
// Refname has only one component
|
||||
return ErrInvalidDatasetID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DatasetFullRe is a regexp that matches a only a target string that is
|
||||
// entirely legal Dataset name.
|
||||
var DatasetFullRe = regexp.MustCompile("^" + DatasetRe.String() + "$")
|
||||
|
||||
type WorkingSetHead struct {
|
||||
Meta *WorkingSetMeta
|
||||
WorkingAddr hash.Hash
|
||||
@@ -636,10 +627,6 @@ func (ds Dataset) MaybeHeadValue() (types.Value, bool, error) {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
func IsValidDatasetName(name string) bool {
|
||||
return DatasetFullRe.MatchString(name)
|
||||
}
|
||||
|
||||
func NewHeadlessDataset(db Database, id string) Dataset {
|
||||
return Dataset{
|
||||
id: id,
|
||||
|
||||
@@ -228,8 +228,7 @@ func TestHeadValueFunctions(t *testing.T) {
|
||||
assert.False(ok)
|
||||
}
|
||||
|
||||
func TestIsValidDatasetName(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
func TestValidateDatasetId(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
valid bool
|
||||
@@ -242,7 +241,13 @@ func TestIsValidDatasetName(t *testing.T) {
|
||||
{"f!!", false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
assert.Equal(c.valid, IsValidDatasetName(c.name),
|
||||
"Expected %s validity to be %t", c.name, c.valid)
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
err := ValidateDatasetId(c.name)
|
||||
if c.valid {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Error(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
12
go/store/spec/absolute_path.go
Normal file → Executable file
12
go/store/spec/absolute_path.go
Normal file → Executable file
@@ -25,15 +25,12 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/datas"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
var datasetCapturePrefixRe = regexp.MustCompile("^(" + datas.DatasetRe.String() + ")")
|
||||
|
||||
// AbsolutePath describes the location of a Value within a Noms database.
|
||||
//
|
||||
// To locate a value relative to some other value, see Path. To locate a value
|
||||
@@ -79,13 +76,8 @@ func NewAbsolutePath(str string) (AbsolutePath, error) {
|
||||
|
||||
pathStr = tail[hash.StringLen:]
|
||||
} else {
|
||||
datasetParts := datasetCapturePrefixRe.FindStringSubmatch(str)
|
||||
if datasetParts == nil {
|
||||
return AbsolutePath{}, fmt.Errorf("invalid dataset name: %s", str)
|
||||
}
|
||||
|
||||
dataset = datasetParts[1]
|
||||
pathStr = str[len(dataset):]
|
||||
dataset = str
|
||||
pathStr = ""
|
||||
}
|
||||
|
||||
if len(pathStr) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user