package link import ( "context" "downloadhub/pkg/data" "flag" "fmt" "os" "strings" "github.com/google/subcommands" ) type ( LinkCmd struct { os string arch string out string } ) func (*LinkCmd) Name() string { return "link" } func (*LinkCmd) Synopsis() string { return "add/edit/remove a download link" } func (*LinkCmd) Usage() string { return `Usage: ./cli link ACTION LINK SLUG Actions: add, edit, rm Options: ` } func (p *LinkCmd) SetFlags(f *flag.FlagSet) { f.StringVar(&p.os, "os", "", "set the operating system") f.StringVar(&p.arch, "architecture", "", "set the instruction set") f.StringVar(&p.out, "out", "./config.json", "path to the configuration file") } func (p *LinkCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { if f.NArg() != 3 { fmt.Fprintln(os.Stderr, "error: bad usage") return subcommands.ExitUsageError } switch strings.ToLower(f.Arg(0)) { case "add": return p.add(f.Arg(1), f.Arg(2)) case "edit": return p.edit(f.Arg(1), f.Arg(2)) case "rm": return p.rm(f.Arg(1), f.Arg(2)) default: { fmt.Fprintln(os.Stderr, "error: unknown command") return subcommands.ExitUsageError } } } func (p *LinkCmd) add(link, slug string) subcommands.ExitStatus { d, err := data.Load(p.out) if err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } var found bool for i, soft := range d.Softwares { if soft.Slug == slug { if exists(link, soft) { fmt.Fprintln(os.Stderr, "error: link already exists") return subcommands.ExitFailure } soft.DownloadLinks = append(soft.DownloadLinks, data.DownloadLink{ OS: p.os, Arch: p.arch, URL: link, }) d.Softwares[i] = soft found = true break } } if !found { fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug) return subcommands.ExitFailure } if err := data.Save(d, p.out); err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } return subcommands.ExitSuccess } func (p *LinkCmd) edit(link, slug string) subcommands.ExitStatus { d, err := data.Load(p.out) if err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } var foundSlug, foundLink bool for i, soft := range d.Softwares { if soft.Slug == slug { for y, l := range soft.DownloadLinks { if l.URL == link { if len(p.os) > 0 { l.OS = p.os } if len(p.os) > 0 { l.Arch = p.arch } soft.DownloadLinks[y] = l foundLink = true break } } d.Softwares[i] = soft foundSlug = true break } } if !foundSlug { fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug) return subcommands.ExitFailure } if !foundLink { fmt.Fprintf(os.Stderr, "error: link '%s' cannot be found\n", link) return subcommands.ExitFailure } if err := data.Save(d, p.out); err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } return subcommands.ExitSuccess } func (p *LinkCmd) rm(link, slug string) subcommands.ExitStatus { d, err := data.Load(p.out) if err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } var foundSlug, foundLink bool for i, soft := range d.Softwares { if soft.Slug == slug { var index int for y, l := range soft.DownloadLinks { if l.URL == link { index = y foundLink = true break } } if foundLink { soft.DownloadLinks = append(soft.DownloadLinks[:index], soft.DownloadLinks[index+1:]...) } d.Softwares[i] = soft foundSlug = true break } } if !foundSlug { fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug) return subcommands.ExitFailure } if !foundLink { fmt.Fprintf(os.Stderr, "error: link '%s' cannot be found\n", link) return subcommands.ExitFailure } if err := data.Save(d, p.out); err != nil { fmt.Fprintln(os.Stderr, "error:", err) return subcommands.ExitFailure } return subcommands.ExitSuccess } func exists(link string, soft data.Software) bool { for _, l := range soft.DownloadLinks { if l.URL == link { return true } } return false }