package domain import ( "flag" "os" "strings" "github.com/joho/godotenv" "redmine_tree/domain/model" // Importing the model package ) func Run() { ui := NewUI() // Instantiate UI // Parse flags includeStatusFlag := flag.String("status", "", "Filter issues by status (comma-separated names or IDs)") excludeStatusFlag := flag.String("exclude-status", "", "Exclude issues by status (comma-separated names or IDs)") flag.Usage = func() { ui.PrintUsage(os.Args[0]) } flag.Parse() // Load .env file err := godotenv.Load() if err != nil && !os.IsNotExist(err) { ui.PrintError("Error loading .env file: %v\n", err) } // Load config from ~/.redmine-tree.json config, err := LoadConfig() if err != nil { ui.PrintError("Error loading config file: %v\n", err) } baseURL := "" apiKey := "" // Try to get values from config file first var includeStatuses []string var excludeStatuses []string if config != nil { baseURL = config.Host apiKey = config.Token includeStatuses = config.IncludeStatuses excludeStatuses = config.ExcludeStatuses } // Flag overrides config file if *includeStatusFlag != "" { includeStatuses = strings.Split(*includeStatusFlag, ",") } if *excludeStatusFlag != "" { excludeStatuses = strings.Split(*excludeStatusFlag, ",") } // Environment variables override config file if envBaseURL := os.Getenv("REDMINE_URL"); envBaseURL != "" { baseURL = envBaseURL } if envAPIKey := os.Getenv("REDMINE_TOKEN"); envAPIKey != "" { apiKey = envAPIKey } var projectID string // projectID must be provided as a command-line argument, or list projects if flag.NArg() > 0 { projectID = flag.Arg(0) // Check for misplaced flags for i := 1; i < flag.NArg(); i++ { if strings.HasPrefix(flag.Arg(i), "-") { ui.PrintError("Error: flags must come BEFORE the project ID. Found misplaced flag: %s\n", flag.Arg(i)) } } } else { projects, err := model.FetchAllProjects(baseURL, apiKey) if err != nil { ui.PrintError("Error fetching projects: %v\n", err) } ui.PrintProjects(projects) os.Exit(0) } if baseURL == "" || apiKey == "" { ui.PrintUsage(os.Args[0]) // Pass app name for usage message } project, err := model.FetchProject(baseURL, apiKey, projectID) if err != nil { ui.PrintError("Error fetching project details: %v\n", err) } ui.PrintFetchingProjectDetails(project.Name, projectID) issues, err := model.FetchAllIssues(baseURL, apiKey, projectID) if err != nil { ui.PrintError("Error fetching issues: %v\n", err) } // Apply filtering filteredIssues := model.FilterIssues(issues, includeStatuses, excludeStatuses) ui.PrintTotalIssuesFetched(len(filteredIssues)) roots := model.BuildTree(filteredIssues) // Corrected call ui.PrintIssueTreeHeader(len(roots)) model.PrintTree(roots, "", false) // Corrected call // Print summary ui.PrintSummary(len(filteredIssues), len(roots)) }