nitc :: ModelBuilder :: identify_group
If the directory is not a group null is returned.
Silently return null
if dirpath
does not exists, is not a directory,
cannot be identified or cannot be attached to a mpackage.
If null
is returned, last_loader_error
can be set to a specific error message.
Note: paths
is also used to look for mgroups
# Return the mgroup associated to a directory path.
# If the directory is not a group null is returned.
#
# Silently return `null` if `dirpath` does not exists, is not a directory,
# cannot be identified or cannot be attached to a mpackage.
# If `null` is returned, `last_loader_error` can be set to a specific error message.
#
# Note: `paths` is also used to look for mgroups
fun identify_group(dirpath: String): nullable MGroup
do
# Reset error
last_loader_error = null
var stat = dirpath.file_stat
if stat == null or not stat.is_dir then do
# search dirless directories in known -I paths
if dirpath.chars.has('/') then return null
for p in paths do
var try = p / dirpath
stat = try.file_stat
if stat != null then
dirpath = try
break label
end
end
return null
end label
# Filter out non-directories
if not stat.is_dir then
last_loader_error = "Error: `{dirpath}` is not a directory."
return null
end
# Fast track, the path is already known
var rdp = module_absolute_path(dirpath)
if mgroups.has_key(rdp) then
return mgroups[rdp]
end
# By default, the name of the package or group is the base_name of the directory
var pn = rdp.basename
# Check `package.ini` that indicate a package
var ini = null
var parent = null
var inipath = dirpath / "package.ini"
if inipath.file_exists then
ini = new IniFile.from_file(inipath)
end
if ini == null then
# No ini, multiple course of action
# The root of the directory hierarchy in the file system.
if rdp == "/" then
mgroups[rdp] = null
last_loader_error = "Error: `{dirpath}` is not a Nit package."
return null
end
# Special stopper `packages.ini`
if (dirpath/"packages.ini").file_exists then
# dirpath cannot be a package since it is a package directory
mgroups[rdp] = null
last_loader_error = "Error: `{dirpath}` is not a Nit package."
return null
end
# check the parent directory (if it does not contain the stopper file)
var parentpath = dirpath.join_path("..").simplify_path
var stopper = parentpath / "packages.ini"
if not stopper.file_exists then
# Recursively get the parent group
parent = identify_group(parentpath)
if parent != null then do
var mpackage = parent.mpackage
if not mpackage.accept(dirpath) then
toolcontext.info("directory `{dirpath}` excluded from package `{mpackage}`", 2)
parent = null
end
end
if parent == null then
# Parent is not a group, thus we are not a group either
mgroups[rdp] = null
last_loader_error = "Error: `{dirpath}` is not a Nit package."
return null
end
end
end
var loc = new Location.opaque_file(dirpath)
var mgroup
if parent == null then
# no parent, thus new package
if ini != null then pn = ini["package.name"] or else pn
var mpackage = new MPackage(pn, model, loc)
mgroup = new MGroup(pn, loc, mpackage, null) # same name for the root group
mpackage.root = mgroup
toolcontext.info("found package `{mpackage}` at {dirpath}", 2)
mpackage.ini = ini
else
mgroup = new MGroup(pn, loc, parent.mpackage, parent)
toolcontext.info("found sub group `{mgroup.full_name}` at {dirpath}", 2)
end
# search documentation
# in src first so the documentation of the package code can be distinct for the documentation of the package usage
var readme = dirpath.join_path("README.md")
if not readme.file_exists then readme = dirpath.join_path("README")
if readme.file_exists then
var mdoc = load_markdown(readme)
mgroup.mdoc = mdoc
mdoc.original_mentity = mgroup
end
mgroups[rdp] = mgroup
return mgroup
end
src/loader.nit:497,2--616,4