diff --git a/cmd/pkgserver/api.go b/cmd/pkgserver/api.go index 1c22a27..8c4ebbb 100644 --- a/cmd/pkgserver/api.go +++ b/cmd/pkgserver/api.go @@ -10,15 +10,29 @@ import ( "strconv" "strings" + "hakurei.app/internal/info" "hakurei.app/internal/rosa" ) -func serveCount(index *PackageIndex) func(http.ResponseWriter, *http.Request) { +type InfoPayload struct { + Count int `json:"count"` + HakureiVersion string `json:"hakurei_version"` +} + +func NewInfoPayload(index *PackageIndex) InfoPayload { + count := len(index.sorts[0]) + return InfoPayload{ + Count: count, + HakureiVersion: info.Version(), + } +} + +func serveInfo(index *PackageIndex) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - count := len(index.names) - w.Write([]byte(strconv.Itoa(count))) + w.Header().Set("Content-Type", "text/json; charset=utf-8") + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + WritePayload(w, NewInfoPayload(index)) } } @@ -91,22 +105,26 @@ func serveGet(index *PackageIndex) func(http.ResponseWriter, *http.Request) { return } values := index.sorts[sort][i:min(i+limit, len(index.sorts[sort]))] - payload := NewGetPayload(values) - w.Header().Set("Content-Type", "application/json; charset=utf-8") - w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") - w.WriteHeader(http.StatusOK) - b, err := json.Marshal(payload) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - _, err = bytes.NewBuffer(b).WriteTo(w) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } + WritePayload(w, NewGetPayload(values)) } } + +const ApiVersion = "v1" + func apiRoutes(index *PackageIndex) { - http.HandleFunc("GET /api/count", serveCount(index)) - http.HandleFunc("GET /api/get", serveGet(index)) - http.HandleFunc("GET /api/status/", serveStatus(index)) + http.HandleFunc(fmt.Sprintf("GET /api/%s/info", ApiVersion), serveInfo(index)) + http.HandleFunc(fmt.Sprintf("GET /api/%s/get", ApiVersion), serveGet(index)) + http.HandleFunc(fmt.Sprintf("GET /api/%s/status/", ApiVersion), serveStatus(index)) +} + +func WritePayload(w http.ResponseWriter, payload any) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Expires", "0") + w.WriteHeader(http.StatusOK) + err := json.NewEncoder(w).Encode(payload) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } } diff --git a/cmd/pkgserver/index.go b/cmd/pkgserver/index.go index 37c1b05..29ba371 100644 --- a/cmd/pkgserver/index.go +++ b/cmd/pkgserver/index.go @@ -51,7 +51,7 @@ func createPackageIndex(cache *pkg.Cache, report *rosa.Report) (_ *PackageIndex, statusUrl = "" } else { status = st - statusUrl = fmt.Sprintf("/api/status/%s.log", m.Name) + statusUrl = fmt.Sprintf("/api/%s/status/%s.log", ApiVersion, m.Name) } entry := PackageIndexEntry{ Name: m.Name, diff --git a/internal/azalea/azalea.bnf b/internal/azalea/azalea.bnf deleted file mode 100644 index e69de29..0000000 diff --git a/internal/azalea/azalea.go b/internal/azalea/azalea.go deleted file mode 100644 index ecf6b7e..0000000 --- a/internal/azalea/azalea.go +++ /dev/null @@ -1,69 +0,0 @@ -//go:generate gocc -a azalea.bnf -package azalea - -import ( - "io" - "io/fs" - "os" - "path/filepath" - "strconv" - "strings" - - "hakurei.app/container/check" -) - -type Parser struct { - Generator -} - -func NewParser(gen Generator) *Parser { - return &Parser{ - Generator: gen, - } -} -func (p Parser) Initialise() { - -} - -func (p Parser) Consume(ns string, file io.Reader) error { - return nil -} - -// ConsumeDir walks a directory and consumes all Azalea source files within it and all its subdirectories, as long as they end with the .az extension. -func (p Parser) ConsumeDir(dir *check.Absolute) error { - ds := dir.String() - return filepath.WalkDir(ds, func(path string, d fs.DirEntry, err error) (e error) { - if err != nil { - return err - } - if d.IsDir() || !strings.HasSuffix(d.Name(), ".az") { - return - } - rel, e := filepath.Rel(ds, path) - ns := strings.TrimSuffix(rel, ".az") - f, e := os.Open(path) - return p.Consume(ns, f) - }) -} - -// ConsumeAll consumes all provided readers as Azalea source code, each given the namespace `r%d` where `%d` is the index of the reader in the provided arguments. -func (p Parser) ConsumeAll(in ...io.Reader) error { - for i, r := range in { - err := p.Consume("r"+strconv.FormatInt(int64(i), 10), r) - if err != nil { - return err - } - } - return nil -} - -// ConsumeStrings consumes all provided strings as Azalea source code, each given the namespace `s%d` where `%d` is the index of the string in the provided arugments. -func (p Parser) ConsumeStrings(in ...string) error { - for i, s := range in { - err := p.Consume("s"+strconv.FormatInt(int64(i), 10), strings.NewReader(s)) - if err != nil { - return err - } - } - return nil -} diff --git a/internal/azalea/generator.go b/internal/azalea/generator.go deleted file mode 100644 index ebf0cc7..0000000 --- a/internal/azalea/generator.go +++ /dev/null @@ -1,36 +0,0 @@ -package azalea - -import ( - "io" -) - -type Generator interface { - Finalise() (error, io.Writer) -} - -type JsonGenerator struct { - t any -} - -func NewJsonGenerator[T any]() JsonGenerator { - t := new(T) - - return JsonGenerator{ - t, - } -} - -func (j *JsonGenerator) Finalise() (error, io.Writer) { - -} - -type PkgIRGenerator struct { -} - -func NewPkgIRGenerator() PkgIRGenerator { - return PkgIRGenerator{} -} - -func (p *PkgIRGenerator) Finalise() (error, io.Writer) { - -}