Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / nitpm_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 nitpm_shared
17
18 # Folder where are downloaded nitpm packages
19 fun nitpm_lib_dir: String
20 do
21 var dir = "NITPM_PATH".environ
22 if not dir.is_empty then return dir
23
24 return "HOME".environ / ".local/lib/nit/"
25 end
26
27 redef class Text
28
29 # Does `self` look like a package name?
30 #
31 # ~~~
32 # assert "gamnit".is_package_name
33 # assert "n1t".is_package_name
34 # assert not ".".is_package_name
35 # assert not "./gamnit".is_package_name
36 # assert not "https://github.com/nitlang/nit.git".is_package_name
37 # assert not "git://github.com/nitlang/nit".is_package_name
38 # assert not "git@gitlab.com:xymus/gamnit.git".is_package_name
39 # assert not "4it".is_package_name
40 # ~~~
41 fun is_package_name: Bool
42 do
43 if is_empty then return false
44 if not chars.first.is_alpha then return false
45
46 for c in chars do
47 if not (c.is_alphanumeric or c == '_') then return false
48 end
49
50 return true
51 end
52
53 # Get package name from the Git address `self`
54 #
55 # Return `null` on failure.
56 #
57 # ~~~
58 # assert "https://github.com/nitlang/nit.git".git_name == "nit"
59 # assert "git://github.com/nitlang/nit".git_name == "nit"
60 # assert "gamnit".git_name == "gamnit"
61 # assert "///".git_name == null
62 # assert "file:///".git_name == "file:"
63 # ~~~
64 fun git_name: nullable String
65 do
66 var parts = split("/")
67 for part in parts.reverse_iterator do
68 if not part.is_empty then
69 return part.strip_extension(".git")
70 end
71 end
72
73 return null
74 end
75
76 # Parse the external package declaration, as declared in package.ini
77 #
78 # Return a map of `ExternalPackage` organized by the short package name,
79 # as used in imports from Nit code.
80 fun parse_import: Map[String, ExternalPackage]
81 do
82 var res = new Map[String, ExternalPackage]
83 var ids = self.split(",")
84 for id in ids do
85 id = id.chomp
86 if id.is_empty then continue
87
88 # Check version suffix (e.g. gamnit=1.0)
89 var match = id.search_last("=")
90 var package_name
91 var version = null
92 if match != null then
93 # There's a version suffix
94 package_name = id.substring(0, match.from)
95 version = id.substring_from(match.after)
96 id = package_name
97 else
98 package_name = id
99 end
100
101 # Extract a package name from a Git address
102 if not package_name.is_package_name then
103 # Assume it's a Git repository
104 var git_name = package_name.git_name
105 if git_name == null then
106 # Invalid name
107 # TODO report error only when used by the parser
108 continue
109 end
110 package_name = git_name
111 end
112
113 res[package_name] = new ExternalPackage(id, package_name, version)
114 end
115 return res
116 end
117 end
118
119 # Reference to a nitpm package
120 class ExternalPackage
121
122 # Package identifier (name or Git address), without the version
123 var id: String
124
125 # Standard Nit package name, as used in importations from Nit
126 var name: String
127
128 # Version string of the package
129 var version: nullable String
130
131 # Expected folder name for this package
132 var dir_name: String is lazy do
133 var version = version
134 if version == null then return name
135 return name + "=" + version
136 end
137 end