aboutsummaryrefslogtreecommitdiff
path: root/internal/lfsutil
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lfsutil')
-rw-r--r--internal/lfsutil/oid.go30
-rw-r--r--internal/lfsutil/oid_test.go47
-rw-r--r--internal/lfsutil/storage.go29
-rw-r--r--internal/lfsutil/storage_test.go43
4 files changed, 149 insertions, 0 deletions
diff --git a/internal/lfsutil/oid.go b/internal/lfsutil/oid.go
new file mode 100644
index 00000000..899c7332
--- /dev/null
+++ b/internal/lfsutil/oid.go
@@ -0,0 +1,30 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package lfsutil
+
+import (
+ "strings"
+)
+
+// OID is an LFS object ID.
+type OID string
+
+// ValidOID returns true if given oid is valid according to spec:
+// https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md
+func ValidOID(oid OID) bool {
+ fields := strings.SplitN(string(oid), ":", 2)
+ if len(fields) != 2 {
+ return false
+ }
+ method := fields[0]
+ hash := fields[1]
+
+ switch method {
+ case "sha256":
+ // SHA256 produces 64-char lower case hexadecimal hash
+ return len(hash) == 64 && strings.ToLower(hash) == hash
+ }
+ return false
+}
diff --git a/internal/lfsutil/oid_test.go b/internal/lfsutil/oid_test.go
new file mode 100644
index 00000000..1e3b020a
--- /dev/null
+++ b/internal/lfsutil/oid_test.go
@@ -0,0 +1,47 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package lfsutil
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestValidOID(t *testing.T) {
+ tests := []struct {
+ name string
+ oid OID
+ expVal bool
+ }{
+ {
+ name: "malformed",
+ oid: OID("12345678"),
+ },
+ {
+ name: "unknown method",
+ oid: OID("sha1:7c222fb2927d828af22f592134e8932480637c0d"),
+ },
+
+ {
+ name: "sha256: malformed",
+ oid: OID("sha256:7c222fb2927d828af22f592134e8932480637c0d"),
+ },
+ {
+ name: "sha256: not all lower cased",
+ oid: OID("sha256:EF797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"),
+ },
+ {
+ name: "sha256: valid",
+ oid: OID("sha256:ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"),
+ expVal: true,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ assert.Equal(t, test.expVal, ValidOID(test.oid))
+ })
+ }
+}
diff --git a/internal/lfsutil/storage.go b/internal/lfsutil/storage.go
new file mode 100644
index 00000000..fa10ee03
--- /dev/null
+++ b/internal/lfsutil/storage.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package lfsutil
+
+import (
+ "path/filepath"
+ "strings"
+)
+
+// Storage is the storage type of an LFS object.
+type Storage string
+
+const (
+ StorageLocal Storage = "local"
+)
+
+// StorageLocalPath returns computed file path for storing object on local file system.
+// It returns empty string if given "oid" isn't valid.
+func StorageLocalPath(root string, oid OID) string {
+ if !ValidOID(oid) {
+ return ""
+ }
+
+ // Valid OID is guaranteed to have second element as hash.
+ hash := strings.SplitN(string(oid), ":", 2)[1]
+ return filepath.Join(root, string(hash[0]), string(hash[1]), hash)
+}
diff --git a/internal/lfsutil/storage_test.go b/internal/lfsutil/storage_test.go
new file mode 100644
index 00000000..4f64b92b
--- /dev/null
+++ b/internal/lfsutil/storage_test.go
@@ -0,0 +1,43 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package lfsutil
+
+import (
+ "runtime"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestStorageLocalPath(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ t.Skip("Skipping testing on Windows")
+ return
+ }
+
+ tests := []struct {
+ name string
+ root string
+ oid OID
+ expPath string
+ }{
+ {
+ name: "invalid oid",
+ oid: OID("bad_oid"),
+ },
+
+ {
+ name: "valid oid",
+ root: "/lfs-objects",
+ oid: OID("sha256:ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"),
+ expPath: "/lfs-objects/e/f/ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ assert.Equal(t, test.expPath, StorageLocalPath(test.root, test.oid))
+ })
+ }
+}