diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98e6ef6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.db diff --git a/Client/Database/Filesystem.go b/Client/Database/Filesystem.go index 489879d..11b56eb 100644 --- a/Client/Database/Filesystem.go +++ b/Client/Database/Filesystem.go @@ -2,7 +2,6 @@ package Database import ( "database/sql" - "fmt" "time" ) @@ -29,7 +28,7 @@ func FindOrCreateFileHash(rows []FilesystemHashRow) error { ?, ? ),` - values = append(values, row.Path, row.Path, row.Hash, row.UpdatedAt.String()) + values = append(values, row.Path, row.Path, row.Hash, row.UpdatedAt.Unix()) } stmtString = stmtString[0 : len(stmtString)-1] @@ -44,13 +43,14 @@ func FindOrCreateFileHash(rows []FilesystemHashRow) error { return e } -func FindModifiedFiles(hashes []string) ([]string, error) { +func FindModifiedFiles(hashes []string) (map[int]string, error) { var ( stmtString string stmt *sql.Stmt values []interface{} = []interface{}{} result *sql.Rows - dirtyFiles []string = []string{} + dirtyFiles map[int]string = make(map[int]string) + counter int = 0 e error ) @@ -76,68 +76,39 @@ func FindModifiedFiles(hashes []string) ([]string, error) { defer result.Close() for result.Next() { var id string - var hash string - e = result.Scan(&id, &hash) + var path string + e = result.Scan(&id, &path) if e != nil { return dirtyFiles, e } - fmt.Println(id, hash) - dirtyFiles = append(dirtyFiles, hash) + dirtyFiles[counter] = path + counter++ } e = result.Err() return dirtyFiles, e } -/* -func FindNewFiles(files []string) ([]string, error) { +func GetMostRecentTimestamp() (time.Time, error) { var ( - stmtString string - stmt *sql.Stmt - values []interface{} = []interface{}{} - result *sql.Rows - dirtyFiles []string = []string{} - e error + stmt *sql.Stmt + result *sql.Row + lastUpdatedAt int64 + e error ) - stmtString = `select * -from ( - values (4),(5),(6) -) as v(id) -where not exists (select * - from images i - where i.id = v.id);` - - for _, row := range hashes { - stmtString += "?," - values = append(values, row) - } - - stmtString = stmtString[0:len(stmtString)-1] + ")" - - stmt, e = DB.Prepare(stmtString) + stmt, e = DB.Prepare(` + SELECT updated_at FROM filesystem_hash + ORDER BY updated_at DESC + LIMIT 1; + `) if e != nil { - return dirtyFiles, e + return time.Now(), e } - result, e = stmt.Query(values...) - if e != nil { - return dirtyFiles, e - } + result = stmt.QueryRow() - defer result.Close() - for result.Next() { - var id string - var hash string - e = result.Scan(&id, &hash) - if e != nil { - return dirtyFiles, e - } - fmt.Println(id, hash) - dirtyFiles = append(dirtyFiles, hash) - } + result.Scan(&lastUpdatedAt) - e = result.Err() - return dirtyFiles, e + return time.Unix(lastUpdatedAt, 0), nil } -*/ diff --git a/Client/Database/Init.go b/Client/Database/Init.go index 1aa7d2c..98b2596 100644 --- a/Client/Database/Init.go +++ b/Client/Database/Init.go @@ -30,8 +30,8 @@ func InitDB() error { id INTEGER NOT NULL PRIMARY KEY, path VARCHAR(256), hash VARCHAR(64), - created_at DATE DEFAULT CURRENT_TIMESTAMP, - updated_at DATE + created_at INTEGER DEFAULT CURRENT_TIMESTAMP, + updated_at INTEGER ) ` _, e = DB.Exec(sqlStmt) diff --git a/Client/Filesystem/HashFilesystem.go b/Client/Filesystem/HashFilesystem.go index 262e7c6..bca43c7 100644 --- a/Client/Filesystem/HashFilesystem.go +++ b/Client/Filesystem/HashFilesystem.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strings" + "time" ) func HashFile(path string) (string, error) { @@ -85,13 +86,24 @@ func UpdateFilesystemHash() error { return Database.FindOrCreateFileHash(rows) } -func GetFilesystemDiff() error { +func GetFilesystemDiff() (map[int]string, map[int]string, error) { var ( - fileHash string - hashes []string = []string{} - e error + 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 @@ -115,14 +127,31 @@ func GetFilesystemDiff() error { 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 + } - dirty, e := Database.FindModifiedFiles(hashes) + dirtyFiles, e = Database.FindModifiedFiles(hashes) + if e != nil { + return dirtyFiles, newFiles, e + } - fmt.Println(dirty) + counter = len(dirtyFiles) + + for _, file := range dirtyFiles { + _, ok = newFilesTmp[file] + if !ok { + newFiles[counter] = file + } + } - return e + return dirtyFiles, newFiles, e } diff --git a/Client/Package/CreatePackage.go b/Client/Package/CreatePackage.go new file mode 100644 index 0000000..31ab612 --- /dev/null +++ b/Client/Package/CreatePackage.go @@ -0,0 +1,115 @@ +package Package + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "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 + 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), + ) + } + + fmt.Println("\nNew files...") + for i, file := range newFiles { + fmt.Printf( + "\t%d - %s\n", + i, + Color.Red(file), + ) + } + + fmt.Println("Please select the files you would like to use to create the package. Leave empty for all.") + choices = Helper.Input() + + if choices == "" { + for i, file := range dirtyFiles { + pkgFiles[i] = file + } + for i, file := range newFiles { + pkgFiles[i] = file + } + } 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 { + filePath, ok = dirtyFiles[index] + if !ok { + return errors.New("Invalid package selection") + } + } + 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 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.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") + } + + return nil +} diff --git a/Client/main.go b/Client/main.go index e68248b..faec932 100644 --- a/Client/main.go +++ b/Client/main.go @@ -1,30 +1,59 @@ package main import ( + "flag" + "fmt" + "PackageManager/Client/Database" "PackageManager/Client/Filesystem" + "PackageManager/Client/Package" + "PackageManager/Color" ) func main() { - var e error + var ( + updateFilesytemFlag bool + updateFilesytemFlagLong bool + createPackageFlag bool + createPackageFlagLong bool + + e error + ) e = Database.InitDB() if e != nil { panic(e) } - /* + // Initialise flags + flag.BoolVar(&updateFilesytemFlag, "Uf", false, "Update filesystem database") + flag.BoolVar(&updateFilesytemFlagLong, "update-filesystem", false, "Update filesystem database") + + flag.BoolVar(&createPackageFlag, "Cp", false, "Create package") + flag.BoolVar(&createPackageFlagLong, "create-package", false, "Create Package") + + flag.Parse() + + if updateFilesytemFlag || updateFilesytemFlagLong { e = Filesystem.UpdateFilesystemHash() if e != nil { panic(e) } - */ - e = Filesystem.GetFilesystemDiff() - if e != nil { - panic(e) + return } + if createPackageFlag || createPackageFlagLong { + e = Package.CreatePackage() + if e != nil { + panic(e) + } + return + } + + flag.Usage() + fmt.Println(Color.Fatal("Nothing to do")) + //e := Archive.TarGzip("/tmp/test", "/tmp/test.tar.gz") //e := Archive.UntarGzip("/tmp/test.tar.gz", "/tmp/test") //fmt.Println(e) diff --git a/Color/Color.go b/Color/Color.go new file mode 100644 index 0000000..3d4a9d2 --- /dev/null +++ b/Color/Color.go @@ -0,0 +1,58 @@ +package Color + +import ( + "fmt" + "regexp" + "runtime" +) + +var ( + Success = Green + Info = Teal + Warning = Yellow + Fatal = Red +) + +var ( + Black = Color("\033[1;30m%s\033[0m") + Red = Color("\033[1;31m%s\033[0m") + Green = Color("\033[1;32m%s\033[0m") + Yellow = Color("\033[1;33m%s\033[0m") + Purple = Color("\033[1;34m%s\033[0m") + Magenta = Color("\033[1;35m%s\033[0m") + Teal = Color("\033[1;36m%s\033[0m") + White = Color("\033[1;37m%s\033[0m") +) + +func init() { + if runtime.GOOS != "windows" { + return + } + + Black = Color("%s") + Red = Color("%s") + Green = Color("%s") + Yellow = Color("%s") + Purple = Color("%s") + Magenta = Color("%s") + Teal = Color("%s") + White = Color("%s") +} + +func Color(colorString string) func(...interface{}) string { + sprint := func(args ...interface{}) string { + return fmt.Sprintf(colorString, + fmt.Sprint(args...)) + } + return sprint +} + +func Strip(s string) string { + var ( + reg *regexp.Regexp + res string + ) + reg = regexp.MustCompile("\\033\\[.{1,4}m") + res = reg.ReplaceAllString(s, "${1}") + return res +} diff --git a/Helper/Input.go b/Helper/Input.go new file mode 100644 index 0000000..369778e --- /dev/null +++ b/Helper/Input.go @@ -0,0 +1,24 @@ +package Helper + +import ( + "bufio" + "os" + "strings" +) + +var ( + reader *bufio.Reader = bufio.NewReader(os.Stdin) +) + +func Input() string { + var ( + text string + e error + ) + text, e = reader.ReadString('\n') + if e != nil { + panic(e) + } + // convert CRLF to LF + return strings.Replace(text, "\n", "", -1) +} diff --git a/package_manager.db b/package_manager.db deleted file mode 100644 index 01f184c..0000000 Binary files a/package_manager.db and /dev/null differ