mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-05 05:20:34 +00:00
[api/repos] Add copy API
This commit is contained in:
committed by
André Roth
parent
8114786179
commit
66429bff45
+136
-1
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
@@ -416,7 +417,141 @@ func apiReposPackageFromDir(c *gin.Context) {
|
||||
|
||||
// POST /repos/:name/copy/:src/:file
|
||||
func apiReposCopyPackage(c *gin.Context) {
|
||||
// TODO
|
||||
dstRepoName := c.Params.ByName("name")
|
||||
srcRepoName := c.Params.ByName("src")
|
||||
|
||||
jsonBody := struct {
|
||||
WithDeps bool `json:"with-deps,omitempty"`
|
||||
DryRun bool `json:"dry-run,omitempty"`
|
||||
}{
|
||||
WithDeps: false,
|
||||
DryRun: false,
|
||||
}
|
||||
|
||||
err := c.Bind(&jsonBody)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
collectionFactory := context.NewCollectionFactory()
|
||||
dstRepo, err := collectionFactory.LocalRepoCollection().ByName(dstRepoName)
|
||||
if err != nil {
|
||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("dest repo error: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
err = collectionFactory.LocalRepoCollection().LoadComplete(dstRepo)
|
||||
if err != nil {
|
||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("dest repo error: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
srcRefList *deb.PackageRefList
|
||||
srcRepo *deb.LocalRepo
|
||||
)
|
||||
|
||||
srcRepo, err = collectionFactory.LocalRepoCollection().ByName(srcRepoName)
|
||||
if err != nil {
|
||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("src repo error: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
if srcRepo.UUID == dstRepo.UUID {
|
||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("dest and source are identical"))
|
||||
return
|
||||
}
|
||||
|
||||
err = collectionFactory.LocalRepoCollection().LoadComplete(srcRepo)
|
||||
if err != nil {
|
||||
AbortWithJSONError(c, http.StatusBadRequest, fmt.Errorf("src repo error: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
srcRefList = srcRepo.RefList()
|
||||
taskName := fmt.Sprintf("Copy packages from repo %s to repo %s", srcRepoName, dstRepoName)
|
||||
resources := []string{string(dstRepo.Key()), string(srcRepo.Key())}
|
||||
|
||||
maybeRunTaskInBackground(c, taskName, resources, func(_ aptly.Progress, _ *task.Detail) (*task.ProcessReturnValue, error) {
|
||||
reporter := &aptly.RecordingResultReporter{
|
||||
Warnings: []string{},
|
||||
AddedLines: []string{},
|
||||
RemovedLines: []string{},
|
||||
}
|
||||
|
||||
dstList, err := deb.NewPackageListFromRefList(dstRepo.RefList(), collectionFactory.PackageCollection(), context.Progress())
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("unable to load packages in dest: %s", err)
|
||||
|
||||
}
|
||||
|
||||
srcList, err := deb.NewPackageListFromRefList(srcRefList, collectionFactory.PackageCollection(), context.Progress())
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("unable to load packages in src: %s", err)
|
||||
}
|
||||
|
||||
srcList.PrepareIndex()
|
||||
|
||||
var architecturesList []string
|
||||
|
||||
if jsonBody.WithDeps {
|
||||
dstList.PrepareIndex()
|
||||
|
||||
// Calculate architectures
|
||||
if len(context.ArchitecturesList()) > 0 {
|
||||
architecturesList = context.ArchitecturesList()
|
||||
} else {
|
||||
architecturesList = dstList.Architectures(false)
|
||||
}
|
||||
|
||||
sort.Strings(architecturesList)
|
||||
|
||||
if len(architecturesList) == 0 {
|
||||
return &task.ProcessReturnValue{Code: http.StatusUnprocessableEntity, Value: nil}, fmt.Errorf("unable to determine list of architectures, please specify explicitly")
|
||||
}
|
||||
}
|
||||
|
||||
// srcList.Filter|FilterWithProgress only accept query list
|
||||
queries := make([]deb.PackageQuery, 1)
|
||||
queries[0], err = query.Parse(c.Params.ByName("file"))
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusUnprocessableEntity, Value: nil}, fmt.Errorf("unable to parse query: %s", err)
|
||||
}
|
||||
|
||||
toProcess, err := srcList.FilterWithProgress(queries, jsonBody.WithDeps, dstList, context.DependencyOptions(), architecturesList, context.Progress())
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("filter error: %s", err)
|
||||
}
|
||||
|
||||
err = toProcess.ForEach(func(p *deb.Package) error {
|
||||
err = dstList.Add(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("added %s-%s(%s)", p.Name, p.Version, p.Architecture)
|
||||
reporter.AddedLines = append(reporter.AddedLines, name)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("error processing dest add: %s", err)
|
||||
}
|
||||
|
||||
if jsonBody.DryRun {
|
||||
reporter.Warning("Changes not saved, as dry run has been requested")
|
||||
} else {
|
||||
dstRepo.UpdateRefList(deb.NewPackageRefListFromPackageList(dstList))
|
||||
|
||||
err = collectionFactory.LocalRepoCollection().Update(dstRepo)
|
||||
if err != nil {
|
||||
return &task.ProcessReturnValue{Code: http.StatusInternalServerError, Value: nil}, fmt.Errorf("unable to save: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &task.ProcessReturnValue{Code: http.StatusOK, Value: gin.H{
|
||||
"Report": reporter,
|
||||
}}, nil
|
||||
})
|
||||
}
|
||||
|
||||
// POST /repos/:name/include/:dir/:file
|
||||
|
||||
Reference in New Issue
Block a user