| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // Copyright 2022 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package conan
-
- import (
- "errors"
- "net/http"
- "strings"
-
- conan_model "code.gitea.io/gitea/models/packages/conan"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- conan_module "code.gitea.io/gitea/modules/packages/conan"
- "code.gitea.io/gitea/services/context"
- )
-
- // SearchResult contains the found recipe names
- type SearchResult struct {
- Results []string `json:"results"`
- }
-
- // SearchRecipes searches all recipes matching the query
- func SearchRecipes(ctx *context.Context) {
- q := ctx.FormTrim("q")
-
- opts := parseQuery(ctx.Package.Owner, q)
-
- results, err := conan_model.SearchRecipes(ctx, opts)
- if err != nil {
- apiError(ctx, http.StatusInternalServerError, err)
- return
- }
-
- jsonResponse(ctx, http.StatusOK, &SearchResult{
- Results: results,
- })
- }
-
- // parseQuery creates search options for the given query
- func parseQuery(owner *user_model.User, query string) *conan_model.RecipeSearchOptions {
- opts := &conan_model.RecipeSearchOptions{
- OwnerID: owner.ID,
- }
-
- if query != "" {
- parts := strings.Split(strings.ReplaceAll(query, "@", "/"), "/")
-
- opts.Name = parts[0]
- if len(parts) > 1 && parts[1] != "*" {
- opts.Version = parts[1]
- }
- if len(parts) > 2 && parts[2] != "*" {
- opts.User = parts[2]
- }
- if len(parts) > 3 && parts[3] != "*" {
- opts.Channel = parts[3]
- }
- }
-
- return opts
- }
-
- // SearchPackagesV1 searches all packages of a recipe (Conan v1 endpoint)
- func SearchPackagesV1(ctx *context.Context) {
- searchPackages(ctx, true)
- }
-
- // SearchPackagesV2 searches all packages of a recipe (Conan v2 endpoint)
- func SearchPackagesV2(ctx *context.Context) {
- searchPackages(ctx, false)
- }
-
- func searchPackages(ctx *context.Context, searchAllRevisions bool) {
- rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
-
- if !searchAllRevisions && rref.Revision == "" {
- lastRevision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
- if err != nil {
- if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
- apiError(ctx, http.StatusNotFound, err)
- } else {
- apiError(ctx, http.StatusInternalServerError, err)
- }
- return
- }
- rref = rref.WithRevision(lastRevision.Value)
- } else {
- has, err := conan_model.RecipeExists(ctx, ctx.Package.Owner.ID, rref)
- if err != nil {
- if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
- apiError(ctx, http.StatusNotFound, err)
- } else {
- apiError(ctx, http.StatusInternalServerError, err)
- }
- return
- }
- if !has {
- apiError(ctx, http.StatusNotFound, nil)
- return
- }
- }
-
- recipeRevisions := []*conan_model.PropertyValue{{Value: rref.Revision}}
- if searchAllRevisions {
- var err error
- recipeRevisions, err = conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref)
- if err != nil {
- apiError(ctx, http.StatusInternalServerError, err)
- return
- }
- }
-
- result := make(map[string]*conan_module.Conaninfo)
-
- for _, recipeRevision := range recipeRevisions {
- currentRef := rref
- if recipeRevision.Value != "" {
- currentRef = rref.WithRevision(recipeRevision.Value)
- }
- packageReferences, err := conan_model.GetPackageReferences(ctx, ctx.Package.Owner.ID, currentRef)
- if err != nil {
- if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
- apiError(ctx, http.StatusNotFound, err)
- } else {
- apiError(ctx, http.StatusInternalServerError, err)
- }
- return
- }
- for _, packageReference := range packageReferences {
- if _, ok := result[packageReference.Value]; ok {
- continue
- }
- pref, _ := conan_module.NewPackageReference(currentRef, packageReference.Value, "")
- lastPackageRevision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref)
- if err != nil {
- if errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
- apiError(ctx, http.StatusNotFound, err)
- } else {
- apiError(ctx, http.StatusInternalServerError, err)
- }
- return
- }
- pref = pref.WithRevision(lastPackageRevision.Value)
- infoRaw, err := conan_model.GetPackageInfo(ctx, ctx.Package.Owner.ID, pref)
- if err != nil {
- if errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
- apiError(ctx, http.StatusNotFound, err)
- } else {
- apiError(ctx, http.StatusInternalServerError, err)
- }
- return
- }
- var info *conan_module.Conaninfo
- if err := json.Unmarshal([]byte(infoRaw), &info); err != nil {
- apiError(ctx, http.StatusInternalServerError, err)
- return
- }
- result[pref.Reference] = info
- }
- }
-
- jsonResponse(ctx, http.StatusOK, result)
- }
|