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

Improve CLI output name handling by adding file extensions #2914

Merged

Conversation

charlotteKehm
Copy link
Contributor

@charlotteKehm charlotteKehm commented Jul 27, 2022

{Meaningful title}

Please read the CONTRIBUTING.md before opening a PR.

Issue: #2800 Improving CLI output name handling by adding file extensions if necessary

Description

Descriptive pull request text, answering:

  • What problem/issue are you fixing?
  1. if the user enters no outputfile, then a default output file is created
  2. every outputfile is checked if it has the ending .cc.json. if it does not have the ending, it is automatically inserted (has been implemented in a static/object class OutputFileHandler.kt
  3. In order to run golden_test.sh and TokeiImporterTest.kt properly the variable systemout has been introduced to enable console output
  • What does this PR implement and how?
  • Open issues:
  1. golden_test.sh needs to be updated. Importers that are being used in production aren't tested there (e.g. metricgardener, gitlog...). Importers that are not used in production are tested there (eg. crococosmo)
  2. A Decision has to be made about the default behavior of the outputfilehandling: If an outputfile shall be generated, then several issues need to be considered: conditions for serializing the project, is there a more elegant way to run the tests than using the variable systemout,
  3. Raw Text Parser needs to be adjusted
  4. It would be nice if the logic of OutputFileHandler would be transferred to the interface ParserDialogInterface
  5. build.gradle: task integrationtest: It is not possible to run the integrationtests on a windows notebook without having wsl enabled (via bash). All operating systems need to be considered, hence it is always possible to run the integration tests locally.

Screenshots or gifs

Comment on lines 13 to 17
if (outputName.isEmpty()) return "default.cc.json"
val delimiter = extractDelimiter(outputName)
if (delimiter.isEmpty()) {
return outputName.substringBefore(".") + ".cc.json"
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that the code style has not been formatted automatically.
I recommend to always add curly braces even for if-statements with one line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am using the gradle target ktlintFormat and have enabled the codestyle.xml in my intellij-settings.
I have seen in multiple files that curly braces are not used in if - statements with one line, for instance TokeiImporter.kt and assumed it would be a convention. Do I misunderstand something?
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything is fine :) There are a lot of if statements without curly braces from the past. I think we discussed this for the visualization. We agreed to use curly braces for new code there. I think we should also do it in analysis part. But this is just a minor remark.

if (outputName.isEmpty()) return "default.cc.json"
val delimiter = extractDelimiter(outputName)
if (delimiter.isEmpty()) {
return outputName.substringBefore(".") + ".cc.json"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work if multiple dots are provided in the fileName like: "my.output.name". This would lead to my.cc.json which would not be correct. Instead you can use substringBeforeLast.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ce-bo We were considering using substringBeforeLast. If you are providing a file name such as "test.cc.json", this would lead to test.cc.cc.json which would also be incorrect. Therefore we decided that by convention fileNames do not involve dots.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricting the filename would not be intuitive. So let's not do this.
In case of "test.cc.json" we can simply check if "cc.json" is included or not. If yes, stop filename processing, if not, continue.

}

private fun extractPath(outputName: String, delimiter: String): String {
return outputName.split(delimiter).dropLast(1).joinToString(delimiter) + delimiter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefere existing Utility functions (examples: https://mkyong.com/java/how-to-get-the-filepath-of-a-file-in-java/).
Thus, different operating system depending pathes are handled automatically.

}

private fun extractFileName(outputName: String, delimiter: String): String {
val fileName = outputName.split(delimiter).reversed().get(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would do the same like in comment

private fun extractFileName(outputName: String, delimiter: String): String {
val fileName = outputName.split(delimiter).reversed().get(0)
if (fileName.isEmpty()) {
return "default.cc.json"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create a constant for "default.cc.json" string.

if (fileName.isEmpty()) {
return "default.cc.json"
}
return fileName.substringBefore(".") + ".cc.json"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use substringBeforeLast instead.

@@ -22,7 +22,7 @@ class ProjectGenerator(private val writer: Writer, private val filePath: String,
project = MergeFilter.mergePipedWithCurrentProject(pipedProject, project)
}

if (toCompress && filePath != "notSpecified") {
if (toCompress && filePath != "default.cc.json") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add/reuse the constant for default.cc.json

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not find any file of constants in the project. Ist there one? Otherwise I would suggest to start one for all the importers (hence, in the directory: import).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think YAGNI. Let's start with just one constant in the ProjectGenerator or in the OutputFileHandler.

BufferedWriter(FileWriter(outputFile!!))
} else {
OutputStreamWriter(output)
if (!test) {
Copy link
Collaborator

@ce-bo ce-bo Aug 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this condition only for debugging? What is variable test used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no this is for executing the parser dialog tests. previously the default condition was to write the output in terminal. now a default file is created. during the build it would not be convenient to generate all the default files (also many tests would need to be corrected) therefore we still write the output of .jsons during the build in terminal.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not change code only to be able to run unit tests properly. Why has the default behavior changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see your point, but I thought the requirement was if the user does not enter any input into the interactive terminal we still create a default cc.json file in the working directory.

Copy link
Collaborator

@ce-bo ce-bo Aug 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay. I think this is not included in the scope of this issue. Now it is a bit mixed.
I would rather name the default something like this INPUT-FILE-NAME-output.cc.json. But ideally we should change this in a separate PR. Currently the default output name is handled in de.maibornwolff.codecharta.tools.interactiveparser.ParserDialogInterface#getOutputFileName and simply the input file name is used as the default output filename. But it seems that not all parsers/importers are using this method.

@charlotteKehm
Copy link
Contributor Author

@ce-bo I resolved your remarks in my latest commit.
I happen to have a problem with sonarcloud code coverage, because it highlights code as uncoverd I haven't written. These are in my opinion legacy issues and I am not sure how we shall deal with them.

Comment on lines 44 to 48
/**
private fun writer(): Writer {
return outputFile?.writer() ?: System.out.writer()
}

**/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this.

@ce-bo
Copy link
Collaborator

ce-bo commented Aug 3, 2022

Let‘s Not change the default behavior when the User does not provide a output file name. Thus, the new systemout flag is not needed to be added in every parser. In the Parser Dialog Interface, I think it is called InteractiveParser or similar, we can extend the method for providing the output file, so that the correct file ending is added if necessary. We can suggest a default Output file Name to the user in the interactive usage but the User should still be possible to not set any Output file name, so that the results are going to be dumped to System.out.

@Chrisp485
Copy link
Contributor

@ce-bo Sorry I'm still a bit confused. Do we want to achieve the following two Cases?

  1. Users doesn't specify a filename -> The output gets written into stdout
  2. User enters an filename -> We just check if the fileextension exists/ is correct, else we add or correct it.

So the changes with the sysout flag need to be removed again and move the functionality of the new OutputFileHandler into the ParserDialogInterface?

@ce-bo
Copy link
Collaborator

ce-bo commented Aug 3, 2022

Yes, that is what I ment. Moving the OutputFileHandler can be checked. I did not have a deep look into that.

@MW-Friedrich MW-Friedrich changed the title FileExtensionHandler added + Tests #2800 Improve CLI output name handling by adding file extensions Aug 10, 2022
Refactor/simplify CrococosmoImporter, so it handles suffixes properly
Enhance tests for Crococosmo and MetricGardener
#2800
…me-by-adding-file-extensions' into fix/2800/improving-cli-output-name-by-adding-file-extensions
…me-by-adding-file-extensions' into fix/2800/improving-cli-output-name-by-adding-file-extensions
…me-by-adding-file-extensions' into fix/2800/improving-cli-output-name-by-adding-file-extensions
Add more tests for MergeFilter
#2800
Refactor all Importers/Parsers for more consistent line breaks
#2800
@sonarcloud
Copy link

sonarcloud bot commented Aug 17, 2022

[CodeCharta Analysis] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

81.2% 81.2% Coverage
0.0% 0.0% Duplication

@sonarcloud
Copy link

sonarcloud bot commented Aug 17, 2022

[CodeCharta Visualization] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

Copy link
Collaborator

@phanlezz phanlezz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets get this merged! 🚀

@MW-Friedrich MW-Friedrich merged commit e8d52b5 into main Aug 17, 2022
@MW-Friedrich MW-Friedrich deleted the fix/2800/improving-cli-output-name-by-adding-file-extensions branch August 17, 2022 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improving CLI output name handling by adding file extensions if necessary
6 participants