Created
June 11, 2025 12:51
-
-
Save mzaini30/9ba080bcb7a98ff94fc9650806233e0b to your computer and use it in GitHub Desktop.
Source code untuk aplikasi backup folder ke flashdisk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"crypto/sha256" | |
"fmt" | |
"io" | |
"os" | |
"os/exec" | |
"path/filepath" | |
"strings" | |
) | |
func main() { | |
// Get target volume label from user | |
var volumeLabel string | |
fmt.Print("Hai sayang! Masukkan label volume target (misalnya, f): ") | |
fmt.Scanln(&volumeLabel) | |
// Get current directory | |
sourceDir, err := os.Getwd() | |
if err != nil { | |
fmt.Println("Aduh, ada error saat mencari direktori saat ini:", err, "") | |
return | |
} | |
// Construct target directory path | |
targetDir := volumeLabel + ":\\" | |
// Read .gitignore file | |
ignoredPaths, err := readGitignore(sourceDir) | |
if err != nil { | |
fmt.Println("Error reading .gitignore:", err) | |
return | |
} | |
// Walk through the source directory | |
err = filepath.Walk(sourceDir, func(sourcePath string, info os.FileInfo, err error) error { | |
if err != nil { | |
fmt.Println("Waduh, gak bisa akses path:", sourcePath, err, "") | |
return err | |
} | |
// Check if path is ignored | |
relativePath, err := filepath.Rel(sourceDir, sourcePath) | |
if err != nil { | |
fmt.Println("Aduh, relatif pathnya error:", err, "") | |
return err | |
} | |
for _, ignoredPath := range ignoredPaths { | |
if strings.HasPrefix(relativePath, ignoredPath) { | |
if info.IsDir() { | |
return filepath.SkipDir | |
} | |
fmt.Println("Gak jadi copy karena diabaikan:", sourcePath) | |
return nil | |
} | |
} | |
// Construct target path | |
targetPath := filepath.Join(targetDir, relativePath) | |
// Create target directory if it doesn't exist | |
if info.IsDir() { | |
if _, err := os.Stat(targetPath); os.IsNotExist(err) { | |
err := os.MkdirAll(targetPath, os.ModeDir|0755) | |
if err != nil { | |
fmt.Println("Error creating directory:", targetPath, err) | |
return err | |
} | |
fmt.Println("Asiiiik, berhasil buat direktori:", targetPath) | |
} | |
return nil | |
} else { | |
targetDir := filepath.Dir(targetPath) | |
if _, err := os.Stat(targetDir); os.IsNotExist(err) { | |
err := os.MkdirAll(targetDir, os.ModeDir|0755) | |
if err != nil { | |
fmt.Println("Error creating directory:", targetDir, err) | |
return err | |
} | |
fmt.Println("Asiiiik, berhasil buat direktori:", targetDir) | |
} | |
} | |
// Check if file exists in target | |
if _, err := os.Stat(targetPath); os.IsNotExist(err) { | |
// Copy file to target | |
err := copyFile(sourcePath, targetPath) | |
if err != nil { | |
fmt.Println("Error copying file:", sourcePath, "to", targetPath, err) | |
return err | |
} | |
fmt.Println("Berhasil copy file:", sourcePath, "ke", targetPath) | |
} else { | |
// Compare SHA checksums | |
sourceChecksum, err := calculateSHA256(sourcePath) | |
if err != nil { | |
fmt.Println("Error calculating SHA256 for source:", sourcePath, err) | |
return err | |
} | |
targetChecksum, err := calculateSHA256(targetPath) | |
if err != nil { | |
fmt.Println("Error calculating SHA256 for target:", targetPath, err) | |
return err | |
} | |
if sourceChecksum != targetChecksum { | |
// Replace target file with source file | |
err := copyFile(sourcePath, targetPath) | |
if err != nil { | |
fmt.Println("Error replacing file:", targetPath, "with", sourcePath, err) | |
return err | |
} | |
fmt.Println("Diganti file:", targetPath, "dengan", sourcePath) | |
} else { | |
// Files are the same, skip | |
fmt.Println("File sama kok, gak ada perubahan:", sourcePath) | |
} | |
} | |
return nil | |
}) | |
if err != nil { | |
fmt.Println("Error walking directory:", err) | |
return | |
} | |
fmt.Println("Backup selesai, sayang!") | |
cmd := exec.Command("cmd", "/c", "pause") | |
cmd.Stdout = os.Stdout | |
cmd.Stderr = os.Stderr | |
cmd.Stdin = os.Stdin // penting agar bisa menerima input | |
cmd.Run() | |
// fmt.Println("Tekan Enter untuk keluar...") | |
// fmt.Scanln() | |
} | |
func readGitignore(sourceDir string) ([]string, error) { | |
var ignoredPaths []string | |
file, err := os.Open(filepath.Join(sourceDir, ".gitignore")) | |
if os.IsNotExist(err) { | |
return ignoredPaths, nil | |
} else if err != nil { | |
return nil, err | |
} | |
defer file.Close() | |
scanner := bufio.NewScanner(file) | |
for scanner.Scan() { | |
line := scanner.Text() | |
line = strings.TrimSpace(line) | |
if line == "" || strings.HasPrefix(line, "#") { | |
continue | |
} | |
ignoredPaths = append(ignoredPaths, line) | |
} | |
if err := scanner.Err(); err != nil { | |
return nil, err | |
} | |
return ignoredPaths, nil | |
} | |
func calculateSHA256(filePath string) (string, error) { | |
file, err := os.Open(filePath) | |
if err != nil { | |
return "", err | |
} | |
defer file.Close() | |
hash := sha256.New() | |
if _, err := io.Copy(hash, file); err != nil { | |
return "", err | |
} | |
return fmt.Sprintf("%x", hash.Sum(nil)), nil | |
} | |
func copyFile(sourcePath string, targetPath string) error { | |
sourceFile, err := os.Open(sourcePath) | |
if err != nil { | |
return err | |
} | |
defer sourceFile.Close() | |
targetFile, err := os.Create(targetPath) | |
if err != nil { | |
return err | |
} | |
defer targetFile.Close() | |
_, err = io.Copy(targetFile, sourceFile) | |
if err != nil { | |
return err | |
} | |
err = targetFile.Sync() | |
if err != nil { | |
// Retry the sync operation a few times | |
for i := 0; i < 3; i++ { | |
err = targetFile.Sync() | |
if err == nil { | |
break | |
} | |
fmt.Println("Sync failed, retrying:", err) | |
} | |
if err != nil { | |
return err | |
} | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment