nitpackage: generate INI files
authorAlexandre Terrasa <alexandre@moz-code.org>
Mon, 7 May 2018 17:57:06 +0000 (13:57 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Tue, 8 May 2018 16:59:08 +0000 (12:59 -0400)
Also remove the old shell script `nit-makepackage`

Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

bin/nit-makepackage [deleted file]
share/man/nit-makepackage.md [deleted file]
src/nitpackage.nit

diff --git a/bin/nit-makepackage b/bin/nit-makepackage
deleted file mode 100755 (executable)
index a03af86..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This shell script creates (or overrides) a package.ini template file in the current directory.
-# The result must be examined and adapted.
-#
-# Default values are guessed from git and the file system.
-
-while true; do
-       case "$1" in
-               "")
-                       break
-                       ;;
-               -h|--help)
-                       echo "nit-makepackage: creates a package.ini in the current directory"
-                       echo "There is no option (yet)"
-                       exit
-                       ;;
-               *)
-                       echo >&2 "nit-makepackage does not accept options yet"
-                       exit 1
-                       ;;
-       esac
-done
-
-
-name=`basename $PWD`
-maintainer=`git shortlog -esn . | head -n 1 | sed 's/\s*[0-9]*\s*//'`
-dir=`git rev-parse --show-prefix`
-git=`git remote get-url origin`
-
-# Setup default keys.
-# The following values works for Github and Gitlab
-root=${git%.git}
-browse=$root
-homepage=$root
-if [ -n "$dir" ]; then
-       browse=$root/tree/master/$dir
-fi
-issues=$root/issues
-
-# Special cases to override
-case "$git" in
-       */nit.git)
-               # For projects on the main Nit tree
-               license=Apache-2.0
-               git=https://github.com/nitlang/nit.git
-               homepage=http://nitlanguage.org
-               root=https://github.com/nitlang/nit
-               browse=$root/tree/master/$dir
-               issues=$root/issues
-               ;;
-esac
-
-# Generate the `package.ini` file
-sed '/^$/d' > package.ini <<SUPERCALIFRAGILISTICEXPIALIDOCIOUS
-[package]
-name=$name
-tags=
-maintainer=$maintainer
-license=$license
-[upstream]
-browse=$browse
-git=$git
-`test -n "$dir" && echo "git.directory=$dir"`
-homepage=$homepage
-issues=$issues
-SUPERCALIFRAGILISTICEXPIALIDOCIOUS
diff --git a/share/man/nit-makepackage.md b/share/man/nit-makepackage.md
deleted file mode 100644 (file)
index 7569395..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# NAME
-
-nit-makepackage - helper script to setup package metadata
-
-# SYNOPSIS
-
-nit-makepackage
-
-# DESCRIPTION
-
-`nit-makepackage` creates (or overrides) a package.ini template file in the current directory.
-The result must be examined and adapted.
-
-Default values are guessed from git and the file system.
-
-# SEE ALSO
-
-The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>
index 8c1ec62..23e7be0 100644 (file)
@@ -21,12 +21,19 @@ redef class ToolContext
        # --expand
        var opt_expand = new OptionBool("Move singleton packages to their own directory", "--expand")
 
+       # --gen-ini
+       var opt_gen_ini = new OptionBool("Generate package.ini files", "--gen-ini")
+
+       # --force
+       var opt_force = new OptionBool("Force update of existing files", "-f", "--force")
+
        # README handling phase
        var readme_phase: Phase = new ReadmePhase(self, null)
 
        redef init do
                super
-               option_context.add_option(opt_expand)
+               option_context.add_option(opt_expand, opt_force)
+               option_context.add_option(opt_gen_ini)
        end
 end
 
@@ -35,7 +42,6 @@ private class ReadmePhase
 
        redef fun process_mainmodule(mainmodule, mmodules) do
                var mpackages = extract_mpackages(mmodules)
-
                for mpackage in mpackages do
 
                        # Fictive and buggy packages are ignored
@@ -55,6 +61,14 @@ private class ReadmePhase
                                        "Warning: `{mpackage}` has no package directory")
                                continue
                        end
+
+                       # Create INI file
+                       if toolcontext.opt_gen_ini.value then
+                               if not mpackage.has_ini or toolcontext.opt_force.value then
+                                       var path = mpackage.gen_ini
+                                       toolcontext.info("generated INI file `{path}`", 0)
+                               end
+                       end
                end
        end
 
@@ -89,6 +103,108 @@ redef class MPackage
 
                return new_path
        end
+
+       private var maintainer: nullable String is lazy do
+               return git_exec("git shortlog -esn . | head -n 1 | sed 's/\\s*[0-9]*\\s*//'")
+       end
+
+       private var contributors: Array[String] is lazy do
+               var contribs = git_exec("git shortlog -esn . | head -n -1 | " +
+                       "sed 's/\\s*[0-9]*\\s*//'")
+               if contribs == null then return new Array[String]
+               return contribs.split("\n")
+       end
+
+       private var git_url: nullable String is lazy do
+               var git = git_exec("git remote get-url origin")
+               if git == null then return null
+               git = git.replace("git@github.com:", "https://github.com/")
+               git = git.replace("git@gitlab.com:", "https://gitlab.com/")
+               return git
+       end
+
+       private var git_dir: nullable String is lazy do
+               return git_exec("git rev-parse --show-prefix")
+       end
+
+       private var browse_url: nullable String is lazy do
+               var git = git_url
+               if git == null then return null
+               var browse = git.replace(".git", "")
+               var dir = git_dir
+               if dir == null or dir.is_empty then return browse
+               return "{browse}/tree/master/{dir}"
+       end
+
+       private var homepage_url: nullable String is lazy do
+               var git = git_url
+               if git == null then return null
+               # Special case for nit files
+               if git.has_suffix("/nit.git") then
+                       return "http://nitlanguage.org"
+               end
+               return git.replace(".git", "")
+       end
+
+       private var issues_url: nullable String is lazy do
+               var git = git_url
+               if git == null then return null
+               return "{git.replace(".git", "")}/issues"
+       end
+
+       private var license: nullable String is lazy do
+               var git = git_url
+               if git == null then return null
+               # Special case for nit files
+               if git.has_suffix("/nit.git") then
+                       return "Apache-2.0"
+               end
+               return null
+       end
+
+       private fun git_exec(cmd: String): nullable String do
+               var path = package_path
+               if path == null then return null
+               if not is_expanded then path = path.dirname
+               with pr = new ProcessReader("sh", "-c", "cd {path} && {cmd}") do
+                       return pr.read_all.trim
+               end
+       end
+
+       private fun gen_ini: String do
+               var ini_path = self.ini_path.as(not null)
+               var ini = new ConfigTree(ini_path)
+
+               ini.update_value("package.name", name)
+               ini.update_value("package.desc", "")
+               ini.update_value("package.tags", "")
+               ini.update_value("package.maintainer", maintainer)
+               ini.update_value("package.more_contributors", contributors.join(","))
+               ini.update_value("package.license", license or else "")
+
+               ini.update_value("upstream.browse", browse_url)
+               ini.update_value("upstream.git", git_url)
+               ini.update_value("upstream.git.directory", git_dir)
+               ini.update_value("upstream.homepage", homepage_url)
+               ini.update_value("upstream.issues", issues_url)
+
+               ini.save
+               return ini_path
+       end
+end
+
+redef class ConfigTree
+       private fun update_value(key: String, value: nullable String) do
+               if value == null then return
+               if not has_key(key) then
+                       self[key] = value
+               else
+                       var old_value = self[key]
+                       if not value.is_empty and old_value != value then
+                               self[key] = value
+                       end
+               end
+       end
 end
 
 # build toolcontext