grafana/scripts/modowners/modowners_test.go

104 lines
2.7 KiB
Go
Raw Normal View History

Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
package main
import (
"bytes"
"log"
"strings"
"testing"
"testing/fstest"
)
func TestCommonElement(t *testing.T) {
for _, test := range []struct {
A []string
B []string
Result bool
}{
{nil, nil, false},
{[]string{"a"}, []string{"a"}, true},
{[]string{"a", "b"}, []string{"a"}, true},
{[]string{"a"}, []string{"b"}, false},
} {
if hasCommonElement(test.A, test.B) != test.Result {
t.Error(test)
}
}
}
func TestCheck(t *testing.T) {
for _, test := range []struct {
description string
fileName string
contents string
args []string
valid bool
expectedOutput string
}{
{"Test valid modfile", "go.mod", `
require (
cloud.google.com/go/storage v1.28.1 // @delivery
cuelang.org/go v0.5.0 // @as-code @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery
github.com/Masterminds/semver v1.5.0 // @delivery @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
)
`, []string{"go.mod"}, true, ""},
{"Test invalid modfile", "go.mod", `
require (
cloud.google.com/go/storage v1.28.1
cuelang.org/go v0.5.0 // @as-code @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery
github.com/Masterminds/semver v1.5.0 // @delivery @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
)
`, []string{"go.mod"}, false, "cloud.google.com/go/storage@v1.28.1\n"},
} {
buf := &bytes.Buffer{}
logger := log.New(buf, "", 0)
filesystem := fstest.MapFS{test.fileName: &fstest.MapFile{Data: []byte(test.contents)}}
err := check(filesystem, logger, test.args)
if test.valid && err != nil {
t.Error(test.description, err)
} else if !test.valid && err == nil {
t.Error(test.description, "error expected")
}
if buf.String() != test.expectedOutput {
t.Error(test.description, buf.String())
}
}
}
func TestModules(t *testing.T) {
buf := &bytes.Buffer{}
logger := log.New(buf, "", 0)
tool: generate owners for modules in `go.mod` (#69583) * test: add test for getFiles * fix: fix getFiles test to take in a module name (not modfile name) * move functionality unrelated to getFiles into main func * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * test * Revert "test" This reverts commit 2b519f3725f5709e5ace412f6bd1de4bc9f15e01. * Revert "attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go" This reverts commit eb952474870243110bdc1087c8468981d5eda5b2. * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * post-pairing with daniel, can access imports in a file * clean up comments for readability * try to return map of importName: files that import the improt * refactor: change getFiles to accept single import name and return list of files that import it * add log to see importPath and importName * hasImport working * start modowners script & add comments for hasImport * fix modules() and uncomment main * start script to add team names to go.mod, currently can access a map of the import and name * :shit: * calculate root directory to point to correct go.mod * chore: delete unnecessary files * chore: uncomment tests * chore: remove unnecessary comments, update documentation comments with correct cli commands * fix: revert changes in go.mod and go.sum * where is my dependency flag value?? * fix: owners function now can list all owners (with counts) or list a specific owner for a given dependency * fix: change fmt.Println to logger.Println for owners func * partial fix: modules now only prints dependencies owned by given team. -i functionality still not working properly * fix: fix TestModules, modules * chore: update check error message to specify user needs to assign owner to new dependency * fix: adjust punctuation in error string * fix: clean up comments in modowners * chore: remove note in modowners_test
2023-07-18 12:42:09 -05:00
filesystem := fstest.MapFS{"go.mod": &fstest.MapFile{Data: []byte(`
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
require (
cloud.google.com/go/storage v1.28.1
cuelang.org/go v0.5.0 // @as-code @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery
github.com/Masterminds/semver v1.5.0 // @delivery @grafana/grafana-backend-group
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
)
`)}}
tool: generate owners for modules in `go.mod` (#69583) * test: add test for getFiles * fix: fix getFiles test to take in a module name (not modfile name) * move functionality unrelated to getFiles into main func * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * test * Revert "test" This reverts commit 2b519f3725f5709e5ace412f6bd1de4bc9f15e01. * Revert "attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go" This reverts commit eb952474870243110bdc1087c8468981d5eda5b2. * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * post-pairing with daniel, can access imports in a file * clean up comments for readability * try to return map of importName: files that import the improt * refactor: change getFiles to accept single import name and return list of files that import it * add log to see importPath and importName * hasImport working * start modowners script & add comments for hasImport * fix modules() and uncomment main * start script to add team names to go.mod, currently can access a map of the import and name * :shit: * calculate root directory to point to correct go.mod * chore: delete unnecessary files * chore: uncomment tests * chore: remove unnecessary comments, update documentation comments with correct cli commands * fix: revert changes in go.mod and go.sum * where is my dependency flag value?? * fix: owners function now can list all owners (with counts) or list a specific owner for a given dependency * fix: change fmt.Println to logger.Println for owners func * partial fix: modules now only prints dependencies owned by given team. -i functionality still not working properly * fix: fix TestModules, modules * chore: update check error message to specify user needs to assign owner to new dependency * fix: adjust punctuation in error string * fix: clean up comments in modowners * chore: remove note in modowners_test
2023-07-18 12:42:09 -05:00
err := modules(filesystem, logger, []string{"go.mod"})
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
if err != nil {
t.Error(err, buf.String())
}
logs := buf.String()
// Expected results
expectedModules := []string{
tool: generate owners for modules in `go.mod` (#69583) * test: add test for getFiles * fix: fix getFiles test to take in a module name (not modfile name) * move functionality unrelated to getFiles into main func * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * test * Revert "test" This reverts commit 2b519f3725f5709e5ace412f6bd1de4bc9f15e01. * Revert "attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go" This reverts commit eb952474870243110bdc1087c8468981d5eda5b2. * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * post-pairing with daniel, can access imports in a file * clean up comments for readability * try to return map of importName: files that import the improt * refactor: change getFiles to accept single import name and return list of files that import it * add log to see importPath and importName * hasImport working * start modowners script & add comments for hasImport * fix modules() and uncomment main * start script to add team names to go.mod, currently can access a map of the import and name * :shit: * calculate root directory to point to correct go.mod * chore: delete unnecessary files * chore: uncomment tests * chore: remove unnecessary comments, update documentation comments with correct cli commands * fix: revert changes in go.mod and go.sum * where is my dependency flag value?? * fix: owners function now can list all owners (with counts) or list a specific owner for a given dependency * fix: change fmt.Println to logger.Println for owners func * partial fix: modules now only prints dependencies owned by given team. -i functionality still not working properly * fix: fix TestModules, modules * chore: update check error message to specify user needs to assign owner to new dependency * fix: adjust punctuation in error string * fix: clean up comments in modowners * chore: remove note in modowners_test
2023-07-18 12:42:09 -05:00
"cloud.google.com/go/storage@v1.28.1",
"cuelang.org/go@v0.5.0",
"github.com/Masterminds/semver@v1.5.0",
"",
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
}
expectedResults := strings.Join(expectedModules, "\n")
// Compare logs to expected results
if logs != expectedResults {
tool: generate owners for modules in `go.mod` (#69583) * test: add test for getFiles * fix: fix getFiles test to take in a module name (not modfile name) * move functionality unrelated to getFiles into main func * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * test * Revert "test" This reverts commit 2b519f3725f5709e5ace412f6bd1de4bc9f15e01. * Revert "attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go" This reverts commit eb952474870243110bdc1087c8468981d5eda5b2. * attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go * post-pairing with daniel, can access imports in a file * clean up comments for readability * try to return map of importName: files that import the improt * refactor: change getFiles to accept single import name and return list of files that import it * add log to see importPath and importName * hasImport working * start modowners script & add comments for hasImport * fix modules() and uncomment main * start script to add team names to go.mod, currently can access a map of the import and name * :shit: * calculate root directory to point to correct go.mod * chore: delete unnecessary files * chore: uncomment tests * chore: remove unnecessary comments, update documentation comments with correct cli commands * fix: revert changes in go.mod and go.sum * where is my dependency flag value?? * fix: owners function now can list all owners (with counts) or list a specific owner for a given dependency * fix: change fmt.Println to logger.Println for owners func * partial fix: modules now only prints dependencies owned by given team. -i functionality still not working properly * fix: fix TestModules, modules * chore: update check error message to specify user needs to assign owner to new dependency * fix: adjust punctuation in error string * fix: clean up comments in modowners * chore: remove note in modowners_test
2023-07-18 12:42:09 -05:00
t.Error(logs)
t.Error(expectedResults)
Feat: Add command line app to validate go.mod (#67796) * chore: start modowners * read go.mod, parse modfile, iterate through requires; add dummy go.mod * make BEP owners of all grafana dependencies :scream: * push attempt at logging the require comments * shrink dummy modfile * revert changes in go.mod * access comments suffix * add Module struct; attempt to separate ParseGoMod functionality into its own func; add owner (third) for loop when interating modfile * feat: print all owners in modfile * add additional question in comment * feat: add subcommands: check, owners, modules; chunk out some functions * chunk out subcommand functions * add flags * start tests for common element * refactor: test for common element * attempt #1 to refactor modules to accept multiple args * refactor: refactor modfule func to take 1+ owner arguments (0 arguments not working atm) * chore: remove debug logging * refine existing comments * comment out indirect flag stuff, add example cli command for modules * unsuccessful attempt #2 to refactor modules to accept -o and -i flags * refactor funcs to take filesystem and logger * test: add test for check when all modules have owners * fail attempt 1 to get TestModules to work * assert expected log result in TestModules; unsure if properly reading logs * test: add TestModules to test modules func without any flags returns direct dependencies * test: add TestInvalidCheck for scenario when some dependencies are missing an owner * attempt 1 at refactoring TestCheck into a table * chore: clean TestCheck * chore: clean up comments for func check * move files under scripts/modowners * revert go.mod and go.sum
2023-05-30 10:18:05 -05:00
}
}