GitRoot
Craft your forge, Build your project, Grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5import { JSON } from "json-as";
6import {
7 Commit,
8 File,
9 Plugin,
10 PluginRun,
11 PluginRunWhen,
12 PluginWrite,
13 PluginWriteRight,
14 PluginWriteRightCan,
15 Register,
16 Server,
17} from "plugin/server";
18
19export * from "plugin/exports";
20
21@json
22class FluxConf {
23 constructor(
24 public link: string,
25 public path: string,
26 public title: string,
27 public description: string,
28 public language: string,
29 ) {}
30
31 static build(
32 link: string,
33 path: string,
34 title: string,
35 description: string,
36 language: string,
37 ): FluxConf {
38 return new FluxConf(link, path, title, description, language);
39 }
40
41 generateEmptyRss(): string {
42 return `<rss version="2.0">
43 <channel>
44 <title>${this.title}</title>
45 <link>${this.link}</link>
46 <description>${this.description}</description>
47 <language>${this.language}</language>
48 <generator>Pollen plugin - GitRoot</generator>
49 <!-- next -->
50 </channel>
51</rss>`;
52 }
53}
54
55@json
56class Conf {
57 flux: Array<FluxConf> = [
58 FluxConf.build(
59 "https://YOURINSTANCE.com/YOURPROJECT/",
60 "rss/all.xml",
61 "All push",
62 "Every push made in your forge",
63 "en",
64 ),
65 ];
66
67 default(): Map<string, string> {
68 const m = new Map<string, string>();
69 m.set("flux", JSON.stringify<Array<FluxConf>>(this.flux));
70 return m;
71 }
72}
73
74const defaultRun: PluginRun = new PluginRun(
75 "**/*",
76 ["*"],
77 [PluginRunWhen.Add, PluginRunWhen.Mod, PluginRunWhen.Del],
78 [],
79 new PluginWrite(
80 [],
81 [
82 new PluginWriteRight("rss/*", [
83 PluginWriteRightCan.Add,
84 PluginWriteRightCan.Mod,
85 ]),
86 ],
87 [],
88 [],
89 ),
90 new Conf().default(),
91);
92
93function generateItem(conf: FluxConf, commits: Array<Commit>): string {
94 const before = `<item><author>${commits[0].committerEmail} (${commits[0].committerName})</author><link>${conf.link}</link><title>Has pushed ${commits.length} commits on ${commits[0].branch}</title><description>`;
95 const beforeDesc = `<![CDATA[<p>All commits:</p><ul>`;
96 const afterDesc = `</ul>]]>`;
97 const after = `</description><pubDate>${commits[0].date.toUTCString()}</pubDate><guid>${
98 commits[0].hash
99 }</guid></item>`;
100 const html =
101 beforeDesc +
102 commits
103 .sort((a, b) => a.date.getUTCMilliseconds() - b.date.getUTCMilliseconds())
104 .reduce((acc, item) => {
105 return `${acc}<li>${item.message.replaceAll("\n", "<br/>")}</li>`;
106 }, "") +
107 afterDesc;
108 return before + html + after;
109}
110
111class Pollen implements Plugin {
112 private server: Server;
113 private conf: Conf | null = null;
114 private commits: Array<Commit> = new Array<Commit>();
115
116 constructor(server: Server) {
117 this.server = server;
118 }
119
120 init(
121 repoName: string,
122 confHasChanged: boolean,
123 serializedConf: string,
124 ): void {
125 this.conf = JSON.parse<Conf>(serializedConf);
126
127 for (let i = 0; i < this.conf!.flux.length; ++i) {
128 const flux = this.conf!.flux[i];
129 if (!this.server.webcontent().exists(flux.path)) {
130 this.server
131 .webcontent()
132 .writeContent(flux.path, flux.generateEmptyRss());
133 }
134 }
135 return;
136 }
137
138 startCommit(commit: Commit): void {
139 this.commits.push(commit);
140 return;
141 }
142
143 addFile(file: File): void {
144 return;
145 }
146
147 modFile(file: File): void {
148 return;
149 }
150
151 delFile(file: File): void {
152 return;
153 }
154
155 endCommit(commit: Commit): void {
156 return;
157 }
158
159 finish(): void {
160 if (this.conf != null && this.commits.length > 0) {
161 for (let i = 0; i < this.conf!.flux.length; i++) {
162 this.server
163 .webcontent()
164 .replaceContent(
165 this.conf!.flux[i].path,
166 "<!-- next -->",
167 "<!-- next -->\n" + generateItem(this.conf!.flux[i], this.commits),
168 );
169 }
170 }
171 this.conf = null;
172 this.commits = [];
173 return;
174 }
175}
176
177function build(server: Server): Plugin {
178 return new Pollen(server);
179}
180
181export function install(): void {
182 Register([defaultRun], build);
183}