From e7c01b7cf7744335b1515639dee763467423fc58 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Tue, 24 Oct 2017 17:51:01 -0400 Subject: [PATCH] doc/commands: introduce catalog commands Signed-off-by: Alexandre Terrasa --- src/doc/commands/commands_catalog.nit | 341 ++++++++++++++++++++++ src/doc/commands/tests/test_commands_catalog.nit | 113 +++++++ 2 files changed, 454 insertions(+) create mode 100644 src/doc/commands/commands_catalog.nit create mode 100644 src/doc/commands/tests/test_commands_catalog.nit diff --git a/src/doc/commands/commands_catalog.nit b/src/doc/commands/commands_catalog.nit new file mode 100644 index 0000000..be823d0 --- /dev/null +++ b/src/doc/commands/commands_catalog.nit @@ -0,0 +1,341 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Commands to retrieve Catalog related data +module commands_catalog + +import commands_model + +# A DocCommand based on a Catalog +abstract class CmdCatalog + super DocCommand + + # Catalog to query at + var catalog: Catalog +end + +# A CmdSearch command using a Catalog +class CmdCatalogSearch + super CmdCatalog + super CmdSearch + + autoinit(view, catalog, query, limit, page, count, max) + + redef fun init_results do + if results != null then return new CmdSuccess + + var res = super + if not res isa CmdSuccess then return res + + var query = self.query + if query == null then return new ErrorNoQuery + sorter = null + + var index = view.index + + # lookup by name prefix + var matches = index.find_by_name_prefix(query).uniq. + sort(lname_sorter, name_sorter, kind_sorter) + matches = matches.rerank.sort(vis_sorter, score_sorter) + + # lookup by tags + var malus = matches.length + if catalog.tag2proj.has_key(query) then + for mpackage in catalog.tag2proj[query] do + matches.add new IndexMatch(mpackage, malus) + malus += 1 + end + matches = matches.uniq.rerank.sort(vis_sorter, score_sorter) + end + + # lookup by full_name prefix + malus = matches.length + var full_matches = new IndexMatches + for match in index.find_by_full_name_prefix(query). + sort(lfname_sorter, fname_sorter) do + match.score += 1 + full_matches.add match + end + matches = matches.uniq + + # lookup by similarity + malus = matches.length + var sim_matches = new IndexMatches + for match in index.find_by_similarity(query).sort(score_sorter, lname_sorter, name_sorter) do + if match.score > query.length then break + match.score += 1 + sim_matches.add match + end + matches.add_all sim_matches + matches = matches.uniq + results = matches.rerank.sort(vis_sorter, score_sorter).mentities + return res + end + + private var score_sorter = new ScoreComparator + private var vis_sorter = new VisibilityComparator + private var name_sorter = new NameComparator + private var lname_sorter = new NameLengthComparator + private var fname_sorter = new FullNameComparator + private var lfname_sorter = new FullNameLengthComparator + private var kind_sorter = new MEntityComparator +end + +# Retrieve the catalog metadata for a MPackage +class CmdMetadata + super CmdEntity + + # MPackage metadata retrieved + var metadata: nullable MPackageMetadata = null is optional, writable + + redef fun init_command do + if metadata != null then return new CmdSuccess + + var res = super + if not res isa CmdSuccess then return res + var mentity = self.mentity.as(not null) + + if mentity isa MPackage then + metadata = mentity.metadata + else + return new WarningNoMetadata(mentity) + end + return res + end +end + +# No metadata for `mentity` +class WarningNoMetadata + super CmdWarning + + # MEntity provided + var mentity: MEntity + + redef fun to_s do return "No metadata for `{mentity.full_name}`" +end + +# Retrieve the packages in the catalog +class CmdCatalogPackages + super CmdCatalog + super CmdEntities + + autoinit(view, catalog, limit, page, count, max) + + redef var sorter = new CatalogScoreSorter(catalog) is lazy + + redef fun init_results do + if results != null then return new CmdSuccess + + var res = super + if not res isa CmdSuccess then return res + + results = catalog.mpackages.values.to_a + return res + end +end + +# Retrieve the catalog stats +class CmdCatalogStats + super CmdCatalog + + # Retrieved catalog statistics + var stats: nullable CatalogStats = null is optional, writable + + redef fun init_command do + super + self.stats = catalog.catalog_stats + return new CmdSuccess + end +end + +# Retrieve the catalog tags list +class CmdCatalogTags + super CmdCatalog + + # Sorter to sort tags alphabetically + var tags_sorter = new CatalogTagsSorter is optional, writable + + # Count of packages by tag + var packages_count_by_tags: nullable ArrayMap[String, Int] = null is optional, writable + + redef fun init_command do + super + var tags_to_projects = new ArrayMap[String, Int] + var tags = catalog.tag2proj.keys.to_a + tags_sorter.sort(tags) + for tag in tags do + if not catalog.tag2proj.has_key(tag) then continue + tags_to_projects[tag] = catalog.tag2proj[tag].length + end + packages_count_by_tags = tags_to_projects + return new CmdSuccess + end +end + +# Retrieve the packages for a tag +class CmdCatalogTag + super CmdCatalogPackages + + autoinit(view, catalog, tag, limit, page, count, max) + + # The tag to retrieve + var tag: nullable String = null is optional, writable + + redef fun init_command do + var tag = self.tag + if tag == null then return new ErrorNoTag + + if not catalog.tag2proj.has_key(tag) then return new ErrorTagNotFound(tag) + return super + end + + redef fun init_results do + if results != null then return new CmdSuccess + + var res = super + if not res isa CmdSuccess then return res + + results = catalog.tag2proj[tag].to_a + return res + end +end + +# No tag name provided +class ErrorNoTag + super CmdError + + redef fun to_s do return "No tag name provided" +end + +# No tag with this name in the catalog +class ErrorTagNotFound + super CmdError + + # The tag that was not found + var tag: String + + redef fun to_s do return "No tag found for `{tag}`" +end + +# Retrieve a person from the catalog +class CmdCatalogPerson + super CmdCatalog + + # Person to retrieve + # + # You can also pass a `person_name`. + var person: nullable Person = null is optional, writable + + # Name of the person to retrieve + # + # You can also pass a `person` instance. + var person_name: nullable String = null is optional, writable + + # Initialize the `person` result + fun init_person: CmdMessage do + var person = self.person + if person != null then + person_name = person.name + return new CmdSuccess + end + + var name = self.person_name + if name == null then return new ErrorNoPerson + if not catalog.name2person.has_key(name) then return new ErrorPersonNotFound(name) + self.person = catalog.name2person[name] + return new CmdSuccess + end + + redef fun init_command do + init_person + return super + end +end + +# No person instance or name provided +class ErrorNoPerson + super CmdError + + redef fun to_s do return "No person provided" +end + +# No person found with this name +class ErrorPersonNotFound + super CmdError + + # Name of the person that was not found + var name: String + + redef fun to_s do return "No person found for `{name}`" +end + +# Retrieve the packages maintained by a person +class CmdCatalogMaintaining + super CmdCatalogPerson + super CmdCatalogPackages + + autoinit(view, catalog, person, person_name, limit, page, count, max) + + redef fun init_command do return super + + redef fun init_results do + if results != null then return new CmdSuccess + var res = super + if not res isa CmdSuccess then return res + var person = self.person.as(not null) + + if not catalog.maint2proj.has_key(person) then return res + results = catalog.maint2proj[person] + return res + end +end + +# Retrieve the packages contributed by a person +class CmdCatalogContributing + super CmdCatalogPerson + super CmdCatalogPackages + + autoinit(view, catalog, person, person_name, limit, page, count, max) + + # Include maintained packages? + # + # Default is `false`. + var maintaining = false is optional, writable + + # FIXME linearization + redef fun init_command do return super + + redef fun init_results do + if results != null then return new CmdSuccess + + var res = super + if not res isa CmdSuccess then return res + var person = self.person.as(not null) + + if not catalog.contrib2proj.has_key(person) then return res + + var maint2proj = null + if catalog.maint2proj.has_key(person) then + maint2proj = catalog.maint2proj[person] + end + + var results = new Array[MPackage] + for mpackage in catalog.contrib2proj[person] do + if not maintaining and maint2proj != null and maint2proj.has(mpackage) then continue + results.add mpackage + end + self.results = results + return res + end +end diff --git a/src/doc/commands/tests/test_commands_catalog.nit b/src/doc/commands/tests/test_commands_catalog.nit new file mode 100644 index 0000000..9d60706 --- /dev/null +++ b/src/doc/commands/tests/test_commands_catalog.nit @@ -0,0 +1,113 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module test_commands_catalog is test + +import test_commands +import doc::commands::commands_catalog + +class TestCommandsCatalog + super TestCommands + test + + # Catalog used for tests + var test_catalog: Catalog is lazy do + var catalog = new Catalog(test_builder) + + # Compute the poset + for p in test_view.mpackages do + var g = p.root + assert g != null + test_builder.scan_group(g) + + catalog.deps.add_node(p) + for gg in p.mgroups do for m in gg.mmodules do + for im in m.in_importation.direct_greaters do + var ip = im.mpackage + if ip == null or ip == p then continue + test_catalog.deps.add_edge(p, ip) + end + end + end + # Build the catalog + for mpackage in test_view.mpackages do + catalog.package_page(mpackage) + catalog.git_info(mpackage) + catalog.mpackage_stats(mpackage) + end + return catalog + end + + fun test_cmd_catalog is test do + var cmd = new CmdCatalogPackages(test_view, test_catalog) + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.results.as(not null).first.full_name == "test_prog" + end + + fun test_cmd_catalog_search is test do + var cmd = new CmdCatalogSearch(test_view, test_catalog, "test") + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.results.as(not null).first.full_name == "test_prog" + assert cmd.results.as(not null).first isa MPackage + end + + fun test_cmd_catalog_stats is test do + var cmd = new CmdCatalogStats(test_view, test_catalog) + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.stats != null + end + + fun test_cmd_catalog_tags is test do + var cmd = new CmdCatalogTags(test_view, test_catalog) + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.packages_count_by_tags.as(not null).length == 2 + end + + fun test_cmd_catalog_tag is test do + var cmd = new CmdCatalogTag(test_view, test_catalog, "test") + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.tag == "test" + assert cmd.results.as(not null).length == 1 + end + + fun test_cmd_catalog_person is test do + var cmd = new CmdCatalogPerson(test_view, test_catalog, person_name = "Alexandre Terrasa") + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.person.as(not null).name == "Alexandre Terrasa" + end + + fun test_cmd_catalog_contributing is test do + var cmd = new CmdCatalogContributing(test_view, test_catalog, + person_name = "Alexandre Terrasa") + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.person.as(not null).name == "Alexandre Terrasa" + assert cmd.results.as(not null).length == 1 + end + + fun test_cmd_catalog_maintaining is test do + var cmd = new CmdCatalogMaintaining(test_view, test_catalog, + person_name = "Alexandre Terrasa") + var res = cmd.init_command + assert res isa CmdSuccess + assert cmd.person.as(not null).name == "Alexandre Terrasa" + assert cmd.results.as(not null).length == 2 + end +end -- 1.7.9.5