Merge: src/doc/commands: clean commands hierarchy
[nit.git] / src / doc / commands / commands_catalog.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Commands to retrieve Catalog related data
16 module commands_catalog
17
18 import commands_model
19 import catalog
20
21 # A DocCommand based on a Catalog
22 abstract class CmdCatalog
23 super DocCommand
24
25 autoinit(model, catalog, filter)
26
27 # Catalog to query at
28 var catalog: Catalog
29 end
30
31 # A CmdSearch command using a Catalog
32 class CmdCatalogSearch
33 super CmdCatalog
34 super CmdSearch
35
36 autoinit(model, catalog, filter, query, limit, page, count, max)
37
38 redef fun init_results do
39 if results != null then return new CmdSuccess
40
41 var res = super
42 if not res isa CmdSuccess then return res
43
44 var query = self.query
45 if query == null then return new ErrorNoQuery
46 sorter = null
47
48 var filter = self.filter
49 var index = model.index
50
51 # lookup by name prefix
52 var matches = index.find_by_name_prefix(query, filter).uniq.
53 sort(lname_sorter, name_sorter, kind_sorter)
54 matches = matches.rerank.sort(vis_sorter, score_sorter)
55
56 # lookup by tags
57 var malus = matches.length
58 if catalog.tag2proj.has_key(query) then
59 for mpackage in catalog.tag2proj[query] do
60 if filter != null and not filter.accept_mentity(mpackage) then continue
61 matches.add new IndexMatch(mpackage, malus)
62 malus += 1
63 end
64 matches = matches.uniq.rerank.sort(vis_sorter, score_sorter)
65 end
66
67 # lookup by full_name prefix
68 malus = matches.length
69 var full_matches = new IndexMatches
70 for match in index.find_by_full_name_prefix(query, filter).
71 sort(lfname_sorter, fname_sorter) do
72 match.score += 1
73 full_matches.add match
74 end
75 matches = matches.uniq
76
77 # lookup by similarity
78 malus = matches.length
79 var sim_matches = new IndexMatches
80 for match in index.find_by_similarity(query, filter).sort(score_sorter, kind_sorter, lname_sorter, name_sorter) do
81 if match.score > query.length then break
82 match.score += 1
83 sim_matches.add match
84 end
85 matches.add_all sim_matches
86 matches = matches.uniq
87 results = matches.rerank.sort(vis_sorter, score_sorter).mentities
88 return res
89 end
90
91 private var score_sorter = new ScoreComparator
92 private var vis_sorter = new VisibilityComparator
93 private var name_sorter = new NameComparator
94 private var lname_sorter = new NameLengthComparator
95 private var fname_sorter = new FullNameComparator
96 private var lfname_sorter = new FullNameLengthComparator
97 private var kind_sorter = new MEntityComparator
98 end
99
100 # Retrieve the catalog metadata for a MPackage
101 class CmdMetadata
102 super CmdEntity
103
104 # MPackage metadata retrieved
105 var metadata: nullable MPackageMetadata = null is optional, writable
106
107 redef fun init_command do
108 if metadata != null then return new CmdSuccess
109
110 var res = super
111 if not res isa CmdSuccess then return res
112 var mentity = self.mentity.as(not null)
113
114 if mentity isa MPackage then
115 metadata = mentity.metadata
116 else
117 return new WarningNoMetadata(mentity)
118 end
119 return res
120 end
121 end
122
123 # No metadata for `mentity`
124 class WarningNoMetadata
125 super CmdWarning
126
127 # MEntity provided
128 var mentity: MEntity
129
130 redef fun to_s do return "No metadata for `{mentity.full_name}`"
131 end
132
133 # Retrieve the packages in the catalog
134 class CmdCatalogPackages
135 super CmdCatalog
136 super CmdEntities
137
138 autoinit(model, catalog, filter, limit, page, count, max)
139
140 redef var sorter = new CatalogScoreSorter(catalog) is lazy
141
142 redef fun init_results do
143 if results != null then return new CmdSuccess
144
145 var res = super
146 if not res isa CmdSuccess then return res
147
148 results = catalog.mpackages.values.to_a
149 return res
150 end
151 end
152
153 # Retrieve the catalog stats
154 class CmdCatalogStats
155 super CmdCatalog
156
157 # Retrieved catalog statistics
158 var stats: nullable CatalogStats = null is optional, writable
159
160 redef fun init_command do
161 super
162 self.stats = catalog.catalog_stats
163 return new CmdSuccess
164 end
165 end
166
167 # Retrieve the catalog tags list
168 class CmdCatalogTags
169 super CmdCatalog
170
171 # Sorter to sort tags alphabetically
172 var tags_sorter = new CatalogTagsSorter is optional, writable
173
174 # Count of packages by tag
175 var packages_count_by_tags: nullable ArrayMap[String, Int] = null is optional, writable
176
177 redef fun init_command do
178 super
179 var tags_to_projects = new ArrayMap[String, Int]
180 var tags = catalog.tag2proj.keys.to_a
181 tags_sorter.sort(tags)
182 for tag in tags do
183 if not catalog.tag2proj.has_key(tag) then continue
184 tags_to_projects[tag] = catalog.tag2proj[tag].length
185 end
186 packages_count_by_tags = tags_to_projects
187 return new CmdSuccess
188 end
189 end
190
191 # Retrieve the packages for a tag
192 class CmdCatalogTag
193 super CmdCatalogPackages
194
195 autoinit(model, catalog, filter, tag, limit, page, count, max)
196
197 # The tag to retrieve
198 var tag: nullable String = null is optional, writable
199
200 redef fun init_command do
201 var tag = self.tag
202 if tag == null then return new ErrorNoTag
203
204 if not catalog.tag2proj.has_key(tag) then return new ErrorTagNotFound(tag)
205 return super
206 end
207
208 redef fun init_results do
209 if results != null then return new CmdSuccess
210
211 var res = super
212 if not res isa CmdSuccess then return res
213
214 results = catalog.tag2proj[tag].to_a
215 return res
216 end
217 end
218
219 # No tag name provided
220 class ErrorNoTag
221 super CmdError
222
223 redef fun to_s do return "No tag name provided"
224 end
225
226 # No tag with this name in the catalog
227 class ErrorTagNotFound
228 super CmdError
229
230 # The tag that was not found
231 var tag: String
232
233 redef fun to_s do return "No tag found for `{tag}`"
234 end
235
236 # Retrieve a person from the catalog
237 class CmdCatalogPerson
238 super CmdCatalog
239
240 # Person to retrieve
241 #
242 # You can also pass a `person_name`.
243 var person: nullable Person = null is optional, writable
244
245 # Name of the person to retrieve
246 #
247 # You can also pass a `person` instance.
248 var person_name: nullable String = null is optional, writable
249
250 # Initialize the `person` result
251 fun init_person: CmdMessage do
252 var person = self.person
253 if person != null then
254 person_name = person.name
255 return new CmdSuccess
256 end
257
258 var name = self.person_name
259 if name == null then return new ErrorNoPerson
260 if not catalog.name2person.has_key(name) then return new ErrorPersonNotFound(name)
261 self.person = catalog.name2person[name]
262 return new CmdSuccess
263 end
264
265 redef fun init_command do
266 init_person
267 return super
268 end
269 end
270
271 # No person instance or name provided
272 class ErrorNoPerson
273 super CmdError
274
275 redef fun to_s do return "No person provided"
276 end
277
278 # No person found with this name
279 class ErrorPersonNotFound
280 super CmdError
281
282 # Name of the person that was not found
283 var name: String
284
285 redef fun to_s do return "No person found for `{name}`"
286 end
287
288 # Retrieve the packages maintained by a person
289 class CmdCatalogMaintaining
290 super CmdCatalogPerson
291 super CmdCatalogPackages
292
293 autoinit(model, catalog, filter, person, person_name, limit, page, count, max)
294
295 redef fun init_command do return super
296
297 redef fun init_results do
298 if results != null then return new CmdSuccess
299 var res = super
300 if not res isa CmdSuccess then return res
301 var person = self.person.as(not null)
302
303 if not catalog.maint2proj.has_key(person) then return res
304 results = catalog.maint2proj[person]
305 return res
306 end
307 end
308
309 # Retrieve the packages contributed by a person
310 class CmdCatalogContributing
311 super CmdCatalogPerson
312 super CmdCatalogPackages
313
314 autoinit(model, catalog, filter, person, person_name, limit, page, count, max)
315
316 # Include maintained packages?
317 #
318 # Default is `false`.
319 var maintaining = false is optional, writable
320
321 # FIXME linearization
322 redef fun init_command do return super
323
324 redef fun init_results do
325 if results != null then return new CmdSuccess
326
327 var res = super
328 if not res isa CmdSuccess then return res
329 var person = self.person.as(not null)
330
331 if not catalog.contrib2proj.has_key(person) then return res
332
333 var maint2proj = null
334 if catalog.maint2proj.has_key(person) then
335 maint2proj = catalog.maint2proj[person]
336 end
337
338 var results = new Array[MPackage]
339 for mpackage in catalog.contrib2proj[person] do
340 if not maintaining and maint2proj != null and maint2proj.has(mpackage) then continue
341 results.add mpackage
342 end
343 self.results = results
344 return res
345 end
346 end