Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / nitpm.nit
index 526c875..0c6ed5f 100644 (file)
@@ -78,7 +78,7 @@ class CommandInstall
                                exit 1
                        end
 
-                       var ini = new ConfigTree(ini_path)
+                       var ini = new IniFile.from_file(ini_path)
                        var import_line = ini["package.import"]
                        if import_line == null then
                                print_error "The local `package.ini` declares no external dependencies."
@@ -104,11 +104,10 @@ class CommandInstall
        do
                if package_id.is_package_name then
                        # Ask a centralized server
-                       # TODO choose a future safe URL
                        # TODO customizable server list
                        # TODO parse ini file in memory
 
-                       var url = "https://xymus.net/nitpm/{package_id}.ini"
+                       var url = "https://nitlanguage.org/catalog/p/{package_id}.ini"
                        var ini_path = "/tmp/{package_id}.ini"
 
                        if verbose then print "Looking for a package description at '{url}'"
@@ -136,7 +135,7 @@ class CommandInstall
                                print ini_path.to_path.read_all
                        end
 
-                       var ini = new ConfigTree(ini_path)
+                       var ini = new IniFile.from_file(ini_path)
                        var git_repo = ini["upstream.git"]
                        if git_repo == null then
                                print_error "Package description invalid, or it does not declare a Git repository"
@@ -196,7 +195,7 @@ class CommandInstall
                end
 
                # Recursive install
-               var ini = new ConfigTree(target_dir/"package.ini")
+               var ini = new IniFile.from_file(target_dir/"package.ini")
                var import_line = ini["package.import"]
                if import_line != null then
                        install_packages import_line
@@ -247,39 +246,58 @@ class CommandUninstall
        super Command
 
        redef fun name do return "uninstall"
-       redef fun usage do return "nitpm uninstall <package>"
-       redef fun description do return "Uninstall a package"
+       redef fun usage do return "nitpm uninstall [-f] <package0>[=version] [package1 ...]"
+       redef fun description do return "Uninstall packages"
 
        redef fun apply(args)
        do
-               if args.length != 1 then
+               var opt_force = "-f"
+               var force = args.has(opt_force)
+               if force then args.remove(opt_force)
+
+               if args.is_empty then
                        print_local_help
                        exit 1
                end
 
-               var name = args.first
-               var target_dir = nitpm_lib_dir / name
+               for name in args do
 
-               if not target_dir.file_exists or not target_dir.to_path.is_dir then
-                       print_error "Package not found"
-                       exit 1
-               end
+                       var clean_nitpm_lib_dir = nitpm_lib_dir.simplify_path
+                       var target_dir = clean_nitpm_lib_dir / name
 
-               # Ask confirmation
-               var response = prompt("Delete {target_dir.escape_to_sh}? [Y/n] ")
-               var accept = response != null and
-                       (response.to_lower == "y" or response.to_lower == "yes" or response == "")
-               if not accept then return
+                       # Check validity of the package to delete
+                       target_dir = target_dir.simplify_path
+                       var within_dir = target_dir.has_prefix(clean_nitpm_lib_dir + "/") and
+                               target_dir.length > clean_nitpm_lib_dir.length + 1
+                       var valid_name = name.length > 0 and name.chars.first.is_lower
+                       if not valid_name or not within_dir then
+                               print_error "Package name '{name}' is invalid"
+                               continue
+                       end
 
-               var cmd = "rm -rf {target_dir.escape_to_sh}"
-               if verbose then print "+ {cmd}"
+                       if not target_dir.file_exists or not target_dir.to_path.is_dir then
+                               print_error "Package not found"
+                               exit 1
+                       end
 
-               var proc = new Process("sh", "-c", cmd)
-               proc.wait
+                       # Ask confirmation
+                       if not force then
+                               var response = prompt("Delete {target_dir.escape_to_sh}? [Y/n] ")
+                               var accept = response != null and
+                                       (response.to_lower == "y" or response.to_lower == "yes" or response == "")
+                               if not accept then return
+                       end
 
-               if proc.status != 0 then
-                       print_error "Uninstall failed"
-                       exit 1
+                       var cmd = "rm -rf {target_dir.escape_to_sh}"
+                       if verbose then print "+ {cmd}"
+
+                       var proc = new Process("sh", "-c", cmd)
+                       proc.wait
+
+                       if proc.status != 0 then
+                               print_error "Uninstall failed"
+                               exit 1
+                       end
                end
        end
 end
@@ -295,17 +313,30 @@ class CommandList
        redef fun apply(args)
        do
                var files = nitpm_lib_dir.files
+               var name_to_desc = new Map[String, nullable String]
+               var max_name_len = 0
+
+               # Collect package info
                for file in files do
                        var ini_path = nitpm_lib_dir / file / "package.ini"
                        if verbose then print "- Reading ini file at {ini_path}"
-                       var ini = new ConfigTree(ini_path)
+                       var ini = new IniFile.from_file(ini_path)
                        var tags = ini["package.tags"]
 
-                       if tags != null then
-                               print "{file.justify(15, 0.0)} {tags}"
-                       else
-                               print file
-                       end
+                       name_to_desc[file] = tags
+                       max_name_len = max_name_len.max(file.length)
+               end
+
+               # Sort in alphabetical order
+               var sorted_names = name_to_desc.keys.to_a
+               alpha_comparator.sort sorted_names
+
+               # Print with clear columns
+               for name in sorted_names do
+                       var col0 = name.justify(max_name_len+1, 0.0)
+                       var col1 = name_to_desc[name] or else ""
+                       var line = col0 + col1
+                       print line.trim
                end
        end
 end
@@ -339,10 +370,10 @@ redef class Sys
        var opts = new OptionContext
 
        # Help option
-       var opt_help = new OptionBool("Show this help message", "--help", "-h")
+       var opt_help = new OptionBool("Show help message", "-h", "--help")
 
        # Verbose mode option
-       var opt_verbose = new OptionBool("Print more information", "--verbose", "-v")
+       var opt_verbose = new OptionBool("Print more information", "-v", "--verbose")
        private fun verbose: Bool do return opt_verbose.value
 
        # All command line actions, mapped to their short `name`