<commit_before>local search = {}

local dir = require("luarocks.dir")
local path = require("luarocks.path")
local manif = require("luarocks.manif")
local vers = require("luarocks.core.vers")
local cfg = require("luarocks.core.cfg")
local util = require("luarocks.util")
local queries = require("luarocks.queries")
local results = require("luarocks.results")

--- Store a search result (a rock or rockspec) in the result tree.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param result table: A result.
function search.store_result(result_tree, result)
   assert(type(result_tree) == "table")
   assert(result:type() == "result")

   local name = result.name
   local version = result.version

   if not result_tree[name] then result_tree[name] = {} end
   if not result_tree[name][version] then result_tree[name][version] = {} end
   table.insert(result_tree[name][version], {
      arch = result.arch,
      repo = result.repo
   })
end

--- Store a match in a result tree if version matches query.
-- Name, version, arch and repository path are stored in a given
-- table, optionally checking if version and arch (if given) match
-- a query.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param result table: a result object.
-- @param query table: a query object.
local function store_if_match(result_tree, result, query)
   assert(result:type() == "result")
   assert(query:type() == "query")

   if result:satisfies(query) then
      search.store_result(result_tree, result)
   end
end

--- Perform search on a local repository.
-- @param repo string: The pathname of the local repository.
-- @param query table: a query object.
-- @param result_tree table or nil: If given, this table will store the
-- result tree; if not given, a new table will be created.
-- @return table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- If a table was given in the "result_tree" parameter, that is the result value.
function search.disk_search(repo, query, result_tree)
   assert(type(repo) == "string")
   assert(query:type() == "query")
   assert(type(result_tree) == "table" or not result_tree)
   
   local fs = require("luarocks.fs")
     
   if not result_tree then
      result_tree = {}
   end
   
   for name in fs.dir(repo) do
      local pathname = dir.path(repo, name)
      local rname, rversion, rarch = path.parse_name(name)

      if rname and (pathname:match(".rockspec$") or pathname:match(".rock$")) then
         local result = results.new(rname, rversion, repo, rarch)
         store_if_match(result_tree, result, query)
      elseif fs.is_dir(pathname) then
         for version in fs.dir(pathname) do
            if version:match("-%d+$") then
               local namespace = nil
               -- FIXME read rock_namespace file
               local result = results.new(name, version, repo, "installed", namespace)
               store_if_match(result_tree, result, query)
            end
         end
      end
   end
   return result_tree
end

local function read_namespace(name, version, tree)
   local namespace
   local fd = io.open(path.rock_namespace_file(name, version, tree), "r")
   if fd then
      namespace = fd:read("*a")
      fd:close()
   end
   return namespace
end

--- Perform search on a rocks server or tree.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param repo string: The URL of a rocks server or
-- the pathname of a rocks tree (as returned by path.rocks_dir()).
-- @param query table: a query object.
-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
-- @param is_local boolean
-- @return true or, in case of errors, nil, an error message and an optional error code.
local function manifest_search(result_tree, repo, query, lua_version, is_local)
   assert(type(result_tree) == "table")
   assert(type(repo) == "string")
   assert(query:type() == "query")

   -- FIXME do not add this in local repos
   if (not is_local) and query.namespace then
      repo = repo .. "/manifests/" .. query.namespace
   end

   local manifest, err, errcode = manif.load_manifest(repo, lua_version)
   if not manifest then
      return nil, err, errcode<commit_msg>Read namespace on disk search as well<commit_after>local search = {}

local dir = require("luarocks.dir")
local path = require("luarocks.path")
local manif = require("luarocks.manif")
local vers = require("luarocks.core.vers")
local cfg = require("luarocks.core.cfg")
local util = require("luarocks.util")
local queries = require("luarocks.queries")
local results = require("luarocks.results")

--- Store a search result (a rock or rockspec) in the result tree.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param result table: A result.
function search.store_result(result_tree, result)
   assert(type(result_tree) == "table")
   assert(result:type() == "result")

   local name = result.name
   local version = result.version

   if not result_tree[name] then result_tree[name] = {} end
   if not result_tree[name][version] then result_tree[name][version] = {} end
   table.insert(result_tree[name][version], {
      arch = result.arch,
      repo = result.repo
   })
end

--- Store a match in a result tree if version matches query.
-- Name, version, arch and repository path are stored in a given
-- table, optionally checking if version and arch (if given) match
-- a query.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param result table: a result object.
-- @param query table: a query object.
local function store_if_match(result_tree, result, query)
   assert(result:type() == "result")
   assert(query:type() == "query")

   if result:satisfies(query) then
      search.store_result(result_tree, result)
   end
end

--- Get the namespace of a locally-installed rock, if any.
-- @param name string: The rock name, without a namespace.
-- @param version string: The rock version.
-- @param tree string: The local tree to use.
-- @return string?: The namespace if it exists, or nil.
local function read_namespace(name, version, tree)
   assert(type(name) == "string")
   assert(type(version) == "string")
   assert(type(tree) == "string")

   local namespace
   local fd = io.open(path.rock_namespace_file(name, version, tree), "r")
   if fd then
      namespace = fd:read("*a")
      fd:close()
   end
   return namespace
end

--- Perform search on a local repository.
-- @param repo string: The pathname of the local repository.
-- @param query table: a query object.
-- @param result_tree table or nil: If given, this table will store the
-- result tree; if not given, a new table will be created.
-- @return table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- If a table was given in the "result_tree" parameter, that is the result value.
function search.disk_search(repo, query, result_tree)
   assert(type(repo) == "string")
   assert(query:type() == "query")
   assert(type(result_tree) == "table" or not result_tree)
   
   local fs = require("luarocks.fs")
     
   if not result_tree then
      result_tree = {}
   end
   
   for name in fs.dir(repo) do
      local pathname = dir.path(repo, name)
      local rname, rversion, rarch = path.parse_name(name)

      if rname and (pathname:match(".rockspec$") or pathname:match(".rock$")) then
         local result = results.new(rname, rversion, repo, rarch)
         store_if_match(result_tree, result, query)
      elseif fs.is_dir(pathname) then
         for version in fs.dir(pathname) do
            if version:match("-%d+$") then
               local namespace = read_namespace(name, version, repo)
               local result = results.new(name, version, repo, "installed", namespace)
               store_if_match(result_tree, result, query)
            end
         end
      end
   end
   return result_tree
end

--- Perform search on a rocks server or tree.
-- @param result_tree table: The result tree, where keys are package names and
-- values are tables matching version strings to arrays of
-- tables with fields "arch" and "repo".
-- @param repo string: The URL of a rocks server or
-- the pathname of a rocks tree (as returned by path.rocks_dir()).
-- @param query table: a query object.
-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
-- @param is_local boolean
-- @return true or, in case of errors, nil, an error message and an optional error code.
local function manifest_search(result_tree, repo, query, lua_version, is_local)
   assert(type(result_tree) == "table")
   assert(type(repo) == "string")
   assert(query:type() == "query")

   -- FIXME do not add this in local repos
   if (not is_local) and query.namespace then
      repo = repo .. "/manifests/" .. query.namespace
   end

   local manifest, err, errcode = manif.load_manifest(repo, lua_version)
   if not manifest then
      return nil, err, errcode
{'fraction_non_alphanumeric': 0.10879223060233495, 'fraction_numerical': 0.00020663291662361815, 'mean_word_length': 3.414044687642499, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2608223', 'n_tokens_mistral': 2794, 'n_tokens_neox': 2766, 'n_words': 1094}