Files
downloadhub/cmd/cli/commands/link/link.go

197 lines
4.1 KiB
Go

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
}