Skip to content

Commit 1d68d9b

Browse files
flow: add --all-external-dependencies-file-path build option
1 parent 2305f51 commit 1d68d9b

8 files changed

Lines changed: 102 additions & 2 deletions

File tree

znai-cli/src/main/java/org/testingisdocumenting/znai/cli/ZnaiCliApp.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.nio.file.Path;
4646
import java.nio.file.Paths;
4747
import java.time.Instant;
48+
import java.util.stream.Collectors;
4849
import java.util.stream.Stream;
4950

5051
public class ZnaiCliApp {
@@ -97,6 +98,7 @@ private void start() {
9798
if (needsDocGeneration()) {
9899
webSite = generateDocs(config.getSourceRoot());
99100
exportLlmTxtIfNeeded();
101+
exportAllExternalDepsIfNeeded();
100102
}
101103

102104
if (config.isPreviewMode()) {
@@ -166,6 +168,38 @@ public void printOutsideDeps() {
166168
.forEach(System.out::println);
167169
}
168170

171+
private void exportAllExternalDepsIfNeeded() {
172+
Path allExternalDepsFilePath = config.getAllExternalDepsFilePath();
173+
if (allExternalDepsFilePath == null) {
174+
return;
175+
}
176+
177+
ProgressReporter.reportPhase("exporting all external dependencies");
178+
ConsoleOutputs.out("creating ", Color.PURPLE, allExternalDepsFilePath);
179+
180+
String content = sortedExternalDependenciesRelativePaths()
181+
.collect(Collectors.joining("\n"));
182+
183+
FileUtils.writeTextContent(allExternalDepsFilePath, content);
184+
}
185+
186+
private Stream<String> sortedExternalDependenciesRelativePaths() {
187+
Path sourceRoot = config.getSourceRoot();
188+
189+
Stream<String> insideDocPaths = webSite.getAuxiliaryFilesRegistry().getAllPaths()
190+
.filter(fullPath -> fullPath.startsWith(sourceRoot))
191+
.map(fullPath -> sourceRoot.relativize(fullPath).toString())
192+
.filter(relativePath -> !relativePath.endsWith(".md"));
193+
194+
Stream<String> outsideDocPaths = webSite.getOutsideDocsRequestedResources().entrySet().stream()
195+
.filter(e -> webSite.isLocalFile(e.getKey()))
196+
.map(e -> sourceRoot.relativize(e.getValue()).toString());
197+
198+
return Stream.concat(insideDocPaths, outsideDocPaths)
199+
.distinct()
200+
.sorted();
201+
}
202+
169203
private void exportLlmTxtIfNeeded() {
170204
Path llmTxtOutputPath = config.getLlmTxtOutputPath();
171205
if (llmTxtOutputPath == null) {

znai-cli/src/main/java/org/testingisdocumenting/znai/cli/ZnaiCliConfig.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public enum OptionKey {
9393

9494
DOC_ID("doc-id", "documentation id", true, false),
9595
LLM_TXT_OUTPUT_PATH("llm-txt-output-path", "save llm.txt to specified path during build", true, false),
96+
ALL_EXTERNAL_DEPS_FILE_PATH("all-external-dependencies-file-path", "save all external file dependencies to specified path during build", true, false),
9697

9798
EXPORT("export", "export destination directory", true, false),
9899

@@ -156,6 +157,7 @@ public boolean hasMultipleArgs() {
156157
buildOptions.add(OptionKey.DOC_ID);
157158
buildOptions.add(OptionKey.DEPLOY);
158159
buildOptions.add(OptionKey.LLM_TXT_OUTPUT_PATH);
160+
buildOptions.add(OptionKey.ALL_EXTERNAL_DEPS_FILE_PATH);
159161
COMMAND_OPTIONS.put(Command.BUILD, buildOptions);
160162

161163
Set<OptionKey> exportOptions = EnumSet.copyOf(commonOptions);
@@ -234,6 +236,7 @@ public enum ModifiedTimeStrategy {
234236
private String actor;
235237
private List<String> lookupPaths;
236238
private Path llmTxtOutputPath;
239+
private Path allExternalDepsFilePath;
237240

238241
private boolean isValidateExternalLinks;
239242

@@ -350,6 +353,10 @@ public Path getLlmTxtOutputPath() {
350353
return llmTxtOutputPath;
351354
}
352355

356+
public Path getAllExternalDepsFilePath() {
357+
return allExternalDepsFilePath;
358+
}
359+
353360
public Path getDeployRoot() {
354361
return validateIsSet("deployRoot", deployRoot);
355362
}
@@ -368,6 +375,9 @@ public void print() {
368375
if (getLlmTxtOutputPath() != null) {
369376
print("llm txt output path", llmTxtOutputPath);
370377
}
378+
if (getAllExternalDepsFilePath() != null) {
379+
print("all external deps file path", allExternalDepsFilePath);
380+
}
371381
} else if (isExportMode()) {
372382
print("source root", sourceRoot);
373383
print("export root", exportRoot);
@@ -452,6 +462,10 @@ private void parseArgs(String[] args) {
452462
Paths.get(commandLine.getOptionValue(OptionKey.LLM_TXT_OUTPUT_PATH.getKey())).toAbsolutePath() :
453463
null;
454464

465+
allExternalDepsFilePath = commandLine.hasOption(OptionKey.ALL_EXTERNAL_DEPS_FILE_PATH.getKey()) ?
466+
Paths.get(commandLine.getOptionValue(OptionKey.ALL_EXTERNAL_DEPS_FILE_PATH.getKey())).toAbsolutePath() :
467+
null;
468+
455469
modifiedTimeStrategy = determineModifiedTimeStrategy(commandLine);
456470

457471
validateMode(commandLine);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* Add: `--all-external-dependencies-file-path=/tmp/external-dependendies.txt` option to list all the external dependencies
2+
used during build.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
# Target
22

33
This is the target page.
4+
5+
:include-file: config.json
6+
7+
:include-file: utils.js
8+
9+
:include-file: app.config
10+
11+
:include-file: schema.graphql
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
../doxygen.zip
1+
../doxygen.zip
2+
../doc-artifacts
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# File Outside
22

3-
Files don't have to belong to chapters if you have simple docs
3+
Files don't have to belong to chapters if you have simple docs
4+
5+
:include-file: chapter-two/sample.py
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2026 znai maintainers
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package scenarios
18+
19+
import static clicommands.CliCommands.getZnai
20+
import static org.testingisdocumenting.webtau.WebTauGroovyDsl.*
21+
22+
scenario('build sampledoc with all external dependencies file') {
23+
def depsFilePath = fs.tempDir('znai-deps').resolve('all-external-deps.txt')
24+
def deployRoot = fs.tempDir('znai-deploy')
25+
26+
znai.run("build --doc-id test-doc --deploy $deployRoot " +
27+
"--source=${cfg.fullPath('sampledoc')} " +
28+
"--all-external-dependencies-file-path $depsFilePath")
29+
30+
fs.textContent(depsFilePath).should == '../doc-artifacts/app.config\n' +
31+
'../doc-artifacts/schema.graphql\n' +
32+
'chapter-one/config.json\n' +
33+
'chapter-two/sample.py\n' +
34+
'utils.js'
35+
}

znai-website-gen/src/main/java/org/testingisdocumenting/znai/website/WebSite.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ public Map<String, Path> getOutsideDocsRequestedResources() {
174174
return resourceResolver.getOutsideDocRequestedResources();
175175
}
176176

177+
public boolean isLocalFile(String path) {
178+
return resourceResolver.isLocalFile(path);
179+
}
180+
177181
public void parseAndDeploy() {
178182
parse();
179183
deploy();

0 commit comments

Comments
 (0)