Skip to content

Instantly share code, notes, and snippets.

@mzaini30
Created June 11, 2025 12:51
Show Gist options
  • Save mzaini30/9ba080bcb7a98ff94fc9650806233e0b to your computer and use it in GitHub Desktop.
Save mzaini30/9ba080bcb7a98ff94fc9650806233e0b to your computer and use it in GitHub Desktop.
Source code untuk aplikasi backup folder ke flashdisk
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