-
Notifications
You must be signed in to change notification settings - Fork 35
/
GenerateSiteCommand.kt
146 lines (129 loc) · 5.48 KB
/
GenerateSiteCommand.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
@file:OptIn(ExperimentalCli::class)
package nl.avisi.structurizr.site.generatr
import kotlinx.cli.*
import nl.avisi.structurizr.site.generatr.site.*
import java.io.File
class GenerateSiteCommand : Subcommand(
"generate-site",
"Generate a site for the selected workspace."
) {
private val gitUrl by option(
ArgType.String, "git-url", "g",
"The URL of the Git repository which contains the Structurizr model. " +
"If a Git repository is provided, it will be cloned and" +
"--workspace-file and --assets-dir will be treated as paths within the cloned repository. " +
"If no Git repository is provided, --workspace-file and --assets-dir will be used as-is, and the site" +
"will only contain one branch, named after the --default-branch option."
)
private val gitUsername by option(
ArgType.String, "git-username", "u",
"Username for the Git repository"
)
private val gitPassword by option(
ArgType.String, "git-password", "p",
"Password for the Git repository"
)
private val workspaceFile by option(
ArgType.String, "workspace-file", "w",
"Relative path within the Git repository of the workspace file"
).required()
private val assetsDir by option(
ArgType.String, "assets-dir", "a",
"Relative path within the Git repository where static assets are located"
)
private val branches by option(
ArgType.String, "branches", "b",
"Comma-separated list of branches to include in the generated site. Not used if '--all-branches' option is set to true"
).default("master")
private val defaultBranch by option(
ArgType.String, "default-branch", "d",
"The default branch"
).default("master")
private val version by option(
ArgType.String, "version", "v",
"The version of the site"
).default("0.0.0")
private val outputDir by option(
ArgType.String, "output-dir", "o",
"Directory where the generated site will be stored. Will be created if it doesn't exist yet."
).default("build/site")
private val allBranches by option(
ArgType.Boolean, "all-branches", "all",
"When set to TRUE will generate a site for every branch in the git repository"
).default(value = false)
private val excludeBranches by option(
ArgType.String, "exclude-branches", "ex",
"Comma-separated list of branches to exclude from the generated site"
).default("")
override fun execute() {
val siteDir = File(outputDir).apply { mkdirs() }
val gitUrl = gitUrl
generateRedirectingIndexPage(siteDir, defaultBranch)
copySiteWideAssets(siteDir)
if (gitUrl != null)
generateSiteForModelInGitRepository(gitUrl, siteDir)
else
generateSiteForModel(siteDir)
}
private fun generateSiteForModelInGitRepository(gitUrl: String, siteDir: File) {
val cloneDir = File("build/model-clone")
val clonedRepository = ClonedRepository(cloneDir, gitUrl, gitUsername, gitPassword).apply {
refreshLocalClone()
}
val branchNames = if (allBranches)
clonedRepository.getBranchNames(excludeBranches.split(","))
else
branches.split(",")
println("The following branches will be checked for Structurizr Workspaces: $branchNames")
val workspaceFileInRepo = File(clonedRepository.cloneDir, workspaceFile)
val branchesToGenerate = branchNames.filter { branch ->
println("Checking branch $branch")
try {
clonedRepository.checkoutBranch(branch)
createStructurizrWorkspace(workspaceFileInRepo)
true
} catch (e: Exception) {
val errorMessage = e.message ?: "Unknown error"
println("Bad Branch $branch: $errorMessage")
false
}
}.sortedWith(branchComparator(defaultBranch))
println("The following branches contain a valid Structurizr workspace: $branchesToGenerate")
if (!branchesToGenerate.contains(defaultBranch)) {
throw Exception("$defaultBranch does not contain a valid structurizr workspace. Site generation halted.")
}
branchesToGenerate.forEach { branch ->
println("Generating site for branch $branch")
clonedRepository.checkoutBranch(branch)
val workspace = createStructurizrWorkspace(workspaceFileInRepo)
writeStructurizrJson(workspace, File(siteDir, branch))
generateDiagrams(workspace, File(siteDir, branch))
generateSite(
version,
workspace,
assetsDir?.let { File(cloneDir, it) },
siteDir,
branchesToGenerate,
branch
)
}
}
private fun generateSiteForModel(siteDir: File) {
val workspace = createStructurizrWorkspace(File(workspaceFile))
writeStructurizrJson(workspace, File(siteDir, defaultBranch))
generateDiagrams(workspace, File(siteDir, defaultBranch))
generateSite(
version,
workspace,
assetsDir?.let { File(it) },
siteDir,
listOf(defaultBranch),
defaultBranch
)
}
}
fun branchComparator(defaultBranch: String) = Comparator<String> { a, b ->
if (a == defaultBranch) -1
else if (b == defaultBranch) 1
else a.compareTo(b, ignoreCase = true)
}