@ -1,3 +1,4 @@ | |||||
*.db | *.db | ||||
*.tar | *.tar | ||||
*.tar.gz | *.tar.gz | ||||
tjpkg |
@ -1,114 +0,0 @@ | |||||
package Database | |||||
import ( | |||||
"database/sql" | |||||
"time" | |||||
) | |||||
type FilesystemHashRow struct { | |||||
Path string | |||||
Hash string | |||||
UpdatedAt time.Time | |||||
} | |||||
func FindOrCreateFileHash(rows []FilesystemHashRow) error { | |||||
var ( | |||||
stmtString string | |||||
stmt *sql.Stmt | |||||
values []interface{} = []interface{}{} | |||||
e error | |||||
) | |||||
stmtString = "INSERT OR REPLACE INTO filesystem_hash (id, path, hash, updated_at) VALUES " | |||||
for _, row := range rows { | |||||
stmtString += `( | |||||
(SELECT id FROM filesystem_hash WHERE path = ?), | |||||
?, | |||||
?, | |||||
? | |||||
),` | |||||
values = append(values, row.Path, row.Path, row.Hash, row.UpdatedAt.Unix()) | |||||
} | |||||
stmtString = stmtString[0 : len(stmtString)-1] | |||||
stmt, e = DB.Prepare(stmtString) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
_, e = stmt.Exec(values...) | |||||
return e | |||||
} | |||||
func FindModifiedFiles(hashes []string) (map[int]string, error) { | |||||
var ( | |||||
stmtString string | |||||
stmt *sql.Stmt | |||||
values []interface{} = []interface{}{} | |||||
result *sql.Rows | |||||
dirtyFiles map[int]string = make(map[int]string) | |||||
counter int = 0 | |||||
e error | |||||
) | |||||
stmtString = "SELECT id, path FROM filesystem_hash WHERE hash NOT IN (" | |||||
for _, row := range hashes { | |||||
stmtString += "?," | |||||
values = append(values, row) | |||||
} | |||||
stmtString = stmtString[0:len(stmtString)-1] + ")" | |||||
stmt, e = DB.Prepare(stmtString) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
result, e = stmt.Query(values...) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
defer result.Close() | |||||
for result.Next() { | |||||
var id string | |||||
var path string | |||||
e = result.Scan(&id, &path) | |||||
if e != nil { | |||||
return dirtyFiles, e | |||||
} | |||||
dirtyFiles[counter] = path | |||||
counter++ | |||||
} | |||||
e = result.Err() | |||||
return dirtyFiles, e | |||||
} | |||||
func GetMostRecentTimestamp() (time.Time, error) { | |||||
var ( | |||||
stmt *sql.Stmt | |||||
result *sql.Row | |||||
lastUpdatedAt int64 | |||||
e error | |||||
) | |||||
stmt, e = DB.Prepare(` | |||||
SELECT updated_at FROM filesystem_hash | |||||
ORDER BY updated_at DESC | |||||
LIMIT 1; | |||||
`) | |||||
if e != nil { | |||||
return time.Now(), e | |||||
} | |||||
result = stmt.QueryRow() | |||||
result.Scan(&lastUpdatedAt) | |||||
return time.Unix(lastUpdatedAt, 0), nil | |||||
} |
@ -0,0 +1,48 @@ | |||||
package Filesystem | |||||
import ( | |||||
"PackageManager/Client/Database" | |||||
"PackageManager/Variables" | |||||
"fmt" | |||||
bolt "go.etcd.io/bbolt" | |||||
) | |||||
func CommitFiles() error { | |||||
var ( | |||||
fsStatus FilesystemStatus | |||||
indexBucket *bolt.Bucket | |||||
f string | |||||
e error | |||||
) | |||||
fsStatus, e = GetFilesystemDiff(Variables.RootDir) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
e = Database.FsDB.Batch(func(tx *bolt.Tx) error { | |||||
indexBucket = tx.Bucket(Variables.FsHashIndexBucket) | |||||
if len(fsStatus.PickedFiles) > 0 { | |||||
for _, f = range fsStatus.PickedFiles { | |||||
fmt.Println(f) | |||||
e = AddFileToBucket(indexBucket, f) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
/* | |||||
e = tx.DeleteBucket(Variables.FsHashPicksBucket) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
*/ | |||||
} | |||||
return nil | |||||
}) | |||||
return e | |||||
} |
@ -0,0 +1,77 @@ | |||||
package Filesystem | |||||
import ( | |||||
"crypto/sha1" | |||||
"regexp" | |||||
"PackageManager/Variables" | |||||
) | |||||
var ( | |||||
sha1Hash = sha1.New() | |||||
PruneRegex []*regexp.Regexp | |||||
IgnoreRegex []*regexp.Regexp | |||||
) | |||||
func init() { | |||||
var e error | |||||
e = InitPruneRegex() | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
e = InitIgnoreRegex() | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
} | |||||
func InitPruneRegex() error { | |||||
var ( | |||||
r *regexp.Regexp | |||||
s string | |||||
e error | |||||
) | |||||
for _, s = range Variables.PruneRegexPaths { | |||||
r, e = regexp.Compile(s) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
PruneRegex = append(PruneRegex, r) | |||||
} | |||||
return nil | |||||
} | |||||
func InitIgnoreRegex() error { | |||||
var ( | |||||
r *regexp.Regexp | |||||
s string | |||||
e error | |||||
) | |||||
for _, s = range Variables.IgnoreRegexPaths { | |||||
r, e = regexp.Compile(s) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
IgnoreRegex = append(IgnoreRegex, r) | |||||
} | |||||
return nil | |||||
} | |||||
func matchAny(p string, a []*regexp.Regexp) bool { | |||||
var ( | |||||
regex *regexp.Regexp | |||||
match bool | |||||
) | |||||
for _, regex = range a { | |||||
match = regex.MatchString(p) | |||||
if match == true { | |||||
return true | |||||
} | |||||
} | |||||
return false | |||||
} |
@ -0,0 +1,211 @@ | |||||
package Filesystem | |||||
import ( | |||||
"bytes" | |||||
"encoding/gob" | |||||
"encoding/hex" | |||||
"errors" | |||||
"fmt" | |||||
"io" | |||||
"os" | |||||
"path/filepath" | |||||
) | |||||
var ( | |||||
// TODO: Where do I put this | |||||
Data string | |||||
) | |||||
type Package struct { | |||||
Name string | |||||
Version string | |||||
} | |||||
type FileObject struct { | |||||
FileMode os.FileMode | |||||
Size int64 | |||||
Package Package | |||||
Ref string | |||||
Sha1 []byte | |||||
} | |||||
type ByName []Package | |||||
func (f FileObject) IsLink() bool { | |||||
return f.FileMode&os.ModeSymlink != 0 | |||||
} | |||||
func (f FileObject) objFile() string { | |||||
return filepath.Join(f.objDir(), hex.EncodeToString(f.Sha1)) | |||||
} | |||||
func (f FileObject) objDir() string { | |||||
return filepath.Join(Data, hex.EncodeToString(f.Sha1[:2])) | |||||
} | |||||
func (f FileObject) Reset(dst string) error { | |||||
var e error | |||||
if f.IsLink() { | |||||
_, e = os.Lstat(dst) | |||||
if !os.IsNotExist(e) { | |||||
e = os.Remove(dst) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
e = os.Symlink(f.Ref, dst) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
return nil | |||||
} | |||||
f.cp(f.objFile(), dst) | |||||
e = os.Chmod(dst, f.FileMode) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
return nil | |||||
} | |||||
func (f FileObject) Stov(src string) error { | |||||
var e error | |||||
if f.IsLink() { | |||||
return nil | |||||
} | |||||
e = os.MkdirAll(f.objDir(), 0744) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
f.cp(src, f.objFile()) | |||||
return nil | |||||
} | |||||
func (f FileObject) cp(src string, dst string) error { | |||||
var ( | |||||
srcFile, dstFile *os.File | |||||
e error | |||||
) | |||||
fmt.Println("cp ", src, dst) | |||||
srcFile, e = os.Open(src) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
defer srcFile.Close() | |||||
dstFile, e = os.Create(dst) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
defer dstFile.Close() | |||||
_, e = io.Copy(dstFile, srcFile) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
return dstFile.Sync() | |||||
} | |||||
func (f FileObject) IsDifferent(fn FileObject) error { | |||||
if f.FileMode != fn.FileMode { | |||||
return errors.New("Mode does not match") | |||||
} | |||||
if f.IsLink() { | |||||
if f.Ref != fn.Ref { | |||||
return errors.New("Ref does not match") | |||||
} | |||||
return nil | |||||
} | |||||
if f.Size != fn.Size { | |||||
return errors.New("Size does not match") | |||||
} | |||||
if bytes.Compare(f.Sha1, fn.Sha1) != 0 { | |||||
return errors.New("Sha1 does not match") | |||||
} | |||||
return nil | |||||
} | |||||
func CreateFileObject(f string) (FileObject, error) { | |||||
var ( | |||||
fo FileObject | |||||
fi os.FileInfo | |||||
file *os.File | |||||
e error | |||||
) | |||||
fi, e = os.Lstat(f) | |||||
if e != nil { | |||||
return fo, e | |||||
} | |||||
fo = FileObject{ | |||||
FileMode: fi.Mode(), | |||||
Size: fi.Size(), | |||||
} | |||||
if fo.IsLink() { | |||||
fo.Ref, e = os.Readlink(f) | |||||
if e != nil { | |||||
return fo, e | |||||
} | |||||
return fo, nil | |||||
} | |||||
file, e = os.Open(f) | |||||
if e != nil { | |||||
return fo, e | |||||
} | |||||
defer file.Close() | |||||
io.Copy(sha1Hash, file) | |||||
fo.Sha1 = sha1Hash.Sum(nil) | |||||
return fo, nil | |||||
} | |||||
func (f FileObject) ToBytes() ([]byte, error) { | |||||
var ( | |||||
encoder *gob.Encoder | |||||
buf bytes.Buffer | |||||
e error | |||||
) | |||||
encoder = gob.NewEncoder(&buf) | |||||
e = encoder.Encode(f) | |||||
return buf.Bytes(), e | |||||
} | |||||
func FromBytes(v []byte) (FileObject, error) { | |||||
var ( | |||||
buf *bytes.Buffer | |||||
decoder *gob.Decoder | |||||
fo FileObject | |||||
e error | |||||
) | |||||
buf = bytes.NewBuffer(v) | |||||
decoder = gob.NewDecoder(buf) | |||||
e = decoder.Decode(&fo) | |||||
if e != nil { | |||||
return fo, e | |||||
} | |||||
return fo, nil | |||||
} |
@ -0,0 +1,171 @@ | |||||
package Filesystem | |||||
import ( | |||||
"PackageManager/Client/Database" | |||||
"PackageManager/Variables" | |||||
"fmt" | |||||
"log" | |||||
"os" | |||||
"path/filepath" | |||||
bolt "go.etcd.io/bbolt" | |||||
) | |||||
type FilesystemStatus struct { | |||||
NewFiles []string | |||||
PickedFiles []string | |||||
ModifiedFiles []string | |||||
MissingFiles []string | |||||
} | |||||
func ShowFilesystemDiff(root string) error { | |||||
var ( | |||||
fsStatus FilesystemStatus | |||||
//f string | |||||
e error | |||||
) | |||||
fsStatus, e = GetFilesystemDiff(root) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
if len(fsStatus.NewFiles) > 0 { | |||||
fmt.Printf("New files: %d\n", len(fsStatus.NewFiles)) | |||||
/* | |||||
fmt.Println("New files:") | |||||
for _, f = range fsStatus.NewFiles { | |||||
fmt.Printf("\t%s\n", Color.Green(f)) | |||||
} | |||||
*/ | |||||
} | |||||
if len(fsStatus.PickedFiles) > 0 { | |||||
fmt.Printf("Picked files: %d\n", len(fsStatus.PickedFiles)) | |||||
/* | |||||
fmt.Println("Added files:") | |||||
for _, f = range fsStatus.PickedFiles { | |||||
fmt.Printf("\t%s\n", Color.Green(f)) | |||||
} | |||||
*/ | |||||
} | |||||
if len(fsStatus.ModifiedFiles) > 0 { | |||||
fmt.Printf("Modified files: %d\n", len(fsStatus.ModifiedFiles)) | |||||
/* | |||||
fmt.Println("Modified files:") | |||||
for _, f = range fsStatus.ModifiedFiles { | |||||
fmt.Printf("\t%s\n", Color.Green(f)) | |||||
} | |||||
*/ | |||||
} | |||||
if len(fsStatus.MissingFiles) > 0 { | |||||
fmt.Printf("Modified files: %d\n", len(fsStatus.MissingFiles)) | |||||
/* | |||||
fmt.Println("Deleted files:") | |||||
for _, f = range fsStatus.MissingFiles { | |||||
fmt.Printf("\t%s\n", Color.Green(f)) | |||||
} | |||||
*/ | |||||
} | |||||
return nil | |||||
} | |||||
func GetFilesystemDiff(root string) (FilesystemStatus, error) { | |||||
var ( | |||||
fsStatus FilesystemStatus = FilesystemStatus{} | |||||
rootStat os.FileInfo | |||||
picksBucket *bolt.Bucket | |||||
indexBucket *bolt.Bucket | |||||
pick, known []byte | |||||
newFileObject FileObject | |||||
knownFileObject FileObject | |||||
e error | |||||
) | |||||
rootStat, e = os.Stat(root) | |||||
if e != nil { | |||||
return fsStatus, e | |||||
} | |||||
if rootStat.IsDir() && root[len(root)-1:] != "/" { | |||||
root = root + "/" | |||||
} | |||||
e = Database.FsDB.View(func(tx *bolt.Tx) error { | |||||
picksBucket = tx.Bucket(Variables.FsHashPicksBucket) | |||||
indexBucket = tx.Bucket(Variables.FsHashPicksBucket) | |||||
filepath.Walk(root, func(p string, i os.FileInfo, _ error) error { | |||||
// Ignore path in Variables.PruneRegexPaths | |||||
if i.IsDir() && matchAny(p, PruneRegex) { | |||||
log.Println("Prune", p) | |||||
return filepath.SkipDir | |||||
} | |||||
// Ignore path in Variables.IgnoreRegexPaths | |||||
if matchAny(p, IgnoreRegex) { | |||||
return nil | |||||
} | |||||
if !i.Mode().IsRegular() && (i.Mode()&os.ModeSymlink == 0) { | |||||
return nil | |||||
} | |||||
pick = picksBucket.Get([]byte(p)) | |||||
known = indexBucket.Get([]byte(p)) | |||||
if pick != nil { | |||||
fsStatus.PickedFiles = append(fsStatus.PickedFiles, p) | |||||
return nil | |||||
} | |||||
if known != nil { | |||||
newFileObject, e = CreateFileObject(p) | |||||
if os.IsNotExist(e) { | |||||
return nil | |||||
} | |||||
if e != nil { | |||||
return e | |||||
} | |||||
knownFileObject, e = FromBytes(known) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
e = newFileObject.IsDifferent(knownFileObject) | |||||
if e != nil { | |||||
fsStatus.ModifiedFiles = append(fsStatus.ModifiedFiles, p) | |||||
} | |||||
return nil | |||||
} | |||||
fsStatus.NewFiles = append(fsStatus.NewFiles, p) | |||||
return nil | |||||
}) | |||||
indexBucket.ForEach(func(k, v []byte) error { | |||||
_, e = os.Lstat(string(k)) | |||||
if os.IsNotExist(e) { | |||||
fsStatus.MissingFiles = append(fsStatus.MissingFiles, string(k)) | |||||
} | |||||
return nil | |||||
}) | |||||
return nil | |||||
}) | |||||
return fsStatus, e | |||||
} |
@ -1,170 +0,0 @@ | |||||
package Filesystem | |||||
import ( | |||||
"PackageManager/Client/Database" | |||||
"PackageManager/Variables" | |||||
"crypto/md5" | |||||
"fmt" | |||||
"io/ioutil" | |||||
"os" | |||||
"path/filepath" | |||||
"strings" | |||||
"time" | |||||
) | |||||
func HashFile(path string) (string, error) { | |||||
var ( | |||||
Md5Hash string | |||||
hashBytes [16]byte | |||||
file *os.File | |||||
e error | |||||
) | |||||
file, e = os.Open(path) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
defer file.Close() | |||||
body, e := ioutil.ReadAll(file) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
//Get the 16 bytes hash | |||||
hashBytes = md5.Sum(body) | |||||
//Convert the bytes to a string | |||||
Md5Hash = fmt.Sprintf("%x", hashBytes) | |||||
return Md5Hash, nil | |||||
} | |||||
func UpdateFilesystemHash() error { | |||||
var ( | |||||
fileHash string | |||||
rows []Database.FilesystemHashRow | |||||
dir string | |||||
e error | |||||
) | |||||
for _, dir = range Variables.InstallDirs { | |||||
_, e = os.Stat(dir) | |||||
if os.IsNotExist(e) { | |||||
continue | |||||
} | |||||
e = filepath.Walk(dir, func(path string, info os.FileInfo, e error) error { | |||||
if e != nil { | |||||
return e | |||||
} | |||||
// Ignore hidden files | |||||
if strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(path, ".") { | |||||
return nil | |||||
} | |||||
// Ignore directories | |||||
if info.IsDir() { | |||||
return nil | |||||
} | |||||
fileHash, e = HashFile(path) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
rows = append(rows, Database.FilesystemHashRow{ | |||||
Path: path, | |||||
Hash: fileHash, | |||||
UpdatedAt: info.ModTime(), | |||||
}) | |||||
// TODO: If len(rows) > x, update the db and clear out rows, and continue | |||||
return nil | |||||
}) | |||||
if e != nil { | |||||
panic(e) | |||||
} | |||||
} | |||||
return Database.FindOrCreateFileHash(rows) | |||||
} | |||||
func GetFilesystemDiff() (map[int]string, map[int]string, error) { | |||||
var ( | |||||
fileHash string | |||||
hashes []string = []string{} | |||||
lastUpdatedAt time.Time | |||||
dirtyFiles map[int]string | |||||
newFiles map[int]string = make(map[int]string) | |||||
newFilesTmp map[string]string = make(map[string]string) | |||||
counter int | |||||
ok bool | |||||
e error | |||||
) | |||||
lastUpdatedAt, e = Database.GetMostRecentTimestamp() | |||||
if e != nil { | |||||
return dirtyFiles, newFiles, e | |||||
} | |||||
e = filepath.Walk(".", func(path string, info os.FileInfo, e error) error { | |||||
if e != nil { | |||||
return e | |||||
} | |||||
// Ignore hidden files | |||||
if strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(path, ".") { | |||||
return nil | |||||
} | |||||
// Ignore directories | |||||
if info.IsDir() { | |||||
return nil | |||||
} | |||||
fileHash, e = HashFile(path) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
hashes = append(hashes, fileHash) | |||||
if info.ModTime().After(lastUpdatedAt) { | |||||
newFilesTmp[path] = path | |||||
} | |||||
// TODO: If len(rows) > x, update the db and clear out rows, and continue | |||||
return nil | |||||
}) | |||||
if e != nil { | |||||
return dirtyFiles, newFiles, e | |||||
} | |||||
dirtyFiles, e = Database.FindModifiedFiles(hashes) | |||||
if e != nil { | |||||
return dirtyFiles, newFiles, e | |||||
} | |||||
for _, file := range dirtyFiles { | |||||
_, ok = newFilesTmp[file] | |||||
if ok { | |||||
delete(newFilesTmp, file) | |||||
} | |||||
} | |||||
counter = len(dirtyFiles) | |||||
for _, file := range newFilesTmp { | |||||
newFiles[counter] = file | |||||
counter++ | |||||
} | |||||
return dirtyFiles, newFiles, e | |||||
} |
@ -0,0 +1,31 @@ | |||||
package Filesystem | |||||
import ( | |||||
"os" | |||||
bolt "go.etcd.io/bbolt" | |||||
) | |||||
func AddFileToBucket(bucket *bolt.Bucket, filePath string) error { | |||||
var ( | |||||
fileObject FileObject | |||||
fileObjectBytes []byte | |||||
e error | |||||
) | |||||
fileObject, e = CreateFileObject(filePath) | |||||
if os.IsNotExist(e) { | |||||
return nil | |||||
} | |||||
if e != nil { | |||||
return e | |||||
} | |||||
fileObjectBytes, e = fileObject.ToBytes() | |||||
if e != nil { | |||||
return e | |||||
} | |||||
return bucket.Put([]byte(filePath), fileObjectBytes) | |||||
} | |||||
func RemoveFileFromBucket(bucket *bolt.Bucket, filePath string) error { | |||||
return bucket.Delete([]byte(filePath)) | |||||
} |
@ -0,0 +1,88 @@ | |||||
package Filesystem | |||||
import ( | |||||
"PackageManager/Client/Database" | |||||
"PackageManager/Variables" | |||||
bolt "go.etcd.io/bbolt" | |||||
) | |||||
func PickFiles(rootPath string) error { | |||||
var ( | |||||
fsStatus FilesystemStatus | |||||
picksBucket *bolt.Bucket | |||||
f string | |||||
e error | |||||
) | |||||
fsStatus, e = GetFilesystemDiff(rootPath) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
e = Database.FsDB.Batch(func(tx *bolt.Tx) error { | |||||
picksBucket = tx.Bucket(Variables.FsHashPicksBucket) | |||||
if len(fsStatus.NewFiles) > 0 { | |||||
for _, f = range fsStatus.NewFiles { | |||||
e = AddFileToBucket(picksBucket, f) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
} | |||||
if len(fsStatus.ModifiedFiles) > 0 { | |||||
for _, f = range fsStatus.NewFiles { | |||||
e = AddFileToBucket(picksBucket, f) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
} | |||||
if len(fsStatus.MissingFiles) > 0 { | |||||
for _, f = range fsStatus.NewFiles { | |||||
e = RemoveFileFromBucket(picksBucket, f) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
} | |||||
return nil | |||||
}) | |||||
return e | |||||
} | |||||
func ResetAllPickedFiles() error { | |||||
var ( | |||||
fsStatus FilesystemStatus | |||||
picksBucket *bolt.Bucket | |||||
f string | |||||
e error | |||||
) | |||||
fsStatus, e = GetFilesystemDiff(Variables.RootDir) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
e = Database.FsDB.Batch(func(tx *bolt.Tx) error { | |||||
picksBucket = tx.Bucket(Variables.FsHashPicksBucket) | |||||
if len(fsStatus.PickedFiles) > 0 { | |||||
for _, f = range fsStatus.PickedFiles { | |||||
e = RemoveFileFromBucket(picksBucket, f) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
} | |||||
} | |||||
return nil | |||||
}) | |||||
return e | |||||
} |
@ -1,145 +1,134 @@ | |||||
package Package | package Package | ||||
import ( | |||||
"errors" | |||||
"fmt" | |||||
"io/ioutil" | |||||
"os" | |||||
"path/filepath" | |||||
"strconv" | |||||
"strings" | |||||
"PackageManager/Archive" | |||||
"PackageManager/Client/Filesystem" | |||||
"PackageManager/Color" | |||||
"PackageManager/Helper" | |||||
) | |||||
func CreatePackage() error { | func CreatePackage() error { | ||||
var ( | |||||
dirtyFiles map[int]string | |||||
newFiles map[int]string | |||||
pkgFiles map[int]string = make(map[int]string) | |||||
choices string | |||||
choicesSplit []string | |||||
filePath string | |||||
pkgName string | |||||
pkgVersion string | |||||
pkgNameVersion string | |||||
tmpDir string | |||||
index int | |||||
ok bool | |||||
e error | |||||
) | |||||
fmt.Println("Initialising package creation...") | |||||
dirtyFiles, newFiles, e = Filesystem.GetFilesystemDiff() | |||||
if e != nil { | |||||
return e | |||||
} | |||||
fmt.Println("\nModified files...") | |||||
for i, file := range dirtyFiles { | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Red(file), | |||||
) | |||||
} | |||||
return nil | |||||
fmt.Println("\nNew files...") | |||||
for i, file := range newFiles { | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Red(file), | |||||
/* | |||||
var ( | |||||
dirtyFiles map[int]string | |||||
newFiles map[int]string | |||||
pkgFiles map[int]string = make(map[int]string) | |||||
choices string | |||||
choicesSplit []string | |||||
filePath string | |||||
pkgName string | |||||
pkgVersion string | |||||
pkgNameVersion string | |||||
tmpDir string | |||||
index int | |||||
ok bool | |||||
e error | |||||
) | ) | ||||
} | |||||
fmt.Println("Please select the files you would like to use to create the package. Leave empty for all.") | |||||
choices = Helper.Input() | |||||
fmt.Println("Initialising package creation...") | |||||
dirtyFiles, newFiles, e = Filesystem.GetFilesystemDiff() | |||||
if e != nil { | |||||
return e | |||||
} | |||||
if choices == "" { | |||||
fmt.Println("\nModified files...") | |||||
for i, file := range dirtyFiles { | for i, file := range dirtyFiles { | ||||
pkgFiles[i] = file | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Red(file), | |||||
) | |||||
} | } | ||||
fmt.Println("\nNew files...") | |||||
for i, file := range newFiles { | for i, file := range newFiles { | ||||
pkgFiles[i] = file | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Red(file), | |||||
) | |||||
} | } | ||||
} else { | |||||
choicesSplit = strings.Split(choices, ",") | |||||
fmt.Println("Please select the files you would like to use to create the package. Leave empty for all.") | |||||
choices = Helper.Input() | |||||
for _, i := range choicesSplit { | |||||
index, e = strconv.Atoi(i) | |||||
if e != nil { | |||||
// TODO: Handle this error | |||||
panic(e) | |||||
if choices == "" { | |||||
for i, file := range dirtyFiles { | |||||
pkgFiles[i] = file | |||||
} | |||||
for i, file := range newFiles { | |||||
pkgFiles[i] = file | |||||
} | } | ||||
filePath, ok = dirtyFiles[index] | |||||
if !ok { | |||||
filePath, ok = newFiles[index] | |||||
} else { | |||||
choicesSplit = strings.Split(choices, ",") | |||||
for _, i := range choicesSplit { | |||||
index, e = strconv.Atoi(i) | |||||
if e != nil { | |||||
// TODO: Handle this error | |||||
panic(e) | |||||
} | |||||
filePath, ok = dirtyFiles[index] | |||||
if !ok { | if !ok { | ||||
return errors.New("Invalid package selection") | |||||
filePath, ok = newFiles[index] | |||||
if !ok { | |||||
return errors.New("Invalid package selection") | |||||
} | |||||
} | } | ||||
pkgFiles[index] = filePath | |||||
} | } | ||||
pkgFiles[index] = filePath | |||||
} | } | ||||
} | |||||
fmt.Println("Please enter the package name:") | |||||
pkgName = Helper.Input() | |||||
if pkgName == "" { | |||||
return errors.New("Invalid package name") | |||||
} | |||||
fmt.Println("Please enter the package name:") | |||||
pkgName = Helper.Input() | |||||
if pkgName == "" { | |||||
return errors.New("Invalid package name") | |||||
} | |||||
fmt.Println("Please enter the package version:") | |||||
pkgVersion = Helper.Input() | |||||
if pkgVersion == "" { | |||||
return errors.New("Invalid package name") | |||||
} | |||||
fmt.Println("Please enter the package version:") | |||||
pkgVersion = Helper.Input() | |||||
if pkgVersion == "" { | |||||
return errors.New("Invalid package name") | |||||
} | |||||
fmt.Printf("Package Name: %s\n", pkgName) | |||||
fmt.Printf("Package Version: %s\n", pkgVersion) | |||||
fmt.Printf("Package Name: %s\n", pkgName) | |||||
fmt.Printf("Package Version: %s\n", pkgVersion) | |||||
fmt.Println("Files to be added") | |||||
for i, file := range pkgFiles { | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Green(file), | |||||
) | |||||
} | |||||
fmt.Println("Files to be added") | |||||
for i, file := range pkgFiles { | |||||
fmt.Printf( | |||||
"\t%d - %s\n", | |||||
i, | |||||
Color.Green(file), | |||||
) | |||||
} | |||||
fmt.Println("Is this correct? [y/N]") | |||||
if strings.ToLower(Helper.Input()) != "y" { | |||||
return errors.New("User aborted") | |||||
} | |||||
fmt.Println("Is this correct? [y/N]") | |||||
if strings.ToLower(Helper.Input()) != "y" { | |||||
return errors.New("User aborted") | |||||
} | |||||
pkgNameVersion = fmt.Sprintf("%s-%s", pkgName, pkgVersion) | |||||
pkgNameVersion = fmt.Sprintf("%s-%s", pkgName, pkgVersion) | |||||
tmpDir, e = ioutil.TempDir("/tmp", pkgNameVersion) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
defer os.RemoveAll(tmpDir) | |||||
tmpDir, e = ioutil.TempDir("/tmp", pkgNameVersion) | |||||
if e != nil { | |||||
return e | |||||
} | |||||
defer os.RemoveAll(tmpDir) | |||||
for _, file := range pkgFiles { | |||||
Filesystem.CopyFile(file, filepath.Join(tmpDir, file)) | |||||
} | |||||
for _, file := range pkgFiles { | |||||
Filesystem.CopyFile(file, filepath.Join(tmpDir, file)) | |||||
} | |||||
// TODO: Add dependancy management here | |||||
// TODO: Add dependancy management here | |||||
e = Archive.TarGzip(tmpDir, pkgNameVersion+".tar.gz") | |||||
if e != nil { | |||||
return e | |||||
} | |||||
e = Archive.TarGzip(tmpDir, pkgNameVersion+".tar.gz") | |||||
if e != nil { | |||||
return e | |||||
} | |||||
fmt.Printf( | |||||
Color.Green("\nSuccessfully created package %s\n"), | |||||
pkgNameVersion, | |||||
) | |||||
fmt.Printf( | |||||
Color.Green("\nSuccessfully created package %s\n"), | |||||
pkgNameVersion, | |||||
) | |||||
return nil | |||||
return nil | |||||
*/ | |||||
} | } |
@ -0,0 +1,14 @@ | |||||
CLIENT_MAIN=Client/main.go | |||||
BUILD=go build -o | |||||
BUILD32=env GOARCH=386 go build | |||||
LINUX_LDFLAGS=--ldflags "-s -w -extldflags=-static" | |||||
LINUX_ENV=env GOOS=linux GOARCH=amd64 | |||||
LINUX_ENV32=env GOOS=linux GOARCH=386 | |||||
LINUX_OUT=tjpkg | |||||
build: | |||||
${LINUX_ENV} ${BUILD} ${LINUX_OUT} ${CLIENT_MAIN} |