Repository: ariga/atlas
Pull request #2356 (2023-12-09 11:01:47)

sql/schema: support excluding enum objects
Closed https://github.com/ariga/atlas/discussions/2352


Patch:
diff --git a/doc/md/declarative/inspect.mdx b/doc/md/declarative/inspect.mdx
index ef89a2eb..3ac29ec9 100644
--- a/doc/md/declarative/inspect.mdx
+++ b/doc/md/declarative/inspect.mdx
@@ -186,7 +186,7 @@ atlas schema inspect -u "mysql://localhost" --exclude "*.prefix_*"
 
 atlas schema inspect -u "mysql://localhost" --exclude "schema.table"
 
-atlas schema inspect -u "mysql://localhost" --exclude "schema.t*[type=table]"
+atlas schema inspect -u "mysql://localhost" --exclude "schema.t*[type=table]" --exclude "schema.e*[type=enum]"
 ```
 
 </TabItem>
@@ -199,7 +199,7 @@ atlas schema inspect -u "mysql://localhost" --exclude "prefix_*"
 
 atlas schema inspect -u "mysql://localhost" --exclude "table"
 
-atlas schema inspect -u "mysql://localhost" --exclude "t*[type=table]"
+atlas schema inspect -u "mysql://localhost" --exclude "t*[type=table]" --exclude "e*[type=enum]"
 ```
 
 </TabItem>
diff --git a/sql/schema/exclude.go b/sql/schema/exclude.go
index 5d7b48cc..e9b8844e 100644
--- a/sql/schema/exclude.go
+++ b/sql/schema/exclude.go
@@ -34,7 +34,7 @@ Filter:
 			}
 			if match {
 				// In case there is a match, and it is
-				// a single glob we exclude this 
+				// a single glob we exclude this
 				if len(g) == 1 {
 					continue Filter
 				}
@@ -88,6 +88,25 @@ func split(patterns []string) ([][]string, error) {
 }
 
 func excludeS(s *Schema, glob []string) error {
+	if globE, exclude := excludeType(typeE, glob[0]); exclude {
+		var objects []Object
+		for _, t := range s.Objects {
+			e, ok := t.(*EnumType)
+			if !ok {
+				objects = append(objects, t)
+				continue
+			}
+			match, err := filepath.Match(globE, e.T)
+			if err != nil {
+				return err
+			}
+			// No match or glob has more than one pattern.
+			if !match || len(glob) != 1 {
+				objects = append(objects, t)
+			}
+		}
+		s.Objects = objects
+	}
 	if globT, exclude := excludeType(typeT, glob[0]); exclude {
 		var tables []*Table
 		for _, t := range s.Tables {
@@ -214,6 +233,7 @@ func excludeV(t *View, pattern string) (err error) {
 }
 
 const (
+	typeE  = "enum"
 	typeV  = "view"
 	typeT  = "table"
 	typeC  = "column"


Test patch:
diff --git a/sql/schema/exclude_test.go b/sql/schema/exclude_test.go
index 34ce92f5..cae7a2df 100644
--- a/sql/schema/exclude_test.go
+++ b/sql/schema/exclude_test.go
@@ -92,6 +92,69 @@ func TestExcludeRealm_Tables(t *testing.T) {
 	require.Empty(t, r.Schemas[2].Tables)
 }
 
+func TestExcludeRealm_Enums(t *testing.T) {
+	e1, e2, e3 := &EnumType{T: "e1"}, &EnumType{T: "e2"}, &EnumType{T: "e3"}
+	s1, s2, s3 := New("s1").AddObjects(e1), New("s2").AddObjects(e1, e2), New("s3").AddObjects(e1, e2, e3)
+
+	r, err := ExcludeRealm(NewRealm(s1, s2, s3), []string{"s1.e1"})
+	require.NoError(t, err)
+	require.Len(t, r.Schemas, 3)
+	require.Empty(t, r.Schemas[0].Objects)
+	require.Len(t, r.Schemas[1].Objects, 2)
+	require.Len(t, r.Schemas[2].Objects, 3)
+
+	// Wrong selector.
+	r, err = ExcludeRealm(NewRealm(s1, s2, s3), []string{"*.e1[type=table]"})
+	require.NoError(t, err)
+	require.Len(t, r.Schemas, 3)
+	require.Empty(t, r.Schemas[0].Objects)
+	require.Len(t, r.Schemas[1].Objects, 2)
+	require.Len(t, r.Schemas[2].Objects, 3)
+
+	// Enum selector.
+	r, err = ExcludeRealm(NewRealm(s1, s2, s3), []string{"*.e1[type=enum]"})
+	require.NoError(t, err)
+	require.Len(t, r.Schemas, 3)
+	require.Empty(t, r.Schemas[0].Objects)
+	require.Len(t, r.Schemas[1].Objects, 1)
+	require.Equal(t, []Object{e2}, r.Schemas[1].Objects)
+	require.Len(t, r.Schemas[2].Objects, 2)
+	require.Equal(t, []Object{e2, e3}, r.Schemas[2].Objects)
+
+	// Exclude all.
+	r, err = ExcludeRealm(NewRealm(s1, s2, s3), []string{"*.*"})
+	require.NoError(t, err)
+	require.Len(t, r.Schemas, 3)
+	require.Empty(t, r.Schemas[0].Objects)
+	require.Empty(t, r.Schemas[1].Objects)
+	require.Empty(t, r.Schemas[2].Objects)
+}
+
+func TestExcludeSchema_Enums(t *testing.T) {
+	e1, e2, e3 := &EnumType{T: "e1"}, &EnumType{T: "e2"}, &EnumType{T: "e3"}
+	r := NewRealm(New("s1").AddObjects(e1, e2, e3))
+
+	s, err := ExcludeSchema(r.Schemas[0], []string{"e1"})
+	require.NoError(t, err)
+	require.Len(t, s.Objects, 2)
+	require.Equal(t, []Object{e2, e3}, s.Objects)
+
+	s, err = ExcludeSchema(r.Schemas[0], []string{"e1", "e2"})
+	require.NoError(t, err)
+	require.Len(t, s.Objects, 1)
+	require.Equal(t, []Object{e3}, s.Objects)
+
+	// Wrong selector.
+	s, err = ExcludeSchema(r.Schemas[0], []string{"e*[type=view]"})
+	require.NoError(t, err)
+	require.Len(t, s.Objects, 1)
+
+	// Enum selector.
+	s, err = ExcludeSchema(r.Schemas[0], []string{"*[type=enum]"})
+	require.NoError(t, err)
+	require.Empty(t, s.Objects)
+}
+
 func TestExcludeRealm_Selector(t *testing.T) {
 	r := NewRealm(
 		New("s1").