|
1 | 1 | package gnit |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "chain/runtime" |
| 5 | + "strconv" |
| 6 | + "strings" |
| 7 | + |
4 | 8 | "gno.land/p/nt/avl" |
| 9 | + "gno.land/p/nt/ufmt" |
5 | 10 | ) |
6 | 11 |
|
7 | 12 | func NewRepository(name string) *Repository { |
@@ -210,20 +215,150 @@ func escapeString(s string) string { |
210 | 215 | } |
211 | 216 |
|
212 | 217 | func (r *Repository) Render(path string) string { |
| 218 | + path = trimSuffix(path, "/") |
| 219 | + |
213 | 220 | if path == "" { |
214 | | - files := r.ListFiles() |
215 | | - result := "# Repository Files\n\n" |
216 | | - for i := 0; i < len(files); i++ { |
217 | | - result += "- " + files[i] + "\n" |
218 | | - } |
| 221 | + return r.renderHome() |
| 222 | + } |
| 223 | + |
| 224 | + if r.IsDirectory(path) { |
| 225 | + return r.renderDirectory(path) |
| 226 | + } |
| 227 | + |
| 228 | + return r.renderFile(path) |
| 229 | +} |
| 230 | + |
| 231 | +func (r *Repository) renderHome() string { |
| 232 | + addr := strings.TrimSuffix(runtime.CurrentRealm().PkgPath(), "/") |
| 233 | + addr = addr[strings.Index(addr, "/r/"):] |
| 234 | + result := "# " + r.identity.Name + "\n\n" |
| 235 | + |
| 236 | + headCommit := r.GetHeadCommit() |
| 237 | + if headCommit != nil { |
| 238 | + result += "**Branch:** " + r.head + " | " |
| 239 | + result += "**Latest:** " + headCommit.Hash[:8] + " - \"" + headCommit.Message + "\"\n\n" |
| 240 | + } else { |
| 241 | + result += "**Branch:** " + r.head + " | No commits yet\n\n" |
| 242 | + } |
| 243 | + |
| 244 | + files, dirs := r.ListDirectory("") |
| 245 | + |
| 246 | + totalItems := len(files) + len(dirs) |
| 247 | + if totalItems == 0 { |
| 248 | + result += "_Repository is empty_\n" |
| 249 | + return result |
| 250 | + } |
| 251 | + |
| 252 | + result += "## Files (" + strconv.Itoa(totalItems) + ")\n\n" |
| 253 | + |
| 254 | + for i := 0; i < len(dirs); i++ { |
| 255 | + result += ufmt.Sprintf("[%s %s/](%s:%s/)\n\n", "📁", dirs[i], addr, dirs[i]) |
| 256 | + } |
| 257 | + |
| 258 | + for i := 0; i < len(files); i++ { |
| 259 | + size := r.GetFileSize(files[i]) |
| 260 | + result += ufmt.Sprintf("[%s %s](%s:%s)", "📄", files[i], addr, files[i]) |
| 261 | + result += " - " + formatBytes(size) |
| 262 | + result += "\n\n" |
| 263 | + } |
| 264 | + |
| 265 | + return result |
| 266 | +} |
| 267 | + |
| 268 | +func (r *Repository) renderDirectory(path string) string { |
| 269 | + addr := strings.TrimSuffix(runtime.CurrentRealm().PkgPath(), "/") |
| 270 | + addr = addr[strings.Index(addr, "/r/"):] |
| 271 | + |
| 272 | + displayPath := path |
| 273 | + if displayPath == "" { |
| 274 | + displayPath = "/" |
| 275 | + } else { |
| 276 | + displayPath = "/" + displayPath |
| 277 | + } |
| 278 | + |
| 279 | + result := "# " + r.identity.Name + displayPath + "\n\n" |
| 280 | + result += "[← Back](" + addr + ")\n\n" |
| 281 | + |
| 282 | + files, dirs := r.ListDirectory(path) |
| 283 | + |
| 284 | + totalItems := len(files) + len(dirs) |
| 285 | + if totalItems == 0 { |
| 286 | + result += "_Empty directory_\n" |
219 | 287 | return result |
220 | 288 | } |
221 | 289 |
|
| 290 | + result += "## Files (" + strconv.Itoa(totalItems) + ")\n\n" |
| 291 | + |
| 292 | + for i := 0; i < len(dirs); i++ { |
| 293 | + result += ufmt.Sprintf("[%s %s/](%s%s:%s/)\n\n", "📁", dirs[i], addr, path, dirs[i]) |
| 294 | + } |
| 295 | + |
| 296 | + for i := 0; i < len(files); i++ { |
| 297 | + size := r.GetFileSize(files[i]) |
| 298 | + result += ufmt.Sprintf("[%s %s](%s:%s/%s)", "📄", files[i], addr, path, files[i]) |
| 299 | + result += " - " + formatBytes(size) |
| 300 | + result += "\n\n" |
| 301 | + } |
| 302 | + |
| 303 | + return result |
| 304 | +} |
| 305 | + |
| 306 | +func (r *Repository) renderFile(path string) string { |
| 307 | + addr := strings.TrimSuffix(runtime.CurrentRealm().PkgPath(), "/") |
| 308 | + addr = addr[strings.Index(addr, "/r/"):] |
| 309 | + |
222 | 310 | content := r.Pull(path) |
223 | 311 | if content == nil { |
224 | | - return "File not found: " + path |
| 312 | + return "# File not found\n\nThe file `" + path + "` does not exist in this repository." |
| 313 | + } |
| 314 | + |
| 315 | + result := "# " + path + "\n\n" |
| 316 | + |
| 317 | + parts := splitPath(path) |
| 318 | + if len(parts) > 1 { |
| 319 | + parentPath := "" |
| 320 | + for i := 0; i < len(parts)-1; i++ { |
| 321 | + if i > 0 { |
| 322 | + parentPath += "/" |
| 323 | + } |
| 324 | + parentPath += parts[i] |
| 325 | + } |
| 326 | + result += "[← Back to " + parentPath + "](" + addr + ":" + parentPath + ")\n\n" |
| 327 | + } else { |
| 328 | + result += "[← Back](" + addr + ")\n\n" |
| 329 | + } |
| 330 | + |
| 331 | + size := len(content) |
| 332 | + result += "**Size:** " + formatBytes(size) + "\n\n" |
| 333 | + |
| 334 | + ext := "" |
| 335 | + for i := len(path) - 1; i >= 0; i-- { |
| 336 | + if path[i] == '.' { |
| 337 | + ext = path[i+1:] |
| 338 | + break |
| 339 | + } |
| 340 | + if path[i] == '/' { |
| 341 | + break |
| 342 | + } |
225 | 343 | } |
226 | | - return string(content) |
| 344 | + |
| 345 | + if ext == "gno" || ext == "go" || ext == "md" || ext == "json" || ext == "yaml" || ext == "toml" { |
| 346 | + result += "```" + ext + "\n" |
| 347 | + result += string(content) |
| 348 | + if !hasSuffix(string(content), "\n") { |
| 349 | + result += "\n" |
| 350 | + } |
| 351 | + result += "```\n" |
| 352 | + } else { |
| 353 | + result += "```\n" |
| 354 | + result += string(content) |
| 355 | + if !hasSuffix(string(content), "\n") { |
| 356 | + result += "\n" |
| 357 | + } |
| 358 | + result += "```\n" |
| 359 | + } |
| 360 | + |
| 361 | + return result |
227 | 362 | } |
228 | 363 |
|
229 | 364 | func (r *Repository) GetFileChunk(filename string, offset, size int) string { |
|
0 commit comments