Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions internal/pkg/project/ignore/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,13 @@ func newTestRegistry(t *testing.T) *registry.Registry {
}
assert.NoError(t, r.Set(row2))

// Notification 1 (under config 345, component keboola.foo)
notification1Key := model.NotificationKey{BranchID: 123, ComponentID: "keboola.foo", ConfigID: `345`, ID: `sub-001`}
notification1 := &model.NotificationState{
NotificationManifest: &model.NotificationManifest{NotificationKey: notification1Key},
Local: &model.Notification{NotificationKey: notification1Key},
}
assert.NoError(t, r.Set(notification1))

return r
}
18 changes: 13 additions & 5 deletions internal/pkg/project/ignore/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/keboola/keboola-as-code/internal/pkg/utils/errors"
)

func (f *File) IgnoreConfigsOrRows() error {
func (f *File) IgnoreObjects() error {
return f.applyIgnoredPatterns()
}

Expand Down Expand Up @@ -44,13 +44,21 @@ func (f *File) applyIgnorePattern(ignoreConfig string) error {
}

parts := strings.Split(ignoreConfig, "/")
switch len(parts) {
case 2:
switch {
case len(parts) == 2:
// Ignore config by componentID/configID.
configID, componentID := parts[1], parts[0]
f.state.IgnoreConfig(configID, componentID)
case 3:
// Ignore specific config row.
case len(parts) == 3 && parts[2] == "notifications":
// Ignore all notifications for a config: componentID/configID/notifications.
componentID, configID := parts[0], parts[1]
f.state.IgnoreNotificationsForConfig(configID, componentID)
case len(parts) == 4 && parts[2] == "notifications":
// Ignore a specific notification: componentID/configID/notifications/notificationID.
componentID, configID, notificationID := parts[0], parts[1], parts[3]
f.state.IgnoreNotification(configID, componentID, notificationID)
case len(parts) == 3:
// Ignore specific config row: componentID/configID/rowID.
configID, rowID := parts[1], parts[2]
f.state.IgnoreConfigRow(configID, rowID)
default:
Expand Down
71 changes: 65 additions & 6 deletions internal/pkg/project/ignore/ignore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/keboola/keboola-as-code/internal/pkg/filesystem/aferofs"
)

func TestFile_IgnoreConfigsOrRows(t *testing.T) {
func TestFile_IgnoreObjects(t *testing.T) {
t.Parallel()

ctx := t.Context()
Expand All @@ -23,15 +23,53 @@ func TestFile_IgnoreConfigsOrRows(t *testing.T) {
file, err := LoadFile(ctx, fs, registry, "foo/bar1")
require.NoError(t, err)

require.NoError(t, file.IgnoreConfigsOrRows())
require.NoError(t, file.IgnoreObjects())

assert.Len(t, registry.IgnoredConfigRows(), 1)
assert.Len(t, registry.IgnoredConfigs(), 1)
assert.Equal(t, "34", registry.IgnoredConfigRows()[0].ID.String())
assert.Equal(t, "345", registry.IgnoredConfigs()[0].ID.String())
}

func TestFile_IgnoreConfigsOrRows_Branch(t *testing.T) {
func TestFile_IgnoreObjects_AllNotificationsForConfig(t *testing.T) {
t.Parallel()

ctx := t.Context()
r := newTestRegistry(t)
fs := aferofs.NewMemoryFs()

require.NoError(t, fs.WriteFile(ctx, filesystem.NewRawFile(`foo/bar1`, "keboola.foo/345/notifications")))

file, err := LoadFile(ctx, fs, r, "foo/bar1")
require.NoError(t, err)

require.NoError(t, file.IgnoreObjects())

ignored := r.IgnoredNotifications()
require.Len(t, ignored, 1)
assert.Equal(t, "sub-001", string(ignored[0].ID))
}

func TestFile_IgnoreObjects_SpecificNotification(t *testing.T) {
t.Parallel()

ctx := t.Context()
r := newTestRegistry(t)
fs := aferofs.NewMemoryFs()

require.NoError(t, fs.WriteFile(ctx, filesystem.NewRawFile(`foo/bar1`, "keboola.foo/345/notifications/sub-001")))

file, err := LoadFile(ctx, fs, r, "foo/bar1")
require.NoError(t, err)

require.NoError(t, file.IgnoreObjects())

ignored := r.IgnoredNotifications()
require.Len(t, ignored, 1)
assert.Equal(t, "sub-001", string(ignored[0].ID))
}

func TestFile_IgnoreObjects_Branch(t *testing.T) {
t.Parallel()

ctx := t.Context()
Expand All @@ -43,14 +81,14 @@ func TestFile_IgnoreConfigsOrRows_Branch(t *testing.T) {
file, err := LoadFile(ctx, fs, r, "foo/bar1")
require.NoError(t, err)

require.NoError(t, file.IgnoreConfigsOrRows())
require.NoError(t, file.IgnoreObjects())

ignored := r.IgnoredBranches()
require.Len(t, ignored, 1)
assert.Equal(t, "123", ignored[0].ID.String())
}

func TestFile_IgnoreConfigsOrRows_BranchWithSlashInName(t *testing.T) {
func TestFile_IgnoreObjects_BranchWithSlashInName(t *testing.T) {
t.Parallel()

ctx := t.Context()
Expand All @@ -62,7 +100,7 @@ func TestFile_IgnoreConfigsOrRows_BranchWithSlashInName(t *testing.T) {
file, err := LoadFile(ctx, fs, r, "foo/bar1")
require.NoError(t, err)

require.NoError(t, file.IgnoreConfigsOrRows())
require.NoError(t, file.IgnoreObjects())

// Branch "feature/foo" should be ignored, not misidentified as a config-row pattern.
ignored := r.IgnoredBranches()
Expand Down Expand Up @@ -109,6 +147,27 @@ func Test_applyIgnoredPatterns(t *testing.T) {
},
wantErr: assert.Error,
},
{
name: "notifications all pattern",
args: args{
pattern: "keboola.foo/345/notifications",
},
wantErr: assert.NoError,
},
{
name: "notifications specific pattern",
args: args{
pattern: "keboola.foo/345/notifications/sub-001",
},
wantErr: assert.NoError,
},
{
name: "notifications too long pattern",
args: args{
pattern: "keboola.foo/345/notifications/sub-001/extra",
},
wantErr: assert.Error,
},
{
name: "short pattern",
args: args{
Expand Down
36 changes: 36 additions & 0 deletions internal/pkg/state/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ func (s *Registry) NullIgnoredBranchStates() {
v.SetLocalState(nil)
v.SetRemoteState(nil)
}
case *model.NotificationState:
if _, ok := ignoredKeys[model.BranchKey{ID: v.BranchID}]; ok {
v.SetLocalState(nil)
v.SetRemoteState(nil)
}
}
}
}
Expand Down Expand Up @@ -293,6 +298,37 @@ func (s *Registry) Notifications() (notifications []*model.NotificationState) {
return notifications
}

func (s *Registry) IgnoreNotificationsForConfig(configID, componentID string) {
for _, obj := range s.All() {
if v, ok := obj.(*model.NotificationState); ok {
if v.ConfigID.String() == configID && v.ComponentID.String() == componentID {
v.Ignore = true
}
}
}
}

func (s *Registry) IgnoreNotification(configID, componentID, notificationID string) {
for _, obj := range s.All() {
if v, ok := obj.(*model.NotificationState); ok {
if v.ConfigID.String() == configID && v.ComponentID.String() == componentID && string(v.ID) == notificationID {
v.Ignore = true
}
}
}
}

func (s *Registry) IgnoredNotifications() (notifications []*model.NotificationState) {
for _, obj := range s.All() {
if v, ok := obj.(*model.NotificationState); ok {
if v.Ignore {
notifications = append(notifications, v)
}
}
}
return notifications
}

func (s *Registry) NotificationsFrom(config model.ConfigKey) (notifications []*model.NotificationState) {
for _, object := range s.All() {
if v, ok := object.(*model.NotificationState); ok {
Expand Down
67 changes: 67 additions & 0 deletions internal/pkg/state/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,73 @@ func TestNullIgnoredBranchStates(t *testing.T) {
assert.Empty(t, s.ConfigRows())
}

func TestNullIgnoredBranchStates_WithNotification(t *testing.T) {
t.Parallel()
s := newTestState(t, knownpaths.NewNop(t.Context()))

// Add a notification under branch 123 / config 345.
notifKey := NotificationKey{BranchID: 123, ComponentID: "keboola.foo", ConfigID: `345`, ID: `sub-001`}
notif := &NotificationState{
NotificationManifest: &NotificationManifest{NotificationKey: notifKey},
Local: &Notification{NotificationKey: notifKey},
}
require.NoError(t, s.Set(notif))

// 7 objects now.
assert.Len(t, s.All(), 7)

s.IgnoreBranch("Main")
s.NullIgnoredBranchStates()

// The notification under branch 123 must also be nulled.
assert.Len(t, s.All(), 1)
assert.Empty(t, s.Notifications())
}

func TestIgnoreNotificationsForConfig(t *testing.T) {
t.Parallel()
s := newTestState(t, knownpaths.NewNop(t.Context()))

notifKey := NotificationKey{BranchID: 123, ComponentID: "keboola.foo", ConfigID: `345`, ID: `sub-001`}
notif := &NotificationState{
NotificationManifest: &NotificationManifest{NotificationKey: notifKey},
Local: &Notification{NotificationKey: notifKey},
}
require.NoError(t, s.Set(notif))

assert.Empty(t, s.IgnoredNotifications())

s.IgnoreNotificationsForConfig("345", "keboola.foo")

ignored := s.IgnoredNotifications()
require.Len(t, ignored, 1)
assert.Equal(t, `sub-001`, string(ignored[0].ID))
}

func TestIgnoreNotification(t *testing.T) {
t.Parallel()
s := newTestState(t, knownpaths.NewNop(t.Context()))

notifKey := NotificationKey{BranchID: 123, ComponentID: "keboola.foo", ConfigID: `345`, ID: `sub-001`}
notif := &NotificationState{
NotificationManifest: &NotificationManifest{NotificationKey: notifKey},
Local: &Notification{NotificationKey: notifKey},
}
require.NoError(t, s.Set(notif))

assert.Empty(t, s.IgnoredNotifications())

// Wrong notification ID — should not match.
s.IgnoreNotification("345", "keboola.foo", "sub-999")
assert.Empty(t, s.IgnoredNotifications())

// Correct ID — should match.
s.IgnoreNotification("345", "keboola.foo", "sub-001")
ignored := s.IgnoredNotifications()
require.Len(t, ignored, 1)
assert.Equal(t, `sub-001`, string(ignored[0].ID))
}

func TestIgnoreBranch(t *testing.T) {
t.Parallel()
s := newTestState(t, knownpaths.NewNop(t.Context()))
Expand Down
10 changes: 7 additions & 3 deletions pkg/lib/operation/project/sync/pull/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ func Run(ctx context.Context, projectState *project.State, o Options, d dependen
return err
}

if err = file.IgnoreConfigsOrRows(); err != nil {
if err = file.IgnoreObjects(); err != nil {
return err
}

ignoreBranchesConfigsAndRows(projectState)
ignoreObjects(projectState)
}

// Diff
Expand Down Expand Up @@ -156,7 +156,7 @@ func Run(ctx context.Context, projectState *project.State, o Options, d dependen
return nil
}

func ignoreBranchesConfigsAndRows(projectState *project.State) {
func ignoreObjects(projectState *project.State) {
for _, v := range projectState.IgnoredConfigRows() {
v.SetRemoteState(nil)
}
Expand All @@ -165,6 +165,10 @@ func ignoreBranchesConfigsAndRows(projectState *project.State) {
v.SetRemoteState(nil)
}

for _, v := range projectState.IgnoredNotifications() {
v.SetRemoteState(nil)
}

// Null both states for ignored branches so they are invisible to the diff.
projectState.NullIgnoredBranchStates()
}
8 changes: 7 additions & 1 deletion pkg/lib/operation/project/sync/push/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,16 @@ func Run(ctx context.Context, projectState *project.State, o Options, d dependen
return err
}

if err = file.IgnoreConfigsOrRows(); err != nil {
if err = file.IgnoreObjects(); err != nil {
return err
}

// Null both states for directly-ignored notifications.
for _, v := range projectState.IgnoredNotifications() {
v.SetLocalState(nil)
v.SetRemoteState(nil)
}

// Make ignored branches invisible to the push diff.
projectState.NullIgnoredBranchStates()
}
Expand Down
Loading