Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/3316/rawtextparser asking twice #3405

Merged
merged 24 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1bb5966
Resolve issues with question about filetype #3316
Nereboss Nov 9, 2023
82e2e01
Add more tests for MetricCollector #3316
Nereboss Nov 9, 2023
5d6177d
Adjust RawTextParser to correctly handle filetypes #3316
Nereboss Nov 10, 2023
5096d5e
Adjust behaviour of metricCollector #3316
Nereboss Nov 10, 2023
fe38425
Added tests for RawTextParser for invalid file type #3316
Nereboss Nov 10, 2023
641bd38
Adjust RawTextParser to correctly handle invalid file types #3316
Nereboss Nov 13, 2023
ec9a47a
Fix assertions for invalid extension tests #3316
fritschldwg Nov 13, 2023
c29c683
Adjust outputfile for added sample project file #3316
fritschldwg Nov 13, 2023
bdf503c
Replace error prints with logger calls #3316
fritschldwg Nov 14, 2023
867ccd6
Add tests for error logging #3316
fritschldwg Nov 14, 2023
ecfd5f3
Adjust condition to match linting style #3316
fritschldwg Nov 14, 2023
5adbf07
Adjust tests for added file to sampleproject #3316
fritschldwg Nov 14, 2023
3c225a1
Adjust tests for added file to sampleproject #3316
fritschldwg Nov 14, 2023
e0bf7f4
Calrify questions for file-extensions and output-file #3316
fritschldwg Nov 14, 2023
d41797e
Update documentation to include file-extensions #3316
fritschldwg Nov 14, 2023
4ca990e
Fix rebase conflicts #3316
Nereboss Nov 21, 2023
67c9f65
Small refactor against code smell found by sonar #3316
Nereboss Nov 16, 2023
2628016
Refactor naming of file extension in sample project #3316
Nereboss Nov 17, 2023
a53915c
Move part of call function into helper function #3316
Nereboss Nov 17, 2023
02962c5
Update flag and readme for rawtextparser #3316
Nereboss Nov 21, 2023
1887c68
Update readme and gh-pages #3316
Nereboss Nov 21, 2023
72d961f
Fix typo in readme and gh-pages #3316
Nereboss Nov 21, 2023
6f368b4
Add missing parameter to gh-pages #3316
Nereboss Nov 21, 2023
35cb98b
Fix rebase conflicts #3316
Nereboss Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/)

## [unreleased] (Added 🚀 | Changed | Removed 🗑 | Fixed 🐞 | Chore 👨‍💻 👩‍💻)

### Changed

- Changed short form of parameter `--file-extensions` of RawTextParser from `-f` to `-fe` [#3405](https://github.com/MaibornWolff/codecharta/pull/3405)
- Update readme and gh-pages for RawTextParser [#3405](https://github.com/MaibornWolff/codecharta/pull/3405)

### Fixed 🐞

- Fix RawTextParser producing incorrect output when no (or multiple) file extensions were specified in interactive mode [#3405](https://github.com/MaibornWolff/codecharta/pull/3405)

## [1.120.1] - 2023-11-17

### Removed 🗑
Expand Down
47 changes: 26 additions & 21 deletions analysis/parser/RawTextParser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,33 @@ This parser analyzes code regardless of the programming language used to generat
## Parameters

```
Usage: rawtextparser [-hv] [--withoutDefaultExcludes]
[--maxIndentationLevel=<maxIndentLvl>]
[--tabWidth=<tabWith>] [-o=<outputFile>]
[-p=<projectName>] [-e=<exclude>]... [-m
[=<metrics>...]]... FILE or FOLDER
Usage: rawtextparser [-hv] [-nc] [--without-default-excludes]
[--max-indentation-level=<maxIndentLvl>]
[-o=<outputFile>] [--tab-width=<tabWidth>]
[-e=<exclude>]... [-fe=<fileExtensions>[\s*,
\s*<fileExtensions>...]]... [-m[=<metrics>...]]...
FILE or FOLDER
generates cc.json from projects or source code files
FILE or FOLDER file/project to parse
--maxIndentationLevel=<maxIndentLvl>
maximum Indentation Level (default 10)
--tabWidth=<tabWith> tab width used (estimated if not provided)
--withoutDefaultExcludes
include build, target, dist, resources and out folders
as well as files/folders starting with '.'
-e, --exclude=<exclude> exclude file/folder according to regex pattern
-h, --help displays this help and exits
FILE or FOLDER file/project to parse
-e, --exclude=<exclude> exclude file/folder according to regex pattern
-fe, --file-extensions=<fileExtensions>[\s*,\s*<fileExtensions>...]
parse only files with specified extensions
(default: any)
-h, --help displays this help and exits
-m, --metrics[=<metrics>...]
metrics to be computed (select all if not specified)
-o, --outputFile=<outputFile>
output File (or empty for stdout)
-p, --projectName=<projectName>
project name
-v, --verbose verbose mode
metrics to be computed (select all if not specified)
--max-indentation-level=<maxIndentLvl>
ce-bo marked this conversation as resolved.
Show resolved Hide resolved
maximum Indentation Level (default 10)
-nc, --not-compressed save uncompressed output File
-o, --output-file=<outputFile>
output File (or empty for stdout)
--tab-width=<tabWidth>
tab width used (estimated if not provided)
-v, --verbose verbose mode
--without-default-excludes
include build, target, dist, resources and out
folders as well as files/folders starting with
'.'
```

## Examples
Expand All @@ -42,7 +47,7 @@ ccsh rawtextparser foo/bar/project
```

```
ccsh rawtextparser foo.txt --maxIndentationLevel=6 tabWidth=4 --metrics=IndentationLevel
ccsh rawtextparser foo.txt --max-indentation-level=6 tab-width=4 --metrics=IndentationLevel
```

```
Expand Down
1 change: 1 addition & 0 deletions analysis/parser/RawTextParser/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies {
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: junit5_version
testImplementation group: 'org.assertj', name: 'assertj-core', version: assertj_version
testImplementation group: 'io.mockk', name: 'mockk', version: mockk_version
testImplementation group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.1'
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ class MetricCollector(
}

private fun isParsableFileExtension(path: String): Boolean {
return fileExtensions.isEmpty() || fileExtensions.contains(path.substringAfterLast("."))
return fileExtensions.isEmpty() ||
fileExtensions.contentEquals(arrayOf("")) ||
fileExtensions.contains(path.substringAfterLast(".")) ||
fileExtensions.contains(".${path.substringAfterLast(".")}")
ce-bo marked this conversation as resolved.
Show resolved Hide resolved
}

private fun isPathExcluded(path: String): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ParserDialog {
)

val outputFileName: String = KInquirer.promptInput(
message = "What is the name of the output file?",
message = "What is the name of the output file (leave empty to print to stdout)?",
)

val isCompressed = (outputFileName.isEmpty()) || KInquirer.promptConfirm(
Expand All @@ -44,7 +44,7 @@ class ParserDialog {
KInquirer.promptInput(message = "Do you want to exclude file/folder according to regex pattern?", default = "", hint = "regex1, regex2.. (leave empty if you don't want to exclude anything)")

val fileExtensions: String =
KInquirer.promptInput(message = "Do you want to exclude file/folder according to regex pattern?", default = "", hint = "regex1, regex2.. (leave empty if you don't want to exclude anything)")
KInquirer.promptInput(message = "Do you only want to parse files with specific file-extensions? ", default = "", hint = "fileType1, fileType2... (leave empty to include all file-extensions)")

val withoutDefaultExcludes: Boolean =
KInquirer.promptConfirm(message = "Do you want to include build, target, dist, resources and out folders as well as files/folders starting with '.'?", default = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import de.maibornwolff.codecharta.tools.interactiveparser.InteractiveParser
import de.maibornwolff.codecharta.tools.interactiveparser.ParserDialogInterface
import de.maibornwolff.codecharta.tools.interactiveparser.util.CodeChartaConstants
import de.maibornwolff.codecharta.util.InputHelper
import mu.KotlinLogging
import picocli.CommandLine
import java.io.File
import java.io.IOException
Expand All @@ -27,6 +28,8 @@ class RawTextParser(
private val error: PrintStream = System.err,
) : Callable<Void>, InteractiveParser {

private val logger = KotlinLogging.logger {}

private val DEFAULT_EXCLUDES = arrayOf("/out/", "/build/", "/target/", "/dist/", "/resources/", "/\\..*")

@CommandLine.Option(names = ["-h", "--help"], usageHelp = true, description = ["displays this help and exits"])
Expand Down Expand Up @@ -61,8 +64,9 @@ class RawTextParser(
private var exclude: Array<String> = arrayOf()

@CommandLine.Option(
names = ["-f", "--file-extensions"],
description = ["parse only files with specified extensions (defualt: any)"]
names = ["-fe", "--file-extensions"],
description = ["parse only files with specified extensions (default: any)"],
split = "\\s*,\\s*"
)
private var fileExtensions: Array<String> = arrayOf()

Expand Down Expand Up @@ -97,6 +101,15 @@ class RawTextParser(
val parameterMap = assembleParameterMap()
val results: Map<String, FileMetrics> =
MetricCollector(inputFile!!, exclude, fileExtensions, parameterMap, metrics).parse()
println()

if (results.isEmpty()) {
println()
logger.error("No files with specified file extension(s) were found within the given folder - not generating an output file!")
return null
}

logWarningsForNotFoundFileExtensions(results)

val pipedProject = ProjectDeserializer.deserializeProject(input)
val project = ProjectGenerator().generate(results, pipedProject)
Expand All @@ -114,6 +127,25 @@ class RawTextParser(
).filterValues { it != null }.mapValues { it.value as Int }
}

private fun logWarningsForNotFoundFileExtensions(results: Map<String, FileMetrics>) {
val notFoundFileExtensions = mutableListOf<String>()
for (fileExtension in fileExtensions) {
var isFileExtensionIncluded = false
for (relativeFileName in results.keys) {
if (relativeFileName.contains(fileExtension)) {
isFileExtensionIncluded = true
}
}
if (!isFileExtensionIncluded) {
notFoundFileExtensions.add(fileExtension)
}
}
if (notFoundFileExtensions.isNotEmpty()) {
println()
notFoundFileExtensions.forEach { logger.warn("The specified file extension '$it' was not found within the given folder!") }
}
Nereboss marked this conversation as resolved.
Show resolved Hide resolved
}

override fun getDialog(): ParserDialogInterface = ParserDialog
override fun isApplicable(resourceToBeParsed: String): Boolean {
println("Checking if RawTextParser is applicable...")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import java.io.File
class MetricCollectorTest {
@Test
fun `Should collect information about a single file`() {
val result = MetricCollector(File("src/test/resources/sampleproject/tabs.xyz").absoluteFile).parse()
val result = MetricCollector(File("src/test/resources/sampleproject/tabs.included").absoluteFile).parse()

Assertions.assertThat(result.size).isEqualTo(1)
Assertions.assertThat(result).containsKey("/tabs.xyz")
Assertions.assertThat(result["/tabs.xyz"]?.metricMap).isNotEmpty
Assertions.assertThat(result).containsKey("/tabs.included")
Assertions.assertThat(result["/tabs.included"]?.metricMap).isNotEmpty
}

@Test
fun `Should collect information about all files within a project`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile).parse()

Assertions.assertThat(result.size).isEqualTo(4)
Assertions.assertThat(result).containsKey("/tabs.xyz")
Assertions.assertThat(result).containsKey("/spaces/spaces_3.xyz")
Assertions.assertThat(result["/tabs.xyz"]?.metricMap).isNotEmpty
Assertions.assertThat(result.size).isEqualTo(5)
Assertions.assertThat(result).containsKey("/tabs.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_3.included")
Assertions.assertThat(result["/tabs.included"]?.metricMap).isNotEmpty
}

@Test
Expand All @@ -33,18 +33,59 @@ class MetricCollectorTest {
}

@Test
fun `Should exlude regex patterns`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, exclude = arrayOf(".*\\.xyz", "foobar")).parse()
fun `Should exclude regex patterns`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, exclude = arrayOf(".*\\.excluded$", "foobar")).parse()

Assertions.assertThat(result.size).isEqualTo(1)
Assertions.assertThat(result).containsKey("/spaces/spaces_xyz.wrong")
Assertions.assertThat(result.size).isEqualTo(4)
Assertions.assertThat(result).containsKey("/spaces/spaces_3.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_5.includedtoo")
Assertions.assertThat(result).doesNotContainKey("/spaces/spaces_x_not_included.excluded")
}

@Test
fun `Should include only spedified File extensions`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("wrong")).parse()
fun `Should include only specified File extension with one given`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("includedtoo")).parse()

Assertions.assertThat(result.size).isEqualTo(1)
Assertions.assertThat(result).containsKey("/spaces/spaces_xyz.wrong")
Assertions.assertThat(result).containsKey("/spaces/spaces_5.includedtoo")
Assertions.assertThat(result).doesNotContainKey("/spaces/spaces_3.included")
Assertions.assertThat(result).doesNotContainKey("tabs.included")
}

@Test
fun `Should include only specified File extensions with multiple given`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("included", "includedtoo")).parse()

Assertions.assertThat(result.size).isEqualTo(4)
Assertions.assertThat(result).containsKey("/spaces/spaces_3.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_4.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_5.includedtoo")
Assertions.assertThat(result).doesNotContainKey("/spaces/spaces_x_not_included.excluded")
}

@Test
fun `Should include all Files when no specific extensions were given (default for interactive mode)`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("")).parse()

Assertions.assertThat(result.size).isEqualTo(5)
Assertions.assertThat(result).containsKey("/spaces/spaces_x_not_included.excluded")
Assertions.assertThat(result).containsKey("/spaces/spaces_3.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_4.included")
Assertions.assertThat(result).containsKey("/spaces/spaces_5.includedtoo")
Assertions.assertThat(result).containsKey("/tabs.included")
}

@Test
fun `Should produce empty result if no valid file extensions were given`() {
val result = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("none")).parse()
Assertions.assertThat(result.size).isEqualTo(0)
}

@Test
fun `Should produce the same result whether the user included a dot in the filetype or not`() {
val resultWithoutDot = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf("included", "includedtoo")).parse()
val resultWithDot = MetricCollector(File("src/test/resources/sampleproject").absoluteFile, fileExtensions = arrayOf(".included", ".includedtoo")).parse()

Assertions.assertThat(resultWithoutDot == resultWithDot)
}
}
Loading
Loading