package main import ( "os" "path/filepath" "sort" "strings" ) type Project struct { Name string Path string Description string HasReadme bool } // ListProjects returns a sorted list of projects from the given directory. // Only directories are considered projects. Hidden directories (starting with .) // are excluded. func ListProjects(projectsPath string) ([]Project, error) { entries, err := os.ReadDir(projectsPath) if err != nil { return nil, err } var projects []Project for _, e := range entries { if !e.IsDir() { continue } name := e.Name() if strings.HasPrefix(name, ".") { continue } p := Project{ Name: name, Path: filepath.Join(projectsPath, name), } // Try to read description from README.md first line readmePath := filepath.Join(p.Path, "README.md") if data, err := os.ReadFile(readmePath); err == nil { p.HasReadme = true lines := strings.SplitN(string(data), "\n", 3) for _, line := range lines { line = strings.TrimSpace(line) line = strings.TrimLeft(line, "# ") if line != "" { p.Description = line break } } } projects = append(projects, p) } sort.Slice(projects, func(i, j int) bool { return projects[i].Name < projects[j].Name }) return projects, nil }