Skip to content

Commit

Permalink
[#91] add rm action
Browse files Browse the repository at this point in the history
  • Loading branch information
kozmod committed Feb 9, 2024
1 parent 7245847 commit fbe54c5
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 3 deletions.
9 changes: 6 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const (
TagDirs = "dirs"
TagRm = "rm"
TagFiles = "files"
TagCmd = "cmd"
TagFS = "fs"
Expand All @@ -21,6 +22,7 @@ const (
type Config struct {
Settings Settings `yaml:"settings"`
Dirs []Section[[]string] `yaml:"dirs,flow"`
Rm []Section[[]string] `yaml:"rm,flow"`
Files []Section[[]File] `yaml:"files,flow"`
Cmd []Section[[]Command] `yaml:"cmd,flow"`
FS []Section[[]string] `yaml:"fs,flow"`
Expand Down Expand Up @@ -211,13 +213,14 @@ func validateConfigSections(conf Config) error {
var (
files = len(conf.Files)
dirs = len(conf.Dirs)
rm = len(conf.Rm)
cmd = len(conf.Cmd)
fs = len(conf.FS)
)
if files == 0 && dirs == 0 && cmd == 0 && fs == 0 {
if files == 0 && dirs == 0 && rm == 0 && cmd == 0 && fs == 0 {
return xerrors.Errorf(
"config not contains executable actions [dirs: %d, files: %d, cms: %d, fs: %d]",
dirs, files, cmd, fs,
"config not contains executable actions [dirs: %d, rm: %d, files: %d, cms: %d, fs: %d]",
dirs, rm, files, cmd, fs,
)
}
return nil
Expand Down
2 changes: 2 additions & 0 deletions internal/config/unmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ func (u *YamlUnmarshaler) Unmarshal(rawConfig []byte) (Config, error) {
conf.Settings = settings
case strings.Index(tag, TagDirs) == 0:
conf.Dirs, err = decode(conf.Dirs, node, tag)
case strings.Index(tag, TagRm) == 0:
conf.Rm, err = decode(conf.Rm, node, tag)
case strings.Index(tag, TagFiles) == 0:
conf.Files, err = decode(conf.Files, node, tag)
case strings.Index(tag, TagCmd) == 0:
Expand Down
5 changes: 5 additions & 0 deletions internal/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
EqualsSign = "="
LessThan = "<"
Tilda = "~"
Astrix = "*"
NewLine = "\n"

LogSliceSep = Comma + Space
Expand All @@ -59,6 +60,10 @@ type (
Apply(path string) (string, error)
}

RmStrategy interface {
Apply(path string) error
}

TemplateProc interface {
Process(name, text string) (string, error)
}
Expand Down
84 changes: 84 additions & 0 deletions internal/exec/rm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package exec

import (
"os"
"path/filepath"
"strings"

"golang.org/x/xerrors"

"github.com/kozmod/progen/internal/entity"
)

type RmAllExecutor struct {
paths []string
strategies []entity.RmStrategy
}

func NewRmAllExecutor(paths []string, strategies []entity.RmStrategy) *RmAllExecutor {
return &RmAllExecutor{
paths: paths,
strategies: strategies,
}
}

func (p *RmAllExecutor) Exec() error {
for _, path := range p.paths {
for _, strategy := range p.strategies {
err := strategy.Apply(path)
if err != nil {
return xerrors.Errorf("execute rm: process rm [%s]: %w", path, err)
}
}
}
return nil
}

type RmAllStrategy struct {
logger entity.Logger
}

func NewRmAllStrategy(logger entity.Logger) *RmAllStrategy {
return &RmAllStrategy{
logger: logger,
}
}

func (p *RmAllStrategy) Apply(path string) error {
astrixIndex := strings.Index(path, entity.Astrix)
if astrixIndex == len(path)-1 {
contents, err := filepath.Glob(path)
if err != nil {
return xerrors.Errorf("rm [%s]: get names of the all files: %w", path, err)
}
for _, item := range contents {
err = os.RemoveAll(item)
if err != nil {
return xerrors.Errorf("rm content [%s]: %w", item, err)
}
}
return nil
}

err := os.RemoveAll(path)
if err != nil {
return xerrors.Errorf("rm [%s]: %w", path, err)
}
p.logger.Infof("rm: %s", path)
return nil
}

type DryRunRmAllStrategy struct {
logger entity.Logger
}

func NewDryRmAllStrategy(logger entity.Logger) *DryRunRmAllStrategy {
return &DryRunRmAllStrategy{
logger: logger,
}
}

func (p *DryRunRmAllStrategy) Apply(path string) error {
p.logger.Infof("rm: %s", path)
return nil
}
117 changes: 117 additions & 0 deletions internal/exec/rm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package exec

import (
"fmt"
"os"
"strings"
"testing"

"github.com/stretchr/testify/assert"

Check failure on line 9 in internal/exec/rm_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"path/filepath"

"github.com/kozmod/progen/internal/entity"
)

func Test_RmAllStrategy(t *testing.T) {
SkipSLowTest(t)

const (
someDir = "some_dir"
someFile = "file_name.txt"
)

t.Run("rm_dir", func(t *testing.T) {
WithTempDir(t, func(tmpDir string) {
var (
a = assert.New(t)
path = filepath.Join(tmpDir, someDir)
mockLogger = MockLogger{
infof: func(format string, args ...any) {
assert.NotEmpty(t, format)
assert.ElementsMatch(t, []string{path}, args)
},
}
)

err := os.MkdirAll(path, os.ModePerm)
a.NoError(err)
a.DirExists(path)

err = NewRmAllStrategy(mockLogger).Apply(path)
a.NoError(err)
a.NoDirExists(path)
})
})

t.Run("rm_file", func(t *testing.T) {
WithTempDir(t, func(tmpDir string) {
var (
a = assert.New(t)
dir = filepath.Join(tmpDir, someDir, someFile)
filePath = filepath.Join(dir, someFile)
mockLogger = MockLogger{
infof: func(format string, args ...any) {
assert.NotEmpty(t, format)
assert.ElementsMatch(t, []string{filePath}, args)
},
}
)

err := os.MkdirAll(dir, os.ModePerm)
a.NoError(err)
a.DirExists(dir)

file, err := os.Create(filePath)
a.NoError(err)
a.FileExists(filePath)
a.Equal(filePath, file.Name())

err = NewRmAllStrategy(mockLogger).Apply(filePath)
a.NoError(err)
a.NoFileExists(filePath)
a.DirExists(dir)
})
})
t.Run("rm_all_files", func(t *testing.T) {
WithTempDir(t, func(tmpDir string) {
const (
filesQuantity = 5
)
var (
a = assert.New(t)
dir = filepath.Join(tmpDir, someDir)
rmPath = filepath.Join(dir, entity.Astrix)
filesPath = make([]string, 0, filesQuantity)
mockLogger = MockLogger{
infof: func(format string, args ...any) {
assert.NotEmpty(t, format)
},
}
)

err := os.MkdirAll(dir, os.ModePerm)
a.NoError(err)
a.DirExists(dir)

for i := 0; i < filesQuantity; i++ {
var (
fileExt = filepath.Ext(someFile)
fileName = fmt.Sprintf("%s_%d%s", strings.TrimSuffix(someFile, fileExt), i, fileExt)
filePath = filepath.Join(tmpDir, someDir, fileName)
)
filesPath = append(filesPath, filePath)
_, err = os.Create(filePath)
a.NoError(err)
a.FileExists(filePath)
}

err = NewRmAllStrategy(mockLogger).Apply(rmPath)
a.NoError(err)
a.DirExists(dir)
for _, path := range filesPath {
a.NoFileExists(path)
}
})
})

}
18 changes: 18 additions & 0 deletions internal/factory/chain_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ func NewExecutorChain(
},
})
}
for _, rm := range conf.Rm {
var (
r = rm
action = r.Tag
)

if !actionFilter.MatchString(action) {
continue
}
builders = append(builders,
ExecutorBuilder{
action: action,
line: r.Line,
procFn: func() (entity.Executor, error) {
return NewRmExecutor(r.Val, logger, dryRun)
},
})
}

var preprocessors []entity.Preprocessor
for _, files := range conf.Files {
Expand Down
21 changes: 21 additions & 0 deletions internal/factory/rm_exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package factory

import (
"github.com/kozmod/progen/internal/entity"
"github.com/kozmod/progen/internal/exec"
)

func NewRmExecutor(paths []string, logger entity.Logger, dryRun bool) (entity.Executor, error) {
if len(paths) == 0 {
logger.Infof("rm executor: `rm` section is empty")
return nil, nil
}

pathsSet := entity.Unique(paths)

if dryRun {
return exec.NewRmAllExecutor(pathsSet, []entity.RmStrategy{exec.NewDryRmAllStrategy(logger)}), nil
}

return exec.NewRmAllExecutor(pathsSet, []entity.RmStrategy{exec.NewRmAllStrategy(logger)}), nil
}

0 comments on commit fbe54c5

Please sign in to comment.