mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-05-07 20:59:37 -05:00
[server][cli] Print version history in ls
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user