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

Property definitions

nitc :: loader $ ModelBuilder :: identify_group
	# 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