From a2ec978608defc7714bbf786a02c017d317d1401 Mon Sep 17 00:00:00 2001 From: Martin Sehnoutka Date: Tue, 24 Sep 2019 16:22:54 +0200 Subject: [PATCH 1/2] minimal travis configuration --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..cb3dd73576 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: go +go: +- 1.12.x +env: +- GO111MODULE=on # needed even for Go 1.12 +script: +- go test -v ./... From 1c7857f02662fe54ba06659e445ea1823a05b296 Mon Sep 17 00:00:00 2001 From: Jacob Kozol Date: Tue, 24 Sep 2019 19:44:21 +0200 Subject: [PATCH 2/2] Add blueprint workspace diff The list of changes between the committed blueprint and its workspace are returned when a user requests the diff. Each change includes the new(added) or the old(removed) package. --- internal/weldr/api.go | 69 +++++++++++++++++++++++++++++++++++--- internal/weldr/api_test.go | 3 ++ internal/weldr/store.go | 21 ++++++++++++ 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/internal/weldr/api.go b/internal/weldr/api.go index 472c38ffbc..188bbcd27b 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -453,13 +453,72 @@ func (api *API) blueprintsDepsolveHandler(writer http.ResponseWriter, request *h }) } -func (api *API) blueprintsDiffHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) { - var reply struct { - Diff []interface{} `json:"diff"` +func (api *API) blueprintsDiffHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { + type pack struct { + Package blueprintPackage `json:"Package"` } - reply.Diff = make([]interface{}, 0) - json.NewEncoder(writer).Encode(reply) + type diff struct { + New *pack `json:"new"` + Old *pack `json:"old"` + } + + type reply struct { + Diffs []diff `json:"diff"` + } + + name := params.ByName("blueprint") + if len(name) == 0 { + statusResponseError(writer, http.StatusNotFound, "no blueprint name given") + return + } + fromCommit := params.ByName("from") + if len(fromCommit) == 0 || fromCommit != "NEWEST" { + statusResponseError(writer, http.StatusNotFound, "invalid from commit ID given") + return + } + toCommit := params.ByName("to") + if len(toCommit) == 0 || toCommit != "WORKSPACE" { + statusResponseError(writer, http.StatusNotFound, "invalid to commit ID given") + return + } + + // Fetch old and new blueprint details from store and return error if not found + var oldBlueprint, newBlueprint blueprint + if !api.store.getBlueprintCommitted(name, &oldBlueprint) || !api.store.getBlueprint(name, &newBlueprint, nil) { + statusResponseError(writer, http.StatusNotFound) + return + } + + newSlice := newBlueprint.Packages + oldMap := make(map[string]blueprintPackage) + diffs := []diff{} + + for _, oldPackage := range oldBlueprint.Packages { + oldMap[oldPackage.Name] = oldPackage + } + + // For each package in new blueprint check if the old one contains it + for _, newPackage := range newSlice { + oldPackage, found := oldMap[newPackage.Name] + // If found remove from old packages map but otherwise create a diff with the added package + if found { + delete(oldMap, oldPackage.Name) + // Create a diff if the versions changed + if oldPackage.Version != newPackage.Version { + diffs = append(diffs, diff{Old: &pack{oldPackage}, New: &pack{newPackage}}) + } + } else { + diffs = append(diffs, diff{Old: nil, New: &pack{newPackage}}) + } + } + + // All packages remaining in the old packages map have been removed in the new blueprint so create a diff + for _, oldPackage := range oldMap { + diffs = append(diffs, diff{Old: &pack{oldPackage}, New: nil}) + } + + json.NewEncoder(writer).Encode(reply{diffs}) } func (api *API) blueprintsNewHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) { diff --git a/internal/weldr/api_test.go b/internal/weldr/api_test.go index 571c8666a5..858892c8a5 100644 --- a/internal/weldr/api_test.go +++ b/internal/weldr/api_test.go @@ -134,4 +134,7 @@ func TestBlueprints(t *testing.T) { testRoute(t, api, "GET", "/api/v0/blueprints/info/test", ``, http.StatusOK, `{"blueprints":[{"name":"test","description":"Test","modules":[],"packages":[{"name":"systemd","version":"123"}],"version":"0"}], "changes":[{"name":"test","changed":true}], "errors":[]}`) + + testRoute(t, api, "GET", "/api/v0/blueprints/diff/test/NEWEST/WORKSPACE", ``, + http.StatusOK, `{"diff":[{"new":{"Package":{"name":"systemd","version":"123"}},"old":null},{"new":null,"old":{"Package":{"name":"httpd","version":"2.4.*"}}}]}`) } diff --git a/internal/weldr/store.go b/internal/weldr/store.go index 9774d98f02..be0a1e0c81 100644 --- a/internal/weldr/store.go +++ b/internal/weldr/store.go @@ -108,6 +108,27 @@ func (s *store) getBlueprint(name string, bp *blueprint, changed *bool) bool { return true } +func (s *store) getBlueprintCommitted(name string, bp *blueprint) bool { + s.mu.RLock() + defer s.mu.RUnlock() + + var ok bool + *bp, ok = s.Blueprints[name] + if !ok { + return false + } + + // cockpit-composer cannot deal with missing "packages" or "modules" + if bp.Packages == nil { + bp.Packages = []blueprintPackage{} + } + if bp.Modules == nil { + bp.Modules = []blueprintPackage{} + } + + return true +} + func (s *store) pushBlueprint(bp blueprint) { s.change(func() { delete(s.Workspace, bp.Name)