[server][cli] Print version history in ls

This commit is contained in:
Abhishek Shroff
2025-06-09 00:49:09 +05:30
parent 3d61961fc3
commit 6da29b93b4
10 changed files with 98 additions and 36 deletions
+2 -2
View File
@@ -29,7 +29,7 @@ var htmlReplacer = strings.NewReplacer(
type FileSystem interface {
ReadDir(core.Resource, bool) ([]core.Resource, error)
FindVersion(core.Resource, uuid.UUID) (core.Version, error)
GetVersion(core.Resource, uuid.UUID) (core.Version, error)
}
func Serve(w http.ResponseWriter, r *http.Request, f FileSystem, res core.Resource) {
@@ -111,7 +111,7 @@ func formatSize(size int) string {
}
func ServeResourceVersion(w http.ResponseWriter, r *http.Request, f FileSystem, res core.Resource, versionID uuid.UUID) {
version, err := f.FindVersion(res, versionID)
version, err := f.GetVersion(res, versionID)
if err != nil {
panic(err)
}
+1 -1
View File
@@ -76,7 +76,7 @@ func handleContentsRequest(c *gin.Context) {
return err
}
v, err := f.FindVersion(r, uuid.Nil)
v, err := f.GetVersion(r, uuid.Nil)
if err != nil {
return err
}
+2 -1
View File
@@ -54,7 +54,8 @@ func FormatSize(size int) string {
for ; sz >= 1000 && si < len(suffix); si, sz = si+1, sz/1024 {
}
if sz >= 10 || si == 0 {
return fmt.Sprintf("%4d%s", int(math.Ceil(sz)), suffix[si])
return strconv.Itoa(int(math.Ceil(sz))) + suffix[si]
// return fmt.Sprintf("%d%s", int(math.Ceil(sz)), suffix[si])
} else {
return fmt.Sprintf("%1.1f%s", sz, suffix[si])
}
+1 -1
View File
@@ -29,7 +29,7 @@ func setupCatCommand() *cobra.Command {
os.Exit(1)
}
v, err := f.FindVersion(r, uuid.Nil)
v, err := f.GetVersion(r, uuid.Nil)
if err != nil {
fmt.Println("cannot find latest version of '" + path + "': " + err.Error())
os.Exit(1)
+18 -2
View File
@@ -85,8 +85,24 @@ to the resource with a particular ID.`,
fmt.Println(common.FormatResourceSummary(c, "", r.Deleted()))
}
} else {
fmt.Println(" Size: " + common.FormatSize(int(r.LatestVersion().Size)))
fmt.Println("SHA-256: " + r.LatestVersion().SHA256[0:12])
fmt.Println(" Size: " + common.FormatSize(int(r.LatestVersion().Size)))
fmt.Println(" SHA-256: " + r.LatestVersion().SHA256[0:12])
versions, err := f.GetAllVersions(r)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
fmt.Println("Versions: " + strconv.Itoa(len(versions)))
for i, v := range versions {
extra := ""
if i == 0 {
extra += " [current]"
}
if v.Deleted != 0 {
extra += " [deleted]"
}
fmt.Printf("%s %5s %s %s%s\n", v.ID.String(), common.FormatSize(int(v.Size)), v.SHA256[0:12], time.Unix(int64(v.Created), 0).Local().Format(time.RFC1123), extra)
}
}
},
}
+5 -2
View File
@@ -33,7 +33,10 @@ type FileSystem interface {
ResourceByID(uuid.UUID) (Resource, error)
ResourceByPath(string) (Resource, error)
ResourceByPathWithRoot(string) (Resource, error)
FindVersion(Resource, uuid.UUID) (Version, error)
// resource_versions.go
GetVersion(Resource, uuid.UUID) (Version, error)
GetAllVersions(Resource) ([]Version, error)
// resource_ancestors.go
GetAncestors(Resource) ([]ResourceAncestor, error)
@@ -76,7 +79,7 @@ type FileSystem interface {
type ReadFileSystem interface {
ResourceByPath(string) (Resource, error)
ReadDir(Resource, bool) ([]Resource, error)
FindVersion(Resource, uuid.UUID) (Version, error)
GetVersion(Resource, uuid.UUID) (Version, error)
Walk(Resource, int, func(Resource, string) error) error
}
+2 -2
View File
@@ -23,8 +23,8 @@ func (f proxyFileSystemReadOnly) ReadDir(r Resource, recursive bool) ([]Resource
return f.f.ReadDir(r, recursive)
}
func (f proxyFileSystemReadOnly) FindVersion(r Resource, versionID uuid.UUID) (Version, error) {
return f.f.FindVersion(r, versionID)
func (f proxyFileSystemReadOnly) GetVersion(r Resource, versionID uuid.UUID) (Version, error) {
return f.f.GetVersion(r, versionID)
}
func (f proxyFileSystemReadOnly) Walk(r Resource, depth int, fn func(Resource, string) error) error {
-25
View File
@@ -2,7 +2,6 @@ package core
import (
"strings"
"time"
"github.com/doug-martin/goqu/v9"
"github.com/google/uuid"
@@ -146,27 +145,3 @@ func parseUUIDPrefix(path string) (pgtype.UUID, string, error) {
}
return pgtype.UUID{}, path, nil
}
func (f filesystem) FindVersion(r Resource, versionID uuid.UUID) (Version, error) {
if versionID == uuid.Nil {
versionID = r.latestVersionInfo.ID
}
const q = `SELECT id, created, size, mime_type, sha256, storage FROM resource_versions
WHERE resource_id = $1::UUID
AND id = $2::UUID
AND DELETED IS NULL`
row := f.db.QueryRow(q, r.id, versionID)
var v Version
var created time.Time
err := row.Scan(&v.ID, &created, &v.Size, &v.MimeType, &v.SHA256, &v.Storage)
if err != nil {
if Is(err, pgx.ErrNoRows) {
err = ErrVersionNotFound
}
return v, err
}
v.Created = int(created.Unix())
return v, nil
}
+45
View File
@@ -0,0 +1,45 @@
package core
import (
"errors"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
func (f filesystem) GetVersion(r Resource, versionID uuid.UUID) (Version, error) {
if versionID == uuid.Nil {
versionID = r.latestVersionInfo.ID
}
const q = `SELECT id, created, size, mime_type, sha256, storage FROM resource_versions
WHERE resource_id = $1::UUID
AND id = $2::UUID
AND DELETED IS NULL`
row := f.db.QueryRow(q, r.id, versionID)
var v Version
var created time.Time
err := row.Scan(&v.ID, &created, &v.Size, &v.MimeType, &v.SHA256, &v.Storage)
if err != nil {
if Is(err, pgx.ErrNoRows) {
return v, ErrVersionNotFound
} else {
return v, errors.New("failed to get resource version: " + err.Error())
}
}
v.Created = int(created.Unix())
return v, nil
}
func (f filesystem) GetAllVersions(r Resource) ([]Version, error) {
const q = `SELECT id, created, deleted, size, mime_type, sha256, storage FROM resource_versions
WHERE resource_id = $1::UUID
ORDER BY created DESC`
if rows, err := f.db.Query(q, r.id); err != nil {
return nil, errors.New("failed to get resource versions: " + err.Error())
} else {
return pgx.CollectRows(rows, scanVersion)
}
}
+22
View File
@@ -6,6 +6,8 @@ import (
"codeberg.org/shroff/phylum/server/internal/storage"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
)
// VersionInfo represents a single version of a resource
@@ -24,6 +26,26 @@ type Version struct {
Storage string
}
func scanVersion(row pgx.CollectableRow) (Version, error) {
var v Version
var created pgtype.Timestamp
var deleted pgtype.Timestamp
err := row.Scan(
&v.ID,
&created,
&deleted,
&v.Size,
&v.MimeType,
&v.SHA256,
&v.Storage,
)
v.Created = int(created.Time.Unix())
if deleted.Valid {
v.Deleted = int(deleted.Time.Unix())
}
return v, err
}
func (v Version) OpenRead(start, length int) (io.ReadCloser, error) {
if v.Storage == "" {
return nil, errors.New("unknown storage backend")