1
2--- Module which builds the index.html page to be used in rocks servers.
3local index = {}
4
5local util = require("luarocks.util")
6local fs = require("luarocks.fs")
7local vers = require("luarocks.core.vers")
8local persist = require("luarocks.persist")
9local dir = require("luarocks.dir")
10local manif = require("luarocks.manif")
11
12local ext_url_target = ' target="_blank"'
13
14local index_header = [[
15<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
16<html>
17<head>
18<title>Available rocks</title>
19<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
20<style>
21body {
22   background-color: white;
23   font-family: "bitstream vera sans", "verdana", "sans";
24   font-size: 14px;
25}
26a {
27   color: #0000c0;
28   text-decoration: none;
29}
30a.pkg {
31   color: black;
32}
33a:hover {
34   text-decoration: underline;
35}
36td.main {
37   border-style: none;
38}
39blockquote {
40   font-size: 12px;
41}
42td.package {
43   background-color: #f0f0f0;
44   vertical-align: top;
45}
46td.spacer {
47   height: 5px;
48}
49td.version {
50   background-color: #d0d0d0;
51   vertical-align: top;
52   text-align: left;
53   padding: 5px;
54   width: 100px;
55}
56p.manifest {
57   font-size: 8px;
58}
59</style>
60</head>
61<body>
62<h1>Available rocks</h1>
63<p>
64Lua modules available from this location for use with <a href="http://www.luarocks.org">LuaRocks</a>:
65</p>
66<table class="main">
67]]
68
69local index_package_begin = [[
70<td class="package">
71<p><a name="$anchor"></a><a href="#$anchor" class="pkg"><b>$package</b></a> - $summary<br/>
72</p><blockquote><p>$detailed<br/>
73$externaldependencies
74<font size="-1"><a href="$original">latest sources</a> $homepage | License: $license</font></p>
75</blockquote></a></td>
76<td class="version">
77]]
78
79local index_package_end = [[
80</td></tr>
81<tr><td colspan="2" class="spacer"></td></tr>
82]]
83
84local index_footer_begin = [[
85</table>
86<p class="manifest">
87<a href="manifest">manifest file</a>
88]]
89local index_manifest_ver = [[
90&bull; <a href="manifest-$VER">Lua $VER manifest file</a> (<a href="manifest-$VER.zip">zip</a>)
91]]
92local index_footer_end = [[
93</p>
94</body>
95</html>
96]]
97
98function index.format_external_dependencies(rockspec)
99   if rockspec.external_dependencies then
100      local deplist = {}
101      local listed_set = {}
102      local plats = nil
103      for name, desc in util.sortedpairs(rockspec.external_dependencies) do
104         if name ~= "platforms" then
105            table.insert(deplist, name:lower())
106            listed_set[name] = true
107         else
108            plats = desc
109         end
110      end
111      if plats then
112         for plat, entries in util.sortedpairs(plats) do
113            for name, desc in util.sortedpairs(entries) do
114               if not listed_set[name] then
115                  table.insert(deplist, name:lower() .. " (on "..plat..")")
116               end
117            end
118         end
119      end
120      return '<p><b>External dependencies:</b> ' .. table.concat(deplist, ',&nbsp;').. '</p>'
121   else
122      return ""
123   end
124end
125
126function index.make_index(repo)
127   if not fs.is_dir(repo) then
128      return nil, "Cannot access repository at "..repo
129   end
130   local manifest = manif.load_manifest(repo)
131   local out = io.open(dir.path(repo, "index.html"), "w")
132
133   out:write(index_header)
134   for package, version_list in util.sortedpairs(manifest.repository) do
135      local latest_rockspec = nil
136      local output = index_package_begin
137      for version, data in util.sortedpairs(version_list, vers.compare_versions) do
138         local versions = {}
139         output = output..version..':&nbsp;'
140         table.sort(data, function(a,b) return a.arch < b.arch end)
141         for _, item in ipairs(data) do
142            local file
143            if item.arch == 'rockspec' then
144               file = ("%s-%s.rockspec"):format(package, version)
145               if not latest_rockspec then latest_rockspec = file end
146            else
147               file = ("%s-%s.%s.rock"):format(package, version, item.arch)
148            end
149            table.insert(versions, '<a href="'..file..'">'..item.arch..'</a>')
150         end
151         output = output .. table.concat(versions, ',&nbsp;') .. '<br/>'
152      end
153      output = output .. index_package_end
154      if latest_rockspec then
155         local rockspec = persist.load_into_table(dir.path(repo, latest_rockspec))
156         local descript = rockspec.description or {}
157         local vars = {
158            anchor = package,
159            package = rockspec.package,
160            original = rockspec.source.url,
161            summary = descript.summary or "",
162            detailed = descript.detailed or "",
163            license = descript.license or "N/A",
164            homepage = descript.homepage and ('| <a href="'..descript.homepage..'"'..ext_url_target..'>project homepage</a>') or "",
165            externaldependencies = index.format_external_dependencies(rockspec)
166         }
167         vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ")
168         vars.detailed = vars.detailed:gsub("(https?://[a-zA-Z0-9%.%%-_%+%[%]=%?&/$@;:]+)", '<a href="%1"'..ext_url_target..'>%1</a>')
169         output = output:gsub("$(%w+)", vars)
170      else
171         output = output:gsub("$anchor", package)
172         output = output:gsub("$package", package)
173         output = output:gsub("$(%w+)", "")
174      end
175      out:write(output)
176   end
177   out:write(index_footer_begin)
178   for ver in util.lua_versions() do
179      out:write((index_manifest_ver:gsub("$VER", ver)))
180   end
181   out:write(index_footer_end)
182   out:close()
183end
184
185return index
186