func collectAllSketchFiles(from string) ([]string, error) {
	filePaths := []string{}
	walkFunc := func(currentPath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			return nil
		}
		ext := strings.ToLower(filepath.Ext(currentPath))
		if !MAIN_FILE_VALID_EXTENSIONS[ext] && !ADDITIONAL_FILE_VALID_EXTENSIONS[ext] {
			return nil
		}
		currentFile, err := os.Open(currentPath)
		if err != nil {
			return nil
		}
		currentFile.Close()

		filePaths = append(filePaths, currentPath)
		return nil
	}
	err := gohasissues.Walk(from, walkFunc)
	return filePaths, utils.WrapError(err)
}
func collectAllToolsFolders(from string) ([]string, error) {
	folders := []string{}
	walkFunc := func(currentPath string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		if !info.IsDir() {
			return nil
		}

		rel, err := filepath.Rel(from, currentPath)
		if err != nil {
			return i18n.WrapError(err)
		}
		depth := len(strings.Split(rel, string(os.PathSeparator)))

		if info.Name() == constants.FOLDER_TOOLS && depth == 2 {
			folders = append(folders, currentPath)
		} else if depth > 2 {
			return filepath.SkipDir
		}

		return nil
	}
	err := gohasissues.Walk(from, walkFunc)

	if len(folders) == 0 {
		folders = append(folders, from)
	}

	return folders, i18n.WrapError(err)
}
func collectByWalk(filePaths *[]string, folder string) error {
	checkExtensionFunc := func(ext string) bool {
		return ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext]
	}
	walkFunc := utils.CollectAllReadableFiles(filePaths, checkExtensionFunc)
	err := gohasissues.Walk(folder, walkFunc)
	return utils.WrapError(err)
}
func collectAllSketchFiles(from string) ([]string, error) {
	filePaths := []string{}
	checkExtensionFunc := func(ext string) bool {
		return MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext]
	}
	walkFunc := utils.CollectAllReadableFiles(&filePaths, checkExtensionFunc)
	err := gohasissues.Walk(from, walkFunc)
	return filePaths, utils.WrapError(err)
}
func collectByWalk(filePaths *[]string, folder string) error {
	checkExtensionFunc := func(filePath string) bool {
		name := filepath.Base(filePath)
		ext := strings.ToLower(filepath.Ext(filePath))
		return !strings.HasPrefix(name, ".") && ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext]
	}
	walkFunc := utils.CollectAllReadableFiles(filePaths, checkExtensionFunc)
	err := gohasissues.Walk(folder, walkFunc)
	return utils.WrapError(err)
}
func copyRecursive(from, to string) error {
	copyFunc := func(currentPath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		rel, err := filepath.Rel(from, currentPath)
		if err != nil {
			return i18n.WrapError(err)
		}
		targetPath := filepath.Join(to, rel)
		if info.IsDir() {
			err := os.MkdirAll(targetPath, info.Mode())
			if err != nil {
				return i18n.WrapError(err)
			}
		} else if info.Mode().IsRegular() {
			fromFile, err := os.Open(currentPath)
			if err != nil {
				return i18n.WrapError(err)
			}
			defer fromFile.Close()
			targetFile, err := os.Create(targetPath)
			if err != nil {
				return i18n.WrapError(err)
			}
			defer targetFile.Close()
			_, err = io.Copy(targetFile, fromFile)
			if err != nil {
				return i18n.WrapError(err)
			}
			err = os.Chmod(targetPath, info.Mode())
			if err != nil {
				return i18n.WrapError(err)
			}
		} else if info.Mode()&os.ModeSymlink == os.ModeSymlink {
			linkedFile, err := os.Readlink(currentPath)
			if err != nil {
				return i18n.WrapError(err)
			}
			fromFile := filepath.Join(filepath.Dir(targetPath), linkedFile)
			err = os.Symlink(fromFile, targetPath)
			if err != nil {
				return i18n.WrapError(err)
			}
		} else {
			return errors.Errorf("unable to copy file " + currentPath)
		}

		return nil
	}
	err := gohasissues.Walk(from, copyFunc)
	return i18n.WrapError(err)
}
func collectAllSketchFiles(from string) ([]string, error) {
	filePaths := []string{}
	checkExtensionFunc := func(filePath string) bool {
		name := filepath.Base(filePath)
		ext := strings.ToLower(filepath.Ext(filePath))
		return !strings.HasPrefix(name, ".") && MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext]
	}
	walkFunc := utils.CollectAllReadableFiles(&filePaths, checkExtensionFunc)
	err := gohasissues.Walk(from, walkFunc)
	return filePaths, i18n.WrapError(err)
}
func findBuiltinToolsVersionsFile(folder string) (string, error) {
	builtinToolsVersionsFilePath := constants.EMPTY_STRING
	findBuiltInToolsVersionsTxt := func(currentPath string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		if builtinToolsVersionsFilePath != constants.EMPTY_STRING {
			return nil
		}
		if filepath.Base(currentPath) == constants.FILE_BUILTIN_TOOLS_VERSIONS_TXT {
			builtinToolsVersionsFilePath = currentPath
		}
		return nil
	}
	err := gohasissues.Walk(folder, findBuiltInToolsVersionsTxt)
	return builtinToolsVersionsFilePath, i18n.WrapError(err)
}