Skip to content

Commit

Permalink
utils fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter committed May 5, 2024
1 parent 91bca30 commit e284373
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 23 deletions.
31 changes: 21 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ var forwardCmd = &cobra.Command{
},
}

var utilsCmd = &cobra.Command{
var UtilsCmd = &cobra.Command{
Use: "utils",
}

Expand All @@ -148,7 +148,19 @@ var utilsCutByStringCmd = &cobra.Command{
Args: cobra.MinimumNArgs(3),
Run: func(cmd *cobra.Command, args []string) {
utils.Logger.Out = ioutil.Discard
modes.UtilsCutByString(args[1], args[2], args[3], args[4] == "true", args[5], "", 0)
modes.UtilsCutByString(utils.AString(args, 0, ""), utils.AString(args, 1, ""), utils.AString(args, 2, ""),
utils.ABool(args, 3, true), utils.AString(args, 4, ""), "", 0)
},
}
var utilsCutByLineNumberCmd = &cobra.Command{
Use: "cut-by-line-number <file> <count> <offset> {out-file = ''}",
Short: "A utility that cuts a file by a line number count and offset into a new file or standard output.",
Long: ``,
Args: cobra.MinimumNArgs(3),
Run: func(cmd *cobra.Command, args []string) {
utils.Logger.Out = ioutil.Discard

modes.UtilsCutByLineNumber(utils.AString(args, 0, ""), utils.AInt(args, 1, 0), utils.AInt(args, 2, 0), utils.AString(args, 3, ""))
},
}

Expand All @@ -159,11 +171,9 @@ var utilsCutByDateCmd = &cobra.Command{
Args: cobra.MinimumNArgs(5),
Run: func(cmd *cobra.Command, args []string) {
utils.Logger.Out = ioutil.Discard
offset, err := strconv.Atoi(args[4])
if err != nil {
panic(err)
}
modes.UtilsCutByString(args[0], args[1], args[2], false, args[3], args[5], offset)

modes.UtilsCutByString(utils.AString(args, 0, ""), utils.AString(args, 1, ""), utils.AString(args, 2, ""), false,
utils.AString(args, 5, ""), utils.AString(args, 3, ""), utils.AInt(args, 4, 0))
},
}

Expand Down Expand Up @@ -201,9 +211,10 @@ func init() {
utils.InitLogger()
ch = make(chan models.Message, 1000)

rootCmd.AddCommand(utilsCmd)
utilsCmd.AddCommand(utilsCutByStringCmd)
utilsCmd.AddCommand(utilsCutByDateCmd)
rootCmd.AddCommand(UtilsCmd)
UtilsCmd.AddCommand(utilsCutByStringCmd)
UtilsCmd.AddCommand(utilsCutByDateCmd)
UtilsCmd.AddCommand(utilsCutByLineNumberCmd)

rootCmd.PersistentFlags().StringP("port", "p", "8080", "Port on which the Web UI will be served")
rootCmd.PersistentFlags().StringP("ui-ip", "", "127.0.0.1", "Bind Web UI server to a specific IP address")
Expand Down
91 changes: 87 additions & 4 deletions modes/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,89 @@ import (
"github.com/sirupsen/logrus"
)

func UtilsCutByLineNumber(file string, count int, offset int, outFile string) {

if count < 0 {
panic("`count` must be greater than 0")
}
if offset < 0 {
panic("`offset` must be greater than 0")
}

_, err := os.Stat(file)
if err != nil {
utils.Logger.WithFields(logrus.Fields{
"path": file,
"error": err.Error(),
}).Error("Reading file failed")
return
}

var size int64
var bar *pb.ProgressBar
var r io.Reader
if outFile == "" {
r, size = utils.OpenFileForReading(file)
} else {
r, size, bar = utils.OpenFileForReadingWithProgress(file)
}

utils.Logger.WithFields(logrus.Fields{
"path": file,
"size_bytes": size,
}).Info("Reading file")

var f *os.File
if outFile != "" {
f, err = os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer f.Close() // Close the file when we're done
}

started := false
stopped := false
ln := 0
utils.LineCounterWithChannel(r, func(line utils.Line, cancel func()) {
ln++

if stopped {
return
}

if ln == offset {
started = true
}

if !started {
return
}

if outFile == "" {
os.Stdout.Write(line.Line)
os.Stdout.Write([]byte{'\n'})
} else {
f.Write(line.Line)
f.Write([]byte{'\n'})
if err != nil {
panic(err)
}
}

if ln == count+offset-1 {
cancel()
stopped = true
return
}

})

if outFile != "" {
bar.Finish()
}
}

func UtilsCutByString(file string, start string, end string, caseInsensitive bool, outFile string, dateFormat string, searchOffset int) {
_, err := os.Stat(file)
if err != nil {
Expand Down Expand Up @@ -55,11 +138,11 @@ func UtilsCutByString(file string, start string, end string, caseInsensitive boo
if dateFormat != "" {
startDate, err = time.Parse(dateFormat, start)
if err != nil {
panic(err)
panic("Error while parsing input `start` date: " + err.Error())
}
endDate, err = time.Parse(dateFormat, end)
if err != nil {
panic(err)
panic("Error while parsing input `end` date: " + err.Error())
}
}

Expand All @@ -83,7 +166,7 @@ func UtilsCutByString(file string, start string, end string, caseInsensitive boo
t, err := time.Parse(dateFormat, ln[searchOffset:searchOffset+len(dateFormat)])

if err != nil {
panic(err)
return
}

if !t.IsZero() && (t.After(startDate) || t.Equal(startDate)) {
Expand Down Expand Up @@ -116,7 +199,7 @@ func UtilsCutByString(file string, start string, end string, caseInsensitive boo
t, err := time.Parse(dateFormat, ln[searchOffset:searchOffset+len(dateFormat)])

if err != nil {
panic(err)
return
}

if !t.IsZero() && (t.After(endDate) || t.Equal(endDate)) {
Expand Down
167 changes: 158 additions & 9 deletions modes/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,6 @@ func TestUtilsCutByStringLong(t *testing.T) {
outFile: "",
expectedLines: 1571,
},
{
name: "Basic cut (case sensitive)",
file: tmpFile.Name(),
start: "7650",
end: "9220",
caseInsensitive: false,
outFile: "",
expectedLines: 1571,
},
}

for _, tc := range tests {
Expand Down Expand Up @@ -346,3 +337,161 @@ func TestUtilsCutByStringDate(t *testing.T) {
})
}
}

func TestUtilsCutByLineNumber(t *testing.T) {

// Create a temporary file with some test data
data := `This is line 1
This is line 2 (cut here)
This is line 3 to be copied
This is line 4 (end cut here)
This is line 5`
tmpFile, err := ioutil.TempFile("", "cut_by_string_test")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name()) // Clean up the temporary file

_, err = tmpFile.Write([]byte(data))
if err != nil {
t.Fatal(err)
}

// Define test cases
tests := []struct {
name string
file string
count int
offset int
outFile string
expectedOutput string
}{
{
name: "Basic cut",
file: tmpFile.Name(),
count: 2,
offset: 2,
outFile: "",
expectedOutput: "This is line 2 (cut here)\nThis is line 3 to be copied\n",
},
{
name: "Basic cut (to file)",
file: tmpFile.Name(),
count: 2,
offset: 3,
outFile: t.TempDir() + "/cut_output.txt",
expectedOutput: "This is line 3 to be copied\nThis is line 4 (end cut here)\n",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var oldWriter = os.Stdout
stdout, err := os.CreateTemp("", "")
if err != nil {
panic(err)
}
if tc.outFile == "" {
os.Stdout = stdout
defer func() {
os.Stdout = oldWriter
}()
}

UtilsCutByLineNumber(tc.file, tc.count, tc.offset, tc.outFile)

// Assertions
if tc.outFile == "" {
os.Stdout.Sync()
fl, _ := os.Open(stdout.Name())
content, err := io.ReadAll(fl)

if err != nil {
panic(err)
}
assert.Equal(t, tc.expectedOutput, string(content))
} else {
// Read output file content
outputFileData, err := ioutil.ReadFile(tc.outFile)
assert.Nil(t, err)
assert.Equal(t, tc.expectedOutput, string(outputFileData))
}
})
}
}

func TestUtilsCutLineNumberLong(t *testing.T) {

// Create a temporary file with some test data
const loremipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"

tmpFile, err := ioutil.TempFile("", "cut_by_string_test")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name()) // Clean up the temporary file

for i := 0; i <= 10_000; i++ {
_, err := tmpFile.WriteString(strconv.Itoa(i) + "_" + loremipsum + "\n")
if err != nil {
t.Fatal(err)
}
}

// Define test cases
tests := []struct {
name string
file string
count int
offset int
caseInsensitive bool
outFile string
}{
{
name: "Basic cut",
file: tmpFile.Name(),
count: 3,
offset: 7650,
caseInsensitive: false,
outFile: "",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var oldWriter = os.Stdout
stdout, err := os.CreateTemp("", "")
if err != nil {
panic(err)
}
if tc.outFile == "" {
os.Stdout = stdout
defer func() {
os.Stdout = oldWriter
}()
}

UtilsCutByLineNumber(tc.file, tc.count, tc.offset, tc.outFile)

// Assertions
if tc.outFile == "" {
os.Stdout.Sync()
fl, _ := os.Open(stdout.Name())
num, err := utils.LineCounter(fl)
assert.Nil(t, err)

if err != nil {
panic(err)
}
assert.Equal(t, tc.count, num)
} else {
// Read output file content
outputFileData, err := os.Open(tc.outFile)
assert.Nil(t, err)
num, err := utils.LineCounter(outputFileData)
assert.Nil(t, err)
assert.Equal(t, tc.count, num)
}
})
}
}

0 comments on commit e284373

Please sign in to comment.