| @ -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} | |||||