diff --git a/internal/utils/npm.go b/internal/utils/npm.go index 0d8980a..f2579c5 100644 --- a/internal/utils/npm.go +++ b/internal/utils/npm.go @@ -1,6 +1,7 @@ package utils import ( + "bufio" "os" "strings" @@ -9,90 +10,153 @@ import ( errorMessages "github.com/RaulCatalinas/HuskyBC/internal/error_messages" ) -func modifyNpmIgnore(filesToAdd interface{}) { - defer func() { - if r := recover(); r != nil { - WriteMessage(WriteMessageProps{ - Type: enums.MessageTypeError, - Message: errorMessages.FILE_ERROR_MESSAGES[enums.NpmIgnoreWriteError], - }) - - os.Exit(1) - } - }() +func handlePanic() { + if r := recover(); r != nil { + logError(errorMessages.FILE_ERROR_MESSAGES[enums.NpmIgnoreWriteError]) + os.Exit(1) + } +} +func logInfo(message string) { WriteMessage(WriteMessageProps{ Type: enums.MessageTypeInfo, - Message: "Writing in the file \".npmignore\"...", + Message: message, }) +} - CreateFolderOrFileIfNotExists(constants.PATH_DIR_NPMIGNORE, false) +func logSuccess(message string) { + WriteMessage(WriteMessageProps{ + Type: enums.MessageTypeSuccess, + Message: message, + }) +} + +func logError(message string) { + WriteMessage(WriteMessageProps{ + Type: enums.MessageTypeError, + Message: message, + }) +} + +func parseFilesToAdd(filesToAdd interface{}) []string { + switch v := filesToAdd.(type) { + case string: + return []string{strings.TrimSpace(v)} + case []string: + cleaned := make([]string, 0, len(v)) + + for _, file := range v { + trimmed := strings.TrimSpace(file) + + if trimmed != "" { + cleaned = append(cleaned, trimmed) + } + } + + return cleaned + default: + logError(errorMessages.PROCESS_ERROR_MESSAGES[enums.InvalidTypeForFilesToAddError]) + + os.Exit(1) + } + + return nil +} - data := readFile(constants.PATH_DIR_NPMIGNORE) +func mergeFiles(existingFiles, newFiles []string) []string { + fileSet := make(map[string]struct{}, len(existingFiles)+len(newFiles)) - ignoredFiles := string(data) + for _, file := range existingFiles { + fileSet[file] = struct{}{} + } + + for _, file := range newFiles { + fileSet[file] = struct{}{} + } - if ignoredFiles == "" { - var filesToWrite string + merged := make([]string, 0, len(fileSet)) - switch v := filesToAdd.(type) { - case string: - filesToWrite = v - case []string: - filesToWrite = strings.Join(v, "\n") - default: - WriteMessage(WriteMessageProps{ - Type: enums.MessageTypeError, - Message: errorMessages.PROCESS_ERROR_MESSAGES[enums.InvalidTypeForFilesToAddError], - }) + for file := range fileSet { + merged = append(merged, file) + } - os.Exit(1) + return merged +} + +func readNpmIgnore(filePath string) ([]string, error) { + file, err := os.Open(filePath) + + if err != nil { + if os.IsNotExist(err) { + return []string{}, nil + } + + return nil, err + } + + defer file.Close() + + var files []string + + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + if line != "" { + files = append(files, line) } + } - writeFile(constants.PATH_DIR_NPMIGNORE, []byte(filesToWrite)) + return files, scanner.Err() +} - WriteMessage(WriteMessageProps{ - Type: "success", - Message: "\".npmignore\" file modified successfully", - }) +func writeNpmIgnore(filePath string, content []string) error { + file, err := os.Create(filePath) - return + if err != nil { + return err } - ignoredFilesArray := strings.FieldsFunc(ignoredFiles, func(r rune) bool { - return r == '\n' - }) + defer file.Close() - trimmedIgnoredFilesArray := make([]string, 0, len(ignoredFilesArray)) + writer := bufio.NewWriter(file) - for _, file := range ignoredFilesArray { - trimmedFile := strings.TrimSpace(file) + for _, line := range content { + _, err := writer.WriteString(line + "\n") - if trimmedFile != "" { - trimmedIgnoredFilesArray = append(trimmedIgnoredFilesArray, trimmedFile) + if err != nil { + return err } } - switch v := filesToAdd.(type) { - case string: - trimmedIgnoredFilesArray = append(trimmedIgnoredFilesArray, v) - case []string: - trimmedIgnoredFilesArray = append(trimmedIgnoredFilesArray, v...) - default: - WriteMessage(WriteMessageProps{ - Type: enums.MessageTypeError, - Message: errorMessages.PROCESS_ERROR_MESSAGES[enums.InvalidTypeForFilesToAddError], - }) + return writer.Flush() +} + +func modifyNpmIgnore(filesToAdd interface{}) { + defer handlePanic() + + logInfo("Writing to the \".npmignore\" file...") + + CreateFolderOrFileIfNotExists(constants.PATH_DIR_NPMIGNORE, false) + + existingFiles, err := readNpmIgnore(constants.PATH_DIR_NPMIGNORE) + + if err != nil { + logError(errorMessages.FILE_ERROR_MESSAGES[enums.NpmIgnoreWriteError]) os.Exit(1) } - finalContent := strings.Join(trimmedIgnoredFilesArray, "\n") + filesToWrite := parseFilesToAdd(filesToAdd) + finalContent := mergeFiles(existingFiles, filesToWrite) - writeFile(constants.PATH_DIR_NPMIGNORE, []byte(finalContent)) + err = writeNpmIgnore(constants.PATH_DIR_NPMIGNORE, finalContent) - WriteMessage(WriteMessageProps{ - Type: "success", - Message: "\".npmignore\" file modified successfully", - }) + if err != nil { + logError(errorMessages.FILE_ERROR_MESSAGES[enums.NpmIgnoreWriteError]) + os.Exit(1) + } + + logSuccess("\".npmignore\" file modified successfully") }