sync file generator

This commit is contained in:
eyedeekay
2025-05-09 22:15:44 -04:00
parent beda655c5c
commit 50200abc0c
8 changed files with 330 additions and 7 deletions

108
pkg/config/config.go Normal file
View File

@ -0,0 +1,108 @@
// Package config handles the configuration settings for the GitHub mirror sync tool.
package config
import (
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
)
// Config holds the application configuration.
type Config struct {
// GitHub token for authentication
GithubToken string
// Repository URLs
PrimaryRepo string
MirrorRepo string
// Branch names
PrimaryBranch string
MirrorBranch string
// Synchronization settings
SyncInterval string
ForceSync bool
// Output configuration
OutputFile string
SetupWorkflow bool
Verbose bool
}
var (
config Config
// Flags
primaryRepo string
mirrorRepo string
primaryBranch string
mirrorBranch string
syncInterval string
forceSync bool
outputFile string
setupWorkflow bool
verbose bool
)
// AddFlags adds the configuration flags to the given command.
func AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&primaryRepo, "primary", "p", "", "Primary repository URL (required)")
cmd.Flags().StringVarP(&mirrorRepo, "mirror", "m", "", "GitHub mirror repository URL (required)")
cmd.Flags().StringVar(&primaryBranch, "primary-branch", "main", "Primary repository branch name")
cmd.Flags().StringVar(&mirrorBranch, "mirror-branch", "main", "GitHub mirror repository branch name")
cmd.Flags().StringVarP(&syncInterval, "interval", "i", "hourly", "Sync interval (hourly, daily, weekly)")
cmd.Flags().BoolVar(&forceSync, "force", true, "Force sync by overwriting mirror with primary content")
cmd.Flags().StringVarP(&outputFile, "output", "o", "", "Output file for workflow YAML (writes to stdout if not specified)")
cmd.Flags().BoolVar(&setupWorkflow, "setup", false, "Automatically setup the workflow in the GitHub repository")
cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging")
cmd.MarkFlagRequired("primary")
cmd.MarkFlagRequired("mirror")
}
// Load parses the flags and environment variables to build the configuration.
func Load() (*Config, error) {
// Get GitHub token from environment
githubToken := os.Getenv("GH_TOKEN")
if githubToken == "" {
githubToken = os.Getenv("GITHUB_TOKEN")
}
if githubToken == "" && setupWorkflow {
return nil, fmt.Errorf("GitHub token not found in environment (GH_TOKEN or GITHUB_TOKEN) but required for --setup")
}
// Validate repositories
if primaryRepo == "" {
return nil, fmt.Errorf("primary repository URL is required")
}
if mirrorRepo == "" {
return nil, fmt.Errorf("mirror repository URL is required")
}
// Validate sync interval
switch strings.ToLower(syncInterval) {
case "hourly", "daily", "weekly":
// valid
default:
return nil, fmt.Errorf("invalid sync interval: %s (must be hourly, daily, or weekly)", syncInterval)
}
// Set the values in the config struct
config = Config{
GithubToken: githubToken,
PrimaryRepo: primaryRepo,
MirrorRepo: mirrorRepo,
PrimaryBranch: primaryBranch,
MirrorBranch: mirrorBranch,
SyncInterval: syncInterval,
ForceSync: forceSync,
OutputFile: outputFile,
SetupWorkflow: setupWorkflow,
Verbose: verbose,
}
return &config, nil
}

View File

@ -9,8 +9,8 @@ import (
"strings"
"time"
"github.com/go-i2p/go-gh-mirror/pkg/config"
"github.com/go-i2p/go-gh-mirror/pkg/logger"
"github.com/go-i2p/go-github-sync/pkg/config"
"github.com/go-i2p/go-github-sync/pkg/logger"
)
// Client provides Git repository validation and operations.

View File

@ -11,8 +11,8 @@ import (
"github.com/google/go-github/v61/github"
"golang.org/x/oauth2"
"github.com/go-i2p/go-gh-mirror/pkg/config"
"github.com/go-i2p/go-gh-mirror/pkg/logger"
"github.com/go-i2p/go-github-sync/pkg/config"
"github.com/go-i2p/go-github-sync/pkg/logger"
)
const (

View File

@ -0,0 +1,49 @@
// Package logger provides structured logging functionality.
package logger
import (
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Logger wraps zap.Logger to provide a simpler interface.
type Logger struct {
*zap.SugaredLogger
}
// New creates a new Logger instance.
func New(debug bool) *Logger {
level := zapcore.InfoLevel
if debug {
level = zapcore.DebugLevel
}
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig),
zapcore.Lock(os.Stdout),
level,
)
return &Logger{zap.New(core).Sugar()}
}
// With adds structured context to the logger.
func (l *Logger) With(args ...interface{}) *Logger {
return &Logger{l.SugaredLogger.With(args...)}
}

View File

@ -8,8 +8,8 @@ import (
"gopkg.in/yaml.v3"
"github.com/go-i2p/go-gh-mirror/pkg/config"
"github.com/go-i2p/go-gh-mirror/pkg/logger"
"github.com/go-i2p/go-github-sync/pkg/config"
"github.com/go-i2p/go-github-sync/pkg/logger"
)
// Generator generates GitHub Actions workflow files.
@ -187,7 +187,7 @@ git push origin {{.MirrorBranch}}`
// addComments adds explanatory comments to the YAML.
func addComments(yaml string) string {
header := `# GitHub Actions workflow file to sync an external repository to this GitHub mirror.
# This file was automatically generated by go-gh-mirror.
# This file was automatically generated by go-github-sync.
#
# The workflow does the following:
# - Runs on a scheduled basis (and can also be triggered manually)