| @ -1,3 +1,4 @@ | |||
| *.db | |||
| *.tar | |||
| *.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 | |||
| import ( | |||
| "errors" | |||
| "fmt" | |||
| "io/ioutil" | |||
| "os" | |||
| "path/filepath" | |||
| "strconv" | |||
| "strings" | |||
| "PackageManager/Archive" | |||
| "PackageManager/Client/Filesystem" | |||
| "PackageManager/Color" | |||
| "PackageManager/Helper" | |||
| ) | |||
| 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 { | |||
| pkgFiles[i] = file | |||
| fmt.Printf( | |||
| "\t%d - %s\n", | |||
| i, | |||
| Color.Red(file), | |||
| ) | |||
| } | |||
| fmt.Println("\nNew files...") | |||
| 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 { | |||
| 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} | |||