foundweekends / giter8

a command line tool to apply templates defined on GitHub
https://www.foundweekends.org/giter8/
Apache License 2.0
1.74k stars 224 forks source link

giter8 seems ignore hidden folder in `src` layout #401

Open chenrui333 opened 6 years ago

chenrui333 commented 6 years ago

I was trying to introduce the .github/ into my company's template repo, I found it got ignored.

I wonder if that is a bug or there is some workaround. Thanks!

AlvaroCaste commented 5 years ago

I would like to relight this issue to know an answer. Thanks :)

pme123 commented 4 years ago

Me too.

But I have a workaround.

Define the hidden folder like: $hidden$

Now add to the default.properties:

hidden=.idea

TonioGela commented 3 years ago

After more than a week of investigations, I've been able to shrink down the problem. Let's start noting that JGitIgnore uses FastIgnoreRule from the library org.eclipse.jgit.ssh.jsch.

I wrote this test, that is replicating the behaviour of one of my giter8 templates in which I have a .gitignore file that contains the string **/*/target/ and a .github folder (without a target folder inside ofc)

  it should "exclude hidden directories if a double asterisk rule is present" in {
    val rule = new FastIgnoreRule("**/*/target/")
    assert(rule.isMatch(".github/", true))
    assert(rule.getResult())
  }

Incredibly that test passes, and that means that according to the rule **/*/target/ the .github/ folder has to be excluded. In fact, the directory doesn't even have to be hidden to be excluded, the test passes with github/ too. I've tried investigating more and I found that .gitgnore rules are described here in the official doc and in particular they say:

    An asterisk "*" matches anything except a slash. [...]

Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:

    A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".

    A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.

    A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.

    Other consecutive asterisks are considered regular asterisks and will match according to the previous rules.

So, to the best of my understanding, the rule **/*/target/ should match directories named target under at least 1 level of nesting starting from the repository's root dir. My understanding is supported by this StackOverFlow answer btw.

After a lot of tests I might say that the behaviour of git itself matches this interpretation, while FastIgnoreRule of org.eclipse.jgit.ssh.jsch doesn't seem to.

Last but not least: git itself doesn't seem to care a lot about directories (in fact there's a famous trick to add a .gitkeep file in an empty dir to commit it). I'm saying this because in both FastIgnoreRule and giter8's JGitIgnore we are parsing and trying to match rules against directories, without caring about their "emptiness" status and I think that this may be the cause of the bugs.

PROBABLY, and I repeat probably, the thing can be solved by iterating just on files and trying to match the rules against them relying on the third parameter of isMatch by FastIgnore Rule:

public boolean isMatch(String path, boolean directory, boolean pathMatch)

that is documented as true if the match is for the full path

Now, for what concerns a workaround, since a while ago the support for the file .g8ignore is present and work like described in this comment, so placing a .g8ignore file in the root of the project (not under src/main/g8 but in the repo's root) and adding the line !.github/ will solve the issue flawlessly.

I promise that I'll add .g8ignore details in the documentation ASAP.

@chenrui333 @AlvaroCaste @pme123 I'll love to examine your templates in order to debug whether the "hidden folders" problem is related to the content of the .gitignore or to something else.