Skip to content

Better EditorConfig Settings & Code Styles Validation via Travis CI #6523

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

tajmone
Copy link
Contributor

@tajmone tajmone commented Jul 11, 2020

I've managed to revise the EditorConfig and gitattribute setting, as discussed in #6520.

So far, I've covered all the main file types of the repository, leaving out some extensions (HTML, XML, and autogenerated files) which either might not be so important to cover, or might display different code styles depending on context (e.g. XML files, which are present with multiple file extensions).

The list of covered file types:

  • Repository configurations (Git settings, EditorConfig, and CI services)
  • Shell scripts
  • Make files
  • Haskell sources
  • Markdown docs (as discussed in Improve EditorConfig Settings #6520, and excluding test/ folder)
  • Lua and Perl scripts

I've unset validation rules for any files inside the test/ folder, to allow testing edge cases and malformed sources.

A few cosmetic tweaks to some sources were required (indentations, etc.) to pass Travis CI validation via EClint, and now all tests pass.

I'd like the PR to be reviewed, to ensure that no important extensions are being left out from the settings, and that the current configuration is fine.

Also, we might need to decide if we should squash this PR into a single commit or keep each commit separate (I opt for the latter, for it provide a more readable history regarding the source tweaks that enforce code styles, on a per-type basis).

tajmone added 16 commits July 11, 2020 16:07
Update `.editorconfig` and `.gitattributes` files to enforce code styles
conventions for repository settings files (Git, EditorConfig and various
`.*.yml` used by CI services).

Comment out the original `.editorconfig` settings to allow working on
one file type at the time.
Update `.editorconfig` and `.gitattributes` files to enforce code styles
conventions for Makefiles.
Fix spaces indentations to tabs in some `Makefile`s to enforce the new
EditorConfing settings.
Update `.editorconfig` and `.gitattributes` files to enforce code styles
conventions for shell scripts (`LF` EOL, tab indentation).
Fix spaces indentations to tabs in some shell script to enforce the new
EditorConfing settings.

Also update mod of shell script to executable, for Windows Git users.
Setup Travis CI to validate that all commits and PRs comply to the code
style conventions of EditorConfig settings, using EClint for validation
via a custom `validate.sh` script.
Add to `.gitattributes` settings `* text=auto` to set enable text-files
autodetection, in case users don't have `core.autocrlf` set.

Move `test/fb2/reader/* -text` rule to file end, to ensure correct
overriding.
Update `.editorconfig` to enforce code styles conventions for Haskell
sources: indent using spaces, but `indent_size = unset` to allow custom
alignments (i.e. odd indentations) during code validation.
Remove trailing spaces in a source file to enforce the new EditorConfing
settings.
Update `.editorconfig` to enforce code styles conventions for Perl.
Fix indentation of Perl source (two lines) to a multiple of 2, to enforce
the new EditorConfing settings.
Update `.editorconfig` to enforce code styles conventions for Lua.
Fix some indentations in Lua sources to enforce EditorConfing settings.
Update `.editorconfig` to enforce code styles conventions for markdown
files, except in `test/` folder.

Unset all EditorConfig rules for files inside `test/` folder.
Fix tabs to spaces in a couple of markdown docs to enforce EditorConfing
settings.
Remove old commented out settings from `.editorconfig`.
Reorder settings in a consistent way.
Copy link
Collaborator

@tarleb tarleb left a comment

Choose a reason for hiding this comment

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

Thank you for this! I don't know enough about gitattributes, but the editorconfig changes and validation look really good to me.
@jgm has to make the final decision.

charset = utf-8
end_of_line = unset
indent_style = space
indent_size = unset
trim_trailing_whitespace = false
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're not using trailing spaces anywhere, might be ok to set this to true.

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 personally never use trailing spaces for hard line-breaks, but we need to check with @jgm for this setting, after all GFM does support that feature so potentially it could be used in the GFM documentation or templates, and if I remember correctly pandoc also supports the feature via extensions.

I always set trim_trailing_whitespace to true in my projects, because trailing space are the main cause of commits "noise", leading to hard-to-read diffs and (often) spurious contents changes.

Copy link
Owner

Choose a reason for hiding this comment

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

I'm sure there are tests that include trailing whitespace, even if we don't use it in documentation (and for all I recall, we might).

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've revised the rules for test/ folder in commit 6080aeb, so they apply to markdown files only — basically the only checks now are for UTF-8 encoding and EOL consistency, all other rules are dropped to allow testing edge-cases (including trailing spaces).

even if we don't use it in documentation (and for all I recall, we might).

I've checked. the only markdown file with trailing spaces is COPYING.md, which contains some trailing spaces that are just spurious and could actually be removed.

So, @jgm, should we set the rules for markdown files outside the test/ folder to forbid trailing WS? (and cleanup the COPYING.md doc)

Unless we need to use them in the documentation, it would prevent unclean commits.

charset = utf-8
end_of_line = unset
indent_style = space
indent_size = unset
Copy link
Collaborator

Choose a reason for hiding this comment

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

The general coding style uses two spaces, but Haskell indentation is weird sometimes. Does verification fail if we set this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it would fail because the validator tool expects all indentation to be a multiple of the base value. Unfortunately the EditorConfig project doesn't offer separate settings for editor/IDEs configurations and validators right now.

Since most coders add extra spaces to obtain elegant alignments on code that spans multiple lines, it often becomes necessary to either unset indent_size or set it to 1 — the former is better because it doesn't override the editor's defaults, whereas the latter would actually enforce 1-space tabs.

As for markdown (and other lightweight markup syntaxes) the problem affect code blocks, which could be using even or odd indentation, depending on the language snippet being included.

Hopefully in future editions of EditorConfig we'll see new settings to address validation aspects only. Right now, one is forced to compromise on some features to obtain both editor settings and CI validation — e.g. EditorConfig doesn't (and will never) support end_of_line = native, so to allow cross-platform EOL normalization end_of_line has to be unset and the project has to rely on .gitattributes instead.

I'll take a further look at EClint's documentation, there are some ways to customize validation settings and overriding the .editorconfig values via a separate config file for EClint; if this is the case, we could enforce 2-spaces on the editor and override it on EClint by unsetting indent_size for some file types. It might require some time for me to dig into it and test it, but in the meantime we could use these settings for they are fairly good in practical use, from my own experience (you get a sound validation and don't interfere with the editor/IDE).

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've checked EClint documentation, and there's no easy way to override .editorconfig settings on a per-file-type manner (you can override options globally for each run). The only alternative would be to run multiple EClint checks, each targetting a specific file extension, but it seems an overkill solution.

.editorconfig Outdated

## Test Files
#############
[test/**]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I just realized that we still want the general rules to apply for Haskell and Lua files in test. Should we move those rules further down, or is there a better way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we should apply the above pattern only to markdown files?

## Test Files
#############
[test/**.{md,markdown}]

After all, I believe that is only the markdown files that need relaxed rules to allow testing edge-cases and malformed documents.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6080aeb!

@@ -0,0 +1,15 @@
dist: trusty
Copy link
Collaborator

Choose a reason for hiding this comment

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

If I understand correctly, then this is a temporary solution and would be converted into a GitHub Action workflow after merging?

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 leave that choice to you, as you're surely more qualified to decide on this.

Personally, I always use Travis for code validation, to avoid bumping into the free GH Actions limits (since validation is done for every commit on every branch, having many repositories could quickly reach the limit).

Another reason to keep it on Travis (instead of Circle or GH Actions) might be performance, since it would run in a parallel job.

Copy link
Owner

Choose a reason for hiding this comment

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

I'd like to avoid using multiple CI providers; if we can do it all in GH actions that seems better to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a ready availabe EClint action:

https://github.com/marketplace/actions/eclint

I haven't use GH Actions before, some I'm not sure how to set it up. Can someone else add the action?

@@ -143,12 +143,12 @@ end

function Link(s, src, tit, attr)
return "<a href='" .. escape(src,true) .. "' title='" ..
escape(tit,true) .. "'>" .. s .. "</a>"
escape(tit,true) .. "'>" .. s .. "</a>"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand most of the changes in this file. Does validation fail without them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it fails because in this case the setting is 2 spaces, so all indentation needs to be a multiple of 2 (i.e. odd spacing).

All the (cosmetic) changes I've done to the sources were due to validations errors.

@@ -8,11 +8,11 @@
# is the directory, and pandoc is used from path.

if [ $# -eq 2 ]; then
PANDOC=$1
DIR=$2
PANDOC=$1
Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed!

{Para = function (p) table.insert(acc, p.content[1].text) end}
)
assert.are_equal('1234', table.concat(acc))
local acc = {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

These should be indented by two additional spaces.

Copy link
Contributor Author

@tajmone tajmone Jul 12, 2020

Choose a reason for hiding this comment

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

Commit 5bdf167 should fix this (hopefully).

[*.sh]
charset = utf-8
end_of_line = lf
indent_style = tab
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 are using 4 spaces, at least that's what I've been using. But I might be wrong and I am ok with either.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To the best of my knowledge, shell scripts should use tabs only for indentation, because spaces indents could lead to problems in some contexts — the matter is subject of dispute (as everything relating to the tabs-vs-space flamewars) but this seems to be the prevalent opinion, at least on long StackOverflow discussions.

But I'll set it to any value you suggest, the most important thing is to keep the code consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason why tabs are preferable is in case shell scripts are used to dynamically generate other scripts via pipes and redirections, where tabs are a safer option because common used tools will auto-strip leading tabs (but not spaces).

An example:

https://www.howtobuildsoftware.com/index.php/how-do/ctWc/shell-sh-perforce-error-in-creating-p4-label-non-interactively-as-part-of-shell-script

Beside that, it boils down to a matter of personal choice (and the many flamewars on the subject didn't really bring any solution to the issue). I personally prefer using spaces in version controlled projects, for they create more readable diffs. But since in Make files tabs are mandatory, and shell scripts are sometimes used to manipulate Make files, I prefer to adopt tabs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some interesting trivia on the subject:

So, yes, I'm for spaces-indentation, but make an exception for shell scripts.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting, I didn't know. Thanks!

tajmone added 2 commits July 12, 2020 12:36
Fix excessive indentation in `test/grofftest.sh`.
Adjust indentation in `test/lua/module/pandoc.lua`.
@jgm
Copy link
Owner

jgm commented Jul 13, 2020

I'm not sure about the impact of all these changes. What if someone edits a template and this adds CRLF line endings, and then runs tests and the tests fail to pass because the golden tests have LF line endings? We don't want that.

Apply relaxed rules in `test/` folder to markdown files only.
@tajmone
Copy link
Contributor Author

tajmone commented Jul 13, 2020

What if someone edits a template and this adds CRLF line endings, and then runs tests and the tests fail to pass because the golden tests have LF line endings? We don't want that.

Currently the EditorConfig settings are enforcing only LF EOL for repository configuration files, Make files and shell scripts; all other text files EOLs are set to native via Git attributes and are being ignored by the EditorConfig validator.

Of course, Git will prevent commits in case of inconsistent EOLs.

@tarleb
Copy link
Collaborator

tarleb commented Jul 13, 2020

I honestly don't understand why, but the tests still pass even after running unix2dos data/templates/*.

@tajmone
Copy link
Contributor Author

tajmone commented Jul 13, 2020

I honestly don't understand why, but the tests still pass even after running unix2dos data/templates/*.

Because EditorConfig doesn't support the native value for line-ending settings:

There's been a long debate on the lack of this feature, but (to make it short) the official response is that "native" is not acceptable as an EditorConfig definition, so it won't be implemented.

So when working with Git repos that allow native EOL normalization (which should be the default) you simply have to disable EOL consistency in EditorConfig: end_of_line = unset.

Beside those file-types which need to enforce a specific EOL type, we're relying on .gitattributes for checking native EOL consistency at commit time.
Which is why running unix2dos/dos2unix locally won't fail the validation test — but Git should refuse a commit which would introduce wrong or inconsistent EOLs. So it's safe to rely on.

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.

3 participants