nitpm: intro service to parse the import line in package.ini
authorAlexis Laferrière <alexis.laf@xymus.net>
Mon, 26 Feb 2018 21:19:09 +0000 (16:19 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Wed, 28 Mar 2018 13:14:04 +0000 (09:14 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/picnit.nit
src/picnit_shared.nit

index f5e28c8..5df3bcd 100644 (file)
@@ -22,56 +22,6 @@ import curl
 
 import picnit_shared
 
-redef class Text
-
-       # Does `self` look like a package name?
-       #
-       # ~~~
-       # assert "gamnit".is_package_name
-       # assert "n1t".is_package_name
-       # assert not ".".is_package_name
-       # assert not "./gamnit".is_package_name
-       # assert not "https://github.com/nitlang/nit.git".is_package_name
-       # assert not "git://github.com/nitlang/nit".is_package_name
-       # assert not "git@gitlab.com:xymus/gamnit.git".is_package_name
-       # assert not "4it".is_package_name
-       # ~~~
-       private fun is_package_name: Bool
-       do
-               if is_empty then return false
-               if not chars.first.is_alpha then return false
-
-               for c in chars do
-                       if not (c.is_alphanumeric or c == '_') then return false
-               end
-
-               return true
-       end
-
-       # Get package name from the Git address `self`
-       #
-       # Return `null` on failure.
-       #
-       # ~~~
-       # assert "https://github.com/nitlang/nit.git".git_name == "nit"
-       # assert "git://github.com/nitlang/nit".git_name == "nit"
-       # assert "gamnit".git_name == "gamnit"
-       # assert "///".git_name == null
-       # assert "file:///".git_name == "file:"
-       # ~~~
-       private fun git_name: nullable String
-       do
-               var parts = split("/")
-               for part in parts.reverse_iterator do
-                       if not part.is_empty then
-                               return part.strip_extension(".git")
-                       end
-               end
-
-               return null
-       end
-end
-
 # Command line action, passed after `picnit`
 abstract class Command
 
index 07d44cd..80b7b30 100644 (file)
@@ -17,3 +17,115 @@ module picnit_shared
 
 # Folder where are downloaded picnit packages
 fun picnit_lib_dir: String do do return "HOME".environ / ".local/lib/nit/"
+
+redef class Text
+
+       # Does `self` look like a package name?
+       #
+       # ~~~
+       # assert "gamnit".is_package_name
+       # assert "n1t".is_package_name
+       # assert not ".".is_package_name
+       # assert not "./gamnit".is_package_name
+       # assert not "https://github.com/nitlang/nit.git".is_package_name
+       # assert not "git://github.com/nitlang/nit".is_package_name
+       # assert not "git@gitlab.com:xymus/gamnit.git".is_package_name
+       # assert not "4it".is_package_name
+       # ~~~
+       fun is_package_name: Bool
+       do
+               if is_empty then return false
+               if not chars.first.is_alpha then return false
+
+               for c in chars do
+                       if not (c.is_alphanumeric or c == '_') then return false
+               end
+
+               return true
+       end
+
+       # Get package name from the Git address `self`
+       #
+       # Return `null` on failure.
+       #
+       # ~~~
+       # assert "https://github.com/nitlang/nit.git".git_name == "nit"
+       # assert "git://github.com/nitlang/nit".git_name == "nit"
+       # assert "gamnit".git_name == "gamnit"
+       # assert "///".git_name == null
+       # assert "file:///".git_name == "file:"
+       # ~~~
+       fun git_name: nullable String
+       do
+               var parts = split("/")
+               for part in parts.reverse_iterator do
+                       if not part.is_empty then
+                               return part.strip_extension(".git")
+                       end
+               end
+
+               return null
+       end
+
+       # Parse the external package declaration, as declared in package.ini
+       #
+       # Return a map of `ExternalPackage` organized by the short package name,
+       # as used in imports from Nit code.
+       fun parse_import: Map[String, ExternalPackage]
+       do
+               var res = new Map[String, ExternalPackage]
+               var ids = self.split(",")
+               for id in ids do
+                       id = id.chomp
+                       if id.is_empty then continue
+
+                       # Check version suffix (e.g. gamnit=1.0)
+                       var match = id.search_last("=")
+                       var package_name
+                       var version = null
+                       if match != null then
+                               # There's a version suffix
+                               package_name = id.substring(0, match.from)
+                               version = id.substring_from(match.after)
+                               id = package_name
+                       else
+                               package_name = id
+                       end
+
+                       # Extract a package name from a Git address
+                       if not package_name.is_package_name then
+                               # Assume it's a Git repository
+                               var git_name = package_name.git_name
+                               if git_name == null then
+                                       # Invalid name
+                                       # TODO report error only when used by the parser
+                                       continue
+                               end
+                               package_name = git_name
+                       end
+
+                       res[package_name] = new ExternalPackage(id, package_name, version)
+               end
+               return res
+       end
+end
+
+# Reference to a nitpm package
+class ExternalPackage
+
+       # Package identifier (name or Git address), without the version
+       var id: String
+
+       # Standard Nit package name, as used in importations from Nit
+       var name: String
+
+       # Version string of the package
+       var version: nullable String
+
+       # Expected folder name for this package
+       var dir_name: String is lazy do
+               var version = version
+               if version == null then return name
+               return name + "=" + version
+       end
+end