Skip to content

Commit f832c43

Browse files
timtebeekTim te Beek
andauthored
Only update .gitignore when context files were actually generated (#9)
* Only update .gitignore when context files were actually generated Converts UpdateGitignore from Recipe to ScanningRecipe that first checks whether any .moderne/context/ files exist. If no context files were generated (e.g. no supported frameworks detected), .gitignore is left unchanged, eliminating noisy gitignore-only diffs. Fixes moderneinc/customer-requests#1992 * Polish --------- Co-authored-by: Tim te Beek <tim@device-97.home>
1 parent 329e08c commit f832c43

File tree

2 files changed

+114
-6
lines changed

2 files changed

+114
-6
lines changed

src/main/java/org/openrewrite/prethink/UpdateGitignore.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,27 @@
1717

1818
import lombok.EqualsAndHashCode;
1919
import lombok.Value;
20-
import org.openrewrite.ExecutionContext;
21-
import org.openrewrite.Recipe;
22-
import org.openrewrite.TreeVisitor;
20+
import org.jspecify.annotations.Nullable;
21+
import org.openrewrite.*;
2322
import org.openrewrite.text.PlainText;
2423
import org.openrewrite.text.PlainTextVisitor;
2524

2625
import java.nio.file.Path;
2726
import java.nio.file.Paths;
27+
import java.util.concurrent.atomic.AtomicBoolean;
2828
import java.util.regex.Matcher;
2929
import java.util.regex.Pattern;
3030

31+
import static org.openrewrite.prethink.Prethink.CONTEXT_DIR;
32+
3133
/**
3234
* Updates .gitignore to allow committing the .moderne/context/ directory while
3335
* ignoring other files in .moderne/.
3436
* <p>
37+
* This recipe only modifies .gitignore when context files actually exist in
38+
* .moderne/context/. If no context files were generated (e.g. no supported
39+
* frameworks detected), .gitignore is left unchanged.
40+
* <p>
3541
* This recipe transforms:
3642
* <pre>
3743
* .moderne/
@@ -46,7 +52,7 @@
4652
*/
4753
@Value
4854
@EqualsAndHashCode(callSuper = false)
49-
public class UpdateGitignore extends Recipe {
55+
public class UpdateGitignore extends ScanningRecipe<AtomicBoolean> {
5056

5157
private static final Path GITIGNORE_PATH = Paths.get(".gitignore");
5258

@@ -64,11 +70,36 @@ public class UpdateGitignore extends Recipe {
6470
String displayName = "Update .gitignore for Prethink context";
6571

6672
String description = "Updates .gitignore to allow committing the `.moderne/context/` directory while " +
67-
"ignoring other files in `.moderne/`. Transforms `.moderne/` into `.moderne/*` " +
73+
"ignoring other files in `.moderne/`. Only modifies .gitignore when context files exist " +
74+
"in `.moderne/context/`. Transforms `.moderne/` into `.moderne/*` " +
6875
"with an exception for `!.moderne/context/`.";
6976

7077
@Override
71-
public TreeVisitor<?, ExecutionContext> getVisitor() {
78+
public AtomicBoolean getInitialValue(ExecutionContext ctx) {
79+
return new AtomicBoolean(false);
80+
}
81+
82+
@Override
83+
public TreeVisitor<?, ExecutionContext> getScanner(AtomicBoolean contextFilesExist) {
84+
return new TreeVisitor<Tree, ExecutionContext>() {
85+
@Override
86+
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
87+
if (tree instanceof SourceFile && !contextFilesExist.get()) {
88+
Path path = ((SourceFile) tree).getSourcePath();
89+
if (path.startsWith(CONTEXT_DIR)) {
90+
contextFilesExist.set(true);
91+
}
92+
}
93+
return tree;
94+
}
95+
};
96+
}
97+
98+
@Override
99+
public TreeVisitor<?, ExecutionContext> getVisitor(AtomicBoolean contextFilesExist) {
100+
if (!contextFilesExist.get()) {
101+
return TreeVisitor.noop();
102+
}
72103
return new PlainTextVisitor<ExecutionContext>() {
73104
@Override
74105
public PlainText visitText(PlainText text, ExecutionContext ctx) {

src/test/java/org/openrewrite/prethink/UpdateGitignoreTest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ void replacesModerneDirectoryPattern() {
5757
.idea/
5858
""",
5959
spec -> spec.path(".gitignore")
60+
),
61+
text(
62+
"context",
63+
spec -> spec.path(".moderne/context/architecture.md")
6064
)
6165
);
6266
}
@@ -84,6 +88,10 @@ void addsPatternWhenNoModerneEntry() {
8488
!.moderne/context/
8589
""",
8690
spec -> spec.path(".gitignore")
91+
),
92+
text(
93+
"context",
94+
spec -> spec.path(".moderne/context/architecture.md")
8795
)
8896
);
8997
}
@@ -108,6 +116,10 @@ void addsExceptionWhenWildcardExistsWithoutException() {
108116
!.moderne/context/
109117
""",
110118
spec -> spec.path(".gitignore")
119+
),
120+
text(
121+
"context",
122+
spec -> spec.path(".moderne/context/architecture.md")
111123
)
112124
);
113125
}
@@ -125,6 +137,10 @@ void noChangeWhenAlreadyCorrect() {
125137
!.moderne/context/
126138
""",
127139
spec -> spec.path(".gitignore")
140+
),
141+
text(
142+
"context",
143+
spec -> spec.path(".moderne/context/architecture.md")
128144
)
129145
);
130146
}
@@ -136,6 +152,63 @@ void handlesModerneWithoutTrailingSlash() {
136152
"# Moderne\n.moderne\n",
137153
"# Moderne\n.moderne/*\n!.moderne/context/\n",
138154
spec -> spec.path(".gitignore")
155+
),
156+
text(
157+
"context",
158+
spec -> spec.path(".moderne/context/architecture.md")
159+
)
160+
);
161+
}
162+
163+
@Test
164+
void updatesGitignoreWhenContextFilesExist() {
165+
rewriteRun(
166+
text(
167+
"""
168+
# Build
169+
build/
170+
171+
# Moderne
172+
.moderne/
173+
174+
# IDE
175+
.idea/
176+
""",
177+
"""
178+
# Build
179+
build/
180+
181+
# Moderne
182+
.moderne/*
183+
!.moderne/context/
184+
185+
# IDE
186+
.idea/
187+
""",
188+
spec -> spec.path(".gitignore")
189+
),
190+
text(
191+
"some context content",
192+
spec -> spec.path(".moderne/context/architecture.md")
193+
)
194+
);
195+
}
196+
197+
@Test
198+
void noChangeWhenNoContextFilesExist() {
199+
rewriteRun(
200+
text(
201+
"""
202+
# Build
203+
build/
204+
205+
# Moderne
206+
.moderne/
207+
208+
# IDE
209+
.idea/
210+
""",
211+
spec -> spec.path(".gitignore")
139212
)
140213
);
141214
}
@@ -150,6 +223,10 @@ void doesNotModifyOtherGitignores() {
150223
.moderne/
151224
""",
152225
spec -> spec.path("subdir/.gitignore")
226+
),
227+
text(
228+
"context",
229+
spec -> spec.path(".moderne/context/architecture.md")
153230
)
154231
);
155232
}

0 commit comments

Comments
 (0)