Refactor pkg/archive with a platform-independent stat struct
pkg/archive contains code both invoked from cli (cross platform) and daemon (linux only) and Unix-specific dependencies break compilation on Windows. We extracted those stat-related funcs into platform specific implementations at pkg/system and added unit tests. Signed-off-by: Ahmet Alp Balkan <ahmetb@microsoft.com>
This commit is contained in:
parent
515e7481de
commit
718066ad61
13 changed files with 209 additions and 65 deletions
|
@ -6,11 +6,11 @@ import (
|
|||
"syscall"
|
||||
)
|
||||
|
||||
func Lstat(path string) (*syscall.Stat_t, error) {
|
||||
func Lstat(path string) (*Stat, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
err := syscall.Lstat(path, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
|
25
system/lstat_test.go
Normal file
25
system/lstat_test.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLstat(t *testing.T) {
|
||||
file, invalid, _ := prepareFiles(t)
|
||||
|
||||
statFile, err := Lstat(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if statFile == nil {
|
||||
t.Fatal("returned empty stat for existing file")
|
||||
}
|
||||
|
||||
statInvalid, err := Lstat(invalid)
|
||||
if err == nil {
|
||||
t.Fatal("did not return error for non-existing file")
|
||||
}
|
||||
if statInvalid != nil {
|
||||
t.Fatal("returned non-nil stat for non-existing file")
|
||||
}
|
||||
}
|
|
@ -2,11 +2,7 @@
|
|||
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Lstat(path string) (*syscall.Win32FileAttributeData, error) {
|
||||
func Lstat(path string) (*Stat, error) {
|
||||
// should not be called on cli code path
|
||||
return nil, ErrNotSupportedPlatform
|
||||
}
|
||||
|
|
42
system/stat.go
Normal file
42
system/stat.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type Stat struct {
|
||||
mode uint32
|
||||
uid uint32
|
||||
gid uint32
|
||||
rdev uint64
|
||||
size int64
|
||||
mtim syscall.Timespec
|
||||
}
|
||||
|
||||
func (s Stat) Mode() uint32 {
|
||||
return s.mode
|
||||
}
|
||||
|
||||
func (s Stat) Uid() uint32 {
|
||||
return s.uid
|
||||
}
|
||||
|
||||
func (s Stat) Gid() uint32 {
|
||||
return s.gid
|
||||
}
|
||||
|
||||
func (s Stat) Rdev() uint64 {
|
||||
return s.rdev
|
||||
}
|
||||
|
||||
func (s Stat) Size() int64 {
|
||||
return s.size
|
||||
}
|
||||
|
||||
func (s Stat) Mtim() syscall.Timespec {
|
||||
return s.mtim
|
||||
}
|
||||
|
||||
func (s Stat) GetLastModification() syscall.Timespec {
|
||||
return s.Mtim()
|
||||
}
|
|
@ -4,10 +4,11 @@ import (
|
|||
"syscall"
|
||||
)
|
||||
|
||||
func GetLastAccess(stat *syscall.Stat_t) syscall.Timespec {
|
||||
return stat.Atim
|
||||
}
|
||||
|
||||
func GetLastModification(stat *syscall.Stat_t) syscall.Timespec {
|
||||
return stat.Mtim
|
||||
func fromStatT(s *syscall.Stat_t) (*Stat, error) {
|
||||
return &Stat{size: s.Size,
|
||||
mode: s.Mode,
|
||||
uid: s.Uid,
|
||||
gid: s.Gid,
|
||||
rdev: s.Rdev,
|
||||
mtim: s.Mtim}, nil
|
||||
}
|
||||
|
|
34
system/stat_test.go
Normal file
34
system/stat_test.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFromStatT(t *testing.T) {
|
||||
file, _, _ := prepareFiles(t)
|
||||
|
||||
stat := &syscall.Stat_t{}
|
||||
err := syscall.Lstat(file, stat)
|
||||
|
||||
s, err := fromStatT(stat)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if stat.Mode != s.Mode() {
|
||||
t.Fatal("got invalid mode")
|
||||
}
|
||||
if stat.Uid != s.Uid() {
|
||||
t.Fatal("got invalid uid")
|
||||
}
|
||||
if stat.Gid != s.Gid() {
|
||||
t.Fatal("got invalid gid")
|
||||
}
|
||||
if stat.Rdev != s.Rdev() {
|
||||
t.Fatal("got invalid rdev")
|
||||
}
|
||||
if stat.Mtim != s.Mtim() {
|
||||
t.Fatal("got invalid mtim")
|
||||
}
|
||||
}
|
|
@ -1,13 +1,16 @@
|
|||
// +build !linux
|
||||
// +build !linux,!windows
|
||||
|
||||
package system
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func GetLastAccess(stat *syscall.Stat_t) syscall.Timespec {
|
||||
return stat.Atimespec
|
||||
}
|
||||
|
||||
func GetLastModification(stat *syscall.Stat_t) syscall.Timespec {
|
||||
return stat.Mtimespec
|
||||
func fromStatT(s *syscall.Stat_t) (*Stat, error) {
|
||||
return &Stat{size: s.Size,
|
||||
mode: uint32(s.Mode),
|
||||
uid: s.Uid,
|
||||
gid: s.Gid,
|
||||
rdev: uint64(s.Rdev),
|
||||
mtim: s.Mtimespec}, nil
|
||||
}
|
||||
|
|
12
system/stat_windows.go
Normal file
12
system/stat_windows.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
// +build windows
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func fromStatT(s *syscall.Win32FileAttributeData) (*Stat, error) {
|
||||
return nil, errors.New("fromStatT should not be called on windows path")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue