diff --git a/README.md b/README.md index dc4f2e1..feb04f8 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,15 @@ You may want to statically upload the contents of a folder. For example maybe th **Caveat**: To ignore files the `.kickflipignore` file must be present IN the folder. +### .kickflipignore + +One glob per line. A line starting with `!` re-includes files another pattern ignored, e.g. ignore all dotfiles but still deploy `.htaccess`: + + .* + !.htaccess + +Unlike `.gitignore`, order doesn't matter: a `!` pattern always wins. + ### Pull request comments Kickflip can post a summary of the changes that will be deployed as a comment on a pull request: diff --git a/src/kickflip.Tests/IgnoreServiceTests.cs b/src/kickflip.Tests/IgnoreServiceTests.cs index 2a6a51a..5f338b1 100644 --- a/src/kickflip.Tests/IgnoreServiceTests.cs +++ b/src/kickflip.Tests/IgnoreServiceTests.cs @@ -27,6 +27,20 @@ public void IsIgnored_HonoursPatternsInIgnoreFile() Assert.False(service.IsIgnored("index.html")); } + [Fact] + public void IsIgnored_NegatedPatternReincludesFile() + { + using var directory = new TempDirectory(); + directory.WriteFile(".kickflipignore", ".*\n!.htaccess\n!.user.ini"); + var service = new IgnoreService(directory.Path); + + Assert.True(service.IsIgnored(".env")); + Assert.False(service.IsIgnored(".htaccess")); + Assert.False(service.IsIgnored(".user.ini")); + Assert.False(service.IsIgnored("index.php")); + Assert.True(service.IsIgnored(".kickflipignore")); + } + [Fact] public void IsIgnored_AlwaysIgnoresTheIgnoreFileItself() { diff --git a/src/kickflip/Services/IgnoreService.cs b/src/kickflip/Services/IgnoreService.cs index fddb1df..c862bb4 100644 --- a/src/kickflip/Services/IgnoreService.cs +++ b/src/kickflip/Services/IgnoreService.cs @@ -17,8 +17,18 @@ public IgnoreService(string localPath) return; } - var ignorePatterns = File.ReadAllLines(ignoreFile); - _matcher.AddIncludePatterns(ignorePatterns); + foreach (var pattern in File.ReadAllLines(ignoreFile)) + { + // "!pattern" re-includes files an earlier pattern ignored; unlike .gitignore, order doesn't matter + if (pattern.StartsWith('!')) + { + _matcher.AddExclude(pattern[1..]); + } + else + { + _matcher.AddInclude(pattern); + } + } } public bool IsIgnored(string path)