80b7b302c97b11f5b4283f78dd851be16d6a2362
[nit.git] / src / picnit_shared.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Services related to the Nit package manager
16 module picnit_shared
17
18 # Folder where are downloaded picnit packages
19 fun picnit_lib_dir: String do do return "HOME".environ / ".local/lib/nit/"
20
21 redef class Text
22
23 # Does `self` look like a package name?
24 #
25 # ~~~
26 # assert "gamnit".is_package_name
27 # assert "n1t".is_package_name
28 # assert not ".".is_package_name
29 # assert not "./gamnit".is_package_name
30 # assert not "https://github.com/nitlang/nit.git".is_package_name
31 # assert not "git://github.com/nitlang/nit".is_package_name
32 # assert not "git@gitlab.com:xymus/gamnit.git".is_package_name
33 # assert not "4it".is_package_name
34 # ~~~
35 fun is_package_name: Bool
36 do
37 if is_empty then return false
38 if not chars.first.is_alpha then return false
39
40 for c in chars do
41 if not (c.is_alphanumeric or c == '_') then return false
42 end
43
44 return true
45 end
46
47 # Get package name from the Git address `self`
48 #
49 # Return `null` on failure.
50 #
51 # ~~~
52 # assert "https://github.com/nitlang/nit.git".git_name == "nit"
53 # assert "git://github.com/nitlang/nit".git_name == "nit"
54 # assert "gamnit".git_name == "gamnit"
55 # assert "///".git_name == null
56 # assert "file:///".git_name == "file:"
57 # ~~~
58 fun git_name: nullable String
59 do
60 var parts = split("/")
61 for part in parts.reverse_iterator do
62 if not part.is_empty then
63 return part.strip_extension(".git")
64 end
65 end
66
67 return null
68 end
69
70 # Parse the external package declaration, as declared in package.ini
71 #
72 # Return a map of `ExternalPackage` organized by the short package name,
73 # as used in imports from Nit code.
74 fun parse_import: Map[String, ExternalPackage]
75 do
76 var res = new Map[String, ExternalPackage]
77 var ids = self.split(",")
78 for id in ids do
79 id = id.chomp
80 if id.is_empty then continue
81
82 # Check version suffix (e.g. gamnit=1.0)
83 var match = id.search_last("=")
84 var package_name
85 var version = null
86 if match != null then
87 # There's a version suffix
88 package_name = id.substring(0, match.from)
89 version = id.substring_from(match.after)
90 id = package_name
91 else
92 package_name = id
93 end
94
95 # Extract a package name from a Git address
96 if not package_name.is_package_name then
97 # Assume it's a Git repository
98 var git_name = package_name.git_name
99 if git_name == null then
100 # Invalid name
101 # TODO report error only when used by the parser
102 continue
103 end
104 package_name = git_name
105 end
106
107 res[package_name] = new ExternalPackage(id, package_name, version)
108 end
109 return res
110 end
111 end
112
113 # Reference to a nitpm package
114 class ExternalPackage
115
116 # Package identifier (name or Git address), without the version
117 var id: String
118
119 # Standard Nit package name, as used in importations from Nit
120 var name: String
121
122 # Version string of the package
123 var version: nullable String
124
125 # Expected folder name for this package
126 var dir_name: String is lazy do
127 var version = version
128 if version == null then return name
129 return name + "=" + version
130 end
131 end