Merge: lib/core: provide default codec-aware read_char
authorJean Privat <jean@pryen.org>
Thu, 10 May 2018 22:46:06 +0000 (18:46 -0400)
committerJean Privat <jean@pryen.org>
Thu, 10 May 2018 22:46:06 +0000 (18:46 -0400)
Previous implementations of read_char were unaware of codec issues, and
used to read a byte and convert it to a code point.

For ASCII characters this was enough, but once unicode characters were
read on a char-by-char basis, wrong characters would appear.

This commit fixes this issue by using the Codec API to read a character
intelligently, and properly support multibyte encodings.

Signed-off-by: Lucas Bajolet <lucas.bajolet@gmail.com>

Pull-Request: #2648
Reviewed-by: Jean Privat <jean@pryen.org>

179 files changed:
bin/nit-makepackage [deleted file]
lib/a_star/package.ini
lib/actors/examples/chameneos-redux/Makefile [moved from lib/actors/examples/chameneos-redux/makefile with 100% similarity]
lib/actors/examples/fannkuchredux/Makefile [moved from lib/actors/examples/fannkuchredux/makefile with 100% similarity]
lib/actors/examples/mandelbrot/Makefile [moved from lib/actors/examples/mandelbrot/makefile with 100% similarity]
lib/actors/examples/simple/Makefile [moved from lib/actors/examples/simple/makefile with 100% similarity]
lib/array_debug/package.ini
lib/base64/package.ini
lib/bucketed_game/package.ini
lib/c/package.ini
lib/cartesian/package.ini
lib/combinations/package.ini
lib/config/package.ini
lib/console/package.ini
lib/core/package.ini
lib/counter/package.ini
lib/cpp/package.ini
lib/crapto/package.ini
lib/crypto/package.ini
lib/date/package.ini
lib/deriving/package.ini
lib/dummy_array/package.ini
lib/egl/package.ini
lib/emscripten/package.ini
lib/event_queue/package.ini
lib/fca/package.ini [new file with mode: 0644]
lib/filter_stream/package.ini
lib/for_abuse/package.ini
lib/gen_nit/package.ini
lib/gettext/package.ini
lib/hash_debug/package.ini
lib/ini/ini.nit
lib/ini/package.ini
lib/json/README.md
lib/json/serialization_read.nit
lib/jvm/package.ini
lib/libevent/package.ini
lib/md5/package.ini
lib/meta/package.ini
lib/more_collections/package.ini
lib/mpd/package.ini
lib/mpi/package.ini
lib/nitcc_runtime/package.ini
lib/niti_runtime/package.ini
lib/noise/package.ini
lib/opts/package.ini
lib/ordered_tree/package.ini
lib/parser_base/package.ini
lib/perfect_hashing/package.ini
lib/performance_analysis/package.ini
lib/pipeline/package.ini
lib/popcorn/package.ini
lib/poset/package.ini
lib/posix_ext/package.ini
lib/postgresql/package.ini
lib/progression/package.ini
lib/prompt/package.ini
lib/readline/package.ini
lib/realtime/package.ini
lib/ropes_debug/package.ini
lib/rubix/package.ini
lib/scene2d/package.ini
lib/sendmail/package.ini
lib/sexp/package.ini
lib/sha1/package.ini
lib/signals/package.ini
lib/standard/package.ini
lib/symbol/package.ini
lib/text_stat/package.ini
lib/vsm/package.ini [new file with mode: 0644]
lib/x11/package.ini
share/man/nit-makepackage.md [deleted file]
share/man/nitpackage.md
share/nitweb/javascripts/entities.js
share/nitweb/views/doc.html [deleted file]
share/nitweb/views/doc/contrib.html [new file with mode: 0644]
share/nitweb/views/doc/entity.html
share/nitweb/views/doc/license.html [new file with mode: 0644]
src/doc/api/api_base.nit
src/doc/api/api_model.nit
src/doc/commands/commands_html.nit
src/doc/commands/commands_ini.nit [new file with mode: 0644]
src/doc/commands/commands_json.nit
src/doc/commands/commands_main.nit [new file with mode: 0644]
src/doc/commands/commands_parser.nit
src/doc/commands/tests/test_commands.nit
src/doc/commands/tests/test_commands_catalog.nit
src/doc/commands/tests/test_commands_html.nit
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_clone.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file_content.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contributors.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_desc.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_git.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_issues.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file_content.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_maintainer.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_main_compile.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_mains.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_man_options.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_man_synopsis.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_html.sav/test_cmd_mentities.res
src/doc/commands/tests/test_commands_html.sav/test_cmd_testing.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_http.nit
src/doc/commands/tests/test_commands_ini.nit [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.nit
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_clone.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file_content.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contributors.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_desc.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_git.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_issues.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file_content.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_maintainer.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_main_compile.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_mains.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_man_options.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_man_synopsis.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_json.sav/test_cmd_mentities.res
src/doc/commands/tests/test_commands_json.sav/test_cmd_search.res
src/doc/commands/tests/test_commands_json.sav/test_cmd_testing.res [new file with mode: 0644]
src/doc/commands/tests/test_commands_main.nit [new file with mode: 0644]
src/doc/commands/tests/test_commands_model.nit
src/doc/commands/tests/test_commands_parser.nit
src/doc/templates/tests/test_templates_json.sav/test_classdefs_to_full_json.res
src/doc/templates/tests/test_templates_json.sav/test_classes_to_full_json.res
src/doc/templates/tests/test_templates_json.sav/test_groups_to_full_json.res
src/doc/templates/tests/test_templates_json.sav/test_modules_to_full_json.res
src/doc/templates/tests/test_templates_json.sav/test_propdefs_to_full_json.res
src/doc/templates/tests/test_templates_json.sav/test_props_to_full_json.res
src/doc/term/term.nit
src/doc/term/tests/test_term.nit
src/doc/term/tests/test_term.sav/test_term_catalog_stats.res
src/doc/term/tests/test_term.sav/test_term_ini_clone.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_contributors.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_desc.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_git.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_issues.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_license.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_ini_maintainer.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_main_compile.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_mains.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_man_options.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_man_synopsis.res [new file with mode: 0644]
src/doc/term/tests/test_term.sav/test_term_testing.res [new file with mode: 0644]
src/interpreter/naive_interpreter.nit
src/interpreter/primitive_types.nit [deleted file]
src/model/model_collect.nit
src/model/mpackage.nit
src/nitpackage.nit
tests/sav/nitcatalog_args1.res
tests/sav/nitdoc_args4.res
tests/sav/nitls_args7.res
tests/sav/nitsmells_args1.res
tests/sav/test_loader_args1.res
tests/sav/test_loader_args2.res
tests/sav/test_loader_args3.res
tests/sav/test_loader_args4.res
tests/sav/test_model_index_args10.res
tests/sav/test_model_index_args11.res
tests/sav/test_model_index_args13.res
tests/sav/test_model_index_args16.res
tests/sav/test_model_index_args20.res
tests/sav/test_model_index_args21.res
tests/sav/test_model_index_args8.res
tests/sav/test_model_index_args9.res
tests/sav/test_neo_args1.res
tests/sav/test_sort_perf_args1.res
tests/test_prog/CONTRIBUTING.md [new file with mode: 0644]
tests/test_prog/LICENSE.md [new file with mode: 0644]
tests/test_prog/man/test_prog.man [new file with mode: 0644]
tests/test_prog/package.ini
tests/test_prog/platform/platform.nit
tests/test_prog/tests/test_game.nit [new file with mode: 0644]

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
index 5ec2a3d..c0540d2 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/a_star.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/a_star/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/a_star.nit
+git.directory=lib/a_star/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 467aeae..33b3958 100644 (file)
@@ -4,8 +4,8 @@ tags=debug,lib
 maintainer=Alexandre Terrasa <alexandre@moz-code.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/array_debug.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/array_debug/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/array_debug.nit
+git.directory=lib/array_debug/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 7009786..4148d79 100644 (file)
@@ -4,8 +4,8 @@ tags=encoding,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/base64.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/base64/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/base64.nit
+git.directory=lib/base64/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 4824079..e9dfe5d 100644 (file)
@@ -4,8 +4,8 @@ tags=game,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/bucketed_game.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/bucketed_game/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/bucketed_game.nit
+git.directory=lib/bucketed_game/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 22850fc..72514cf 100644 (file)
@@ -4,8 +4,8 @@ tags=language,wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/c.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/c/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/c.nit
+git.directory=lib/c/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index fbdc2c4..d3f2d06 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/cartesian.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/cartesian/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/cartesian.nit
+git.directory=lib/cartesian/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index f97a0ed..a9544ef 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/combinations.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/combinations/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/combinations.nit
+git.directory=lib/combinations/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 38dbaf5..9716c31 100644 (file)
@@ -4,8 +4,8 @@ tags=config,options,ini,lib
 maintainer=Alexandre Terrasa <alexandre@moz-code.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/config.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/config/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/config.nit
+git.directory=lib/config/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 10ec43b..4f6a168 100644 (file)
@@ -4,8 +4,8 @@ tags=terminal,lib
 maintainer=Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/console.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/console/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/console.nit
+git.directory=lib/console/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 7b938af..0cfeb2e 100644 (file)
@@ -5,8 +5,8 @@ maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 more_contributors=Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>, Romain Chanoir <romain.chanoir@viacesi.fr>, Christophe Gigax <christophe.gigax@viacesi.fr>, Frédéric Vachon <fredvac@gmail.com>, Jean-Sebastien Gelinas <calestar@gmail.com>, Alexandre Blondin Massé <alexandre.blondin.masse@gmail.com>, Johan Kayser <johan.kayser@viacesi.fr>, Johann Dubois <johann.dubois@outlook.com>, Julien Pagès <julien.projet@gmail.com>
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/core
+browse=https://github.com/nitlang/nit/tree/master/lib/core/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/core
+git.directory=lib/core/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 09bda32..b6d459e 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/counter.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/counter/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/counter.nit
+git.directory=lib/counter/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index a317f35..a1b5bff 100644 (file)
@@ -4,8 +4,8 @@ tags=language,wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/cpp.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/cpp/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/cpp.nit
+git.directory=lib/cpp/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 2f9d180..87e21bd 100644 (file)
@@ -4,7 +4,7 @@ tags=crypto
 maintainer=Philippe Pépos Petitclerc <ppeposp@gmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/crapto
+browse=https://github.com/nitlang/nit/tree/master/lib/crapto/
 git=https://github.com/nitlang/nit.git
 git.directory=lib/crapto/
 homepage=http://nitlanguage.org
index 24f6b14..b3706b6 100644 (file)
@@ -4,8 +4,8 @@ tags=crypto,algo,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/crypto.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/crypto/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/crypto/crypto.nit
+git.directory=lib/crypto/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index ac74d2d..87642f8 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Mehdi Ait Younes <overpex@gmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/date.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/date/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/date.nit
+git.directory=lib/date/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 44690f8..11b0081 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/deriving.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/deriving/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/deriving.nit
+git.directory=lib/deriving/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index cc510fc..21e9fb7 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Floréal Morandat <morandat@lirmm.fr>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/dummy_array.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/dummy_array/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/dummy_array.nit
+git.directory=lib/dummy_array/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index c77b5f8..d008cf4 100644 (file)
@@ -4,8 +4,8 @@ tags=graphics,wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/egl.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/egl/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/egl.nit
+git.directory=lib/egl/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 458a8bc..130ef70 100644 (file)
@@ -4,8 +4,8 @@ tags=platform,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/emscripten
+browse=https://github.com/nitlang/nit/tree/master/lib/emscripten/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/emscripten
+git.directory=lib/emscripten/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 4d5e6ec..9ec2bdd 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/event_queue.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/event_queue/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/event_queue.nit
+git.directory=lib/event_queue/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
diff --git a/lib/fca/package.ini b/lib/fca/package.ini
new file mode 100644 (file)
index 0000000..b0cc6d0
--- /dev/null
@@ -0,0 +1,12 @@
+[package]
+name=fca
+desc=Formal Concept Analysis for Nit
+tags=fca,lib
+maintainer=Alexandre Terrasa <alexandre@moz-code.org>
+license=Apache-2.0
+[upstream]
+browse=https://github.com/nitlang/nit/tree/master/lib/fca/
+git=https://github.com/nitlang/nit.git
+git.directory=lib/fca/
+homepage=http://nitlanguage.org
+issues=https://github.com/nitlang/nit/issues
index c279e04..87706fc 100644 (file)
@@ -4,8 +4,8 @@ tags=io,lib
 maintainer=Floréal Morandat <morandat@lirmm.fr>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/filter_stream.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/filter_stream/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/filter_stream.nit
+git.directory=lib/filter_stream/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 2b768d4..ee907e4 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/for_abuse.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/for_abuse/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/for_abuse.nit
+git.directory=lib/for_abuse/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 0f1530c..169ddb4 100644 (file)
@@ -4,8 +4,8 @@ tags=devel
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/gen_nit.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/gen_nit/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/gen_nit.nit
+git.directory=lib/gen_nit/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index d4f369e..512db68 100644 (file)
@@ -4,8 +4,8 @@ tags=i18n,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/gettext
+browse=https://github.com/nitlang/nit/tree/master/lib/gettext/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/gettext
+git.directory=lib/gettext/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 075ff53..0112a9a 100644 (file)
@@ -4,8 +4,8 @@ tags=debug,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/hash_debug.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/hash_debug/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/hash_debug.nit
+git.directory=lib/hash_debug/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 5e7c671..815995f 100644 (file)
@@ -68,8 +68,9 @@ class ConfigTree
                if node == null then return null
                var map = new HashMap[String, String]
                for k, child in node.children do
-                       if child.value == null then continue
-                       map[k] = child.value.to_s
+                       var value = child.value
+                       if value == null then continue
+                       map[k] = value
                end
                return map
        end
@@ -112,18 +113,41 @@ class ConfigTree
        fun to_map: Map[String, String] do
                var map = new HashMap[String, String]
                for node in leaves do
-                       if node.value == null then continue
-                       map[node.key] = node.value.to_s
+                       var value = node.value
+                       if value == null then continue
+                       map[node.key] = value
                end
                return map
        end
 
        redef fun to_s do return to_map.join(", ", ":")
 
+       # Write `self` in `stream`
+       #
+       #     var config = new ConfigTree("config.ini")
+       #     var out = new StringWriter
+       #     config.write_to(out)
+       #     assert out.to_s == """
+       #     goo=goo
+       #     [foo]
+       #     bar=foobar
+       #     baz=foobaz
+       #     """
        redef fun write_to(stream) do
-               for node in leaves do
-                       if node.value == null then continue
-                       stream.write("{node.key}={node.value.to_s}\n")
+               var todo = new Array[ConfigNode].from(roots.reversed)
+               while not todo.is_empty do
+                       var node = todo.pop
+                       if node.children.not_empty then
+                               todo.add_all node.children.values.to_a.reversed
+                       end
+                       if node.children.not_empty and node.parent == null then
+                               stream.write("[{node.name}]\n")
+                       end
+                       var value = node.value
+                       if value == null then continue
+                       var path = node.path
+                       if path.length > 1 then path.shift
+                       stream.write("{path.join(".")}={value}\n")
                end
        end
 
@@ -234,9 +258,8 @@ class ConfigTree
        private fun set_array(key: String, value: nullable String) do
                key = key.substring(0, key.length - 2)
                var len = 0
-               if has_key(key) then
-                       len = get_node(key).children.length
-               end
+               var node = get_node(key)
+               if node != null then len = node.children.length
                set_node("{key}.{len.to_s}", value)
        end
 
@@ -306,12 +329,23 @@ private class ConfigNode
        var value: nullable String = null
 
        fun key: String do
+               var parent = self.parent
                if parent == null then
                        return name
                end
                return "{parent.key}.{name}"
        end
 
+       fun path: Array[String] do
+               var parent = self.parent
+               if parent == null then
+                       return [name]
+               end
+               var res = new Array[String].from(parent.path)
+               res.add name
+               return res
+       end
+
        fun get_child(name: String): nullable ConfigNode do
                if children.has_key(name) then
                        return children[name]
index bc1adff..896be61 100644 (file)
@@ -4,8 +4,8 @@ tags=format,lib
 maintainer=Alexandre Terrasa <alexandre@moz-code.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/ini.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/ini/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/ini.nit
+git.directory=lib/ini/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index b964d1c..94539c3 100644 (file)
@@ -107,7 +107,7 @@ The type to recreate is either declared or inferred:
 3. If all else fails, `JsonDeserializer` uses the static type of the attribute,
    or the type name passed to `deserialize`.
 
-The method `from_json_string` is a shortcut to `JsonDeserializer` which prints
+The method `deserialize_json` is a shortcut to `JsonDeserializer` which prints
 errors to the console. It is fit only for small scripts and other quick and dirty usage.
 
 ### Example
index 8dd73f7..4b71cea 100644 (file)
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Services to read JSON: `from_json_string` and `JsonDeserializer`
+# Services to read JSON: `deserialize_json` and `JsonDeserializer`
 module serialization_read
 
 import serialization::caching
@@ -364,15 +364,17 @@ redef class Text
 
        # Deserialize a `nullable Object` from this JSON formatted string
        #
+       # If a `static_type` is given, only subtypes of the `static_type` are accepted.
+       #
        # Warning: Deserialization errors are reported with `print_error` and
        # may be returned as a partial object or as `null`.
        #
        # This method is not appropriate when errors need to be handled programmatically,
        # manually use a `JsonDeserializer` in such cases.
-       fun from_json_string: nullable Object
+       fun deserialize_json(static_type: nullable String): nullable Object
        do
                var deserializer = new JsonDeserializer(self)
-               var res = deserializer.deserialize
+               var res = deserializer.deserialize(static_type)
                if deserializer.errors.not_empty then
                        print_error "Deserialization Errors: {deserializer.errors.join(", ")}"
                end
index c3a50c1..605410b 100644 (file)
@@ -4,8 +4,8 @@ tags=java,wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/jvm.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/jvm/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/jvm.nit
+git.directory=lib/jvm/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 2c8ffea..59be396 100644 (file)
@@ -4,8 +4,8 @@ tags=wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/libevent.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/libevent/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/libevent.nit
+git.directory=lib/libevent/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index c24d0d6..7818a5e 100644 (file)
@@ -4,8 +4,8 @@ tags=encoding,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/md5.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/md5/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/md5.nit
+git.directory=lib/md5/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index cc1da56..d80bb8c 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/meta.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/meta/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/meta.nit
+git.directory=lib/meta/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 44b4af9..13ea963 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/more_collections.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/more_collections/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/more_collections.nit
+git.directory=lib/more_collections/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 730b993..80276cb 100644 (file)
@@ -4,8 +4,8 @@ tags=sound,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/mpd.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/mpd/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/mpd.nit
+git.directory=lib/mpd/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 40a0e31..c5e7c26 100644 (file)
@@ -4,8 +4,8 @@ tags=parallelism,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/mpi
+browse=https://github.com/nitlang/nit/tree/master/lib/mpi/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/mpi
+git.directory=lib/mpi/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index e905712..366a36a 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/nitcc_runtime.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/nitcc_runtime/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/nitcc_runtime.nit
+git.directory=lib/nitcc_runtime/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 7103e49..536ed5a 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/niti_runtime.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/niti_runtime/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/niti_runtime.nit
+git.directory=lib/niti_runtime/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 3917ab3..ce15524 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/noise.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/noise/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/noise.nit
+git.directory=lib/noise/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index ed8a3ca..9c63322 100644 (file)
@@ -4,8 +4,8 @@ tags=cli,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/opts.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/opts/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/opts.nit
+git.directory=lib/opts/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 840bb11..b891ad0 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/ordered_tree.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/ordered_tree/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/ordered_tree.nit
+git.directory=lib/ordered_tree/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 28d65d4..48675e7 100644 (file)
@@ -4,8 +4,8 @@ tags=format,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/parser_base.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/parser_base/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/parser_base.nit
+git.directory=lib/parser_base/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index f4ce782..aed6ba6 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Julien Pagès <julien.projet@gmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/perfect_hashing.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/perfect_hashing/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/perfect_hashing.nit
+git.directory=lib/perfect_hashing/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index bcd67ff..ac0cadd 100644 (file)
@@ -4,8 +4,8 @@ tags=debug,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/performance_analysis.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/performance_analysis/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/performance_analysis.nit
+git.directory=lib/performance_analysis/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 6d11449..3deee9b 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/pipeline.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/pipeline/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/pipeline.nit
+git.directory=lib/pipeline/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 8f99b9c..a0f39b8 100644 (file)
@@ -3,7 +3,6 @@ name=popcorn
 tags=web,lib
 maintainer=Alexandre Terrasa <alexandre@moz-code.org>
 license=Apache-2.0
-version=1.0
 [upstream]
 browse=https://github.com/nitlang/nit/tree/master/lib/popcorn/
 git=https://github.com/nitlang/nit.git
index df6546f..6f6badc 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/poset.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/poset/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/poset.nit
+git.directory=lib/poset/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 680e8ee..fac19c8 100644 (file)
@@ -4,8 +4,8 @@ tags=wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/posix_ext.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/posix_ext/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/posix_ext.nit
+git.directory=lib/posix_ext/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index dc82d85..b4f3d66 100644 (file)
@@ -8,4 +8,4 @@ browse=https://github.com/nitlang/nit/tree/master/lib/postgresql/
 git=https://github.com/nitlang/nit.git
 git.directory=lib/postgresql/
 homepage=http://nitlanguage.org
-issues=https://github.com/nitlang/nit/issues
\ No newline at end of file
+issues=https://github.com/nitlang/nit/issues
index 63800ab..2948a59 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/progression.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/progression/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/progression.nit
+git.directory=lib/progression/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 815bd3b..47bb342 100644 (file)
@@ -4,8 +4,8 @@ tags=console,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/prompt.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/prompt/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/prompt.nit
+git.directory=lib/prompt/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index c7e2ee9..4d63d85 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Frédéric Vachon <fredvac@gmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/readline.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/readline/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/readline.nit
+git.directory=lib/readline/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 7ca1264..86a5aaf 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/realtime.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/realtime/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/realtime.nit
+git.directory=lib/realtime/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index e221815..addd8d1 100644 (file)
@@ -4,8 +4,8 @@ tags=debug,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/ropes_debug.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/ropes_debug/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/ropes_debug.nit
+git.directory=lib/ropes_debug/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index c644c2e..42b69b5 100644 (file)
@@ -4,8 +4,8 @@ tags=algo,lib
 maintainer=Lucas Bajolet<r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/rubix.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/rubix/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/rubix.nit
+git.directory=lib/rubix/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index c25d427..9bf435b 100644 (file)
@@ -4,8 +4,8 @@ tags=game,lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/scene2d.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/scene2d/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/scene2d.nit
+git.directory=lib/scene2d/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 5b714a3..7b0633e 100644 (file)
@@ -4,8 +4,8 @@ tags=network,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/sendmail.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/sendmail/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/sendmail.nit
+git.directory=lib/sendmail/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index bb9de0d..8a10cd3 100644 (file)
@@ -4,8 +4,8 @@ tags=format,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/sexp.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/sexp/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/sexp.nit
+git.directory=lib/sexp/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 5d1c7d5..d6f7fb9 100644 (file)
@@ -4,8 +4,8 @@ tags=encoding,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/sha1.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/sha1/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/sha1.nit
+git.directory=lib/sha1/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 24d8750..a565eb9 100644 (file)
@@ -4,8 +4,8 @@ tags=wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/signals.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/signals/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/signals.nit
+git.directory=lib/signals/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index f726f17..f0e2384 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/standard.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/standard/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/standard.nit
+git.directory=lib/standard/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index 671b668..45b1aa6 100644 (file)
@@ -4,8 +4,8 @@ tags=lib
 maintainer=Jean Privat <jean@pryen.org>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/symbol.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/symbol/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/symbol.nit
+git.directory=lib/symbol/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
index fb0ab2b..7c40a6f 100644 (file)
@@ -4,8 +4,8 @@ tags=debug,lib
 maintainer=Lucas Bajolet <r4pass@hotmail.com>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/text_stat.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/text_stat/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/text_stat.nit
+git.directory=lib/text_stat/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
diff --git a/lib/vsm/package.ini b/lib/vsm/package.ini
new file mode 100644 (file)
index 0000000..beb916e
--- /dev/null
@@ -0,0 +1,12 @@
+[package]
+name=vsm
+desc=Vector Space Modelization for Nit
+tags=nlp,vsm,lib
+maintainer=Alexandre Terrasa <alexandre@moz-code.org>
+license=Apache-2.0
+[upstream]
+browse=https://github.com/nitlang/nit/tree/master/lib/vsm/
+git=https://github.com/nitlang/nit.git
+git.directory=lib/vsm/
+homepage=http://nitlanguage.org
+issues=https://github.com/nitlang/nit/issues
index d103b5c..287ad7d 100644 (file)
@@ -4,8 +4,8 @@ tags=ui,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/x11.nit
+browse=https://github.com/nitlang/nit/tree/master/lib/x11/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/x11.nit
+git.directory=lib/x11/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
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 0c21fdb..f49bf26 100644 (file)
@@ -25,10 +25,37 @@ use the following command.
 nitpackage --expand lib/
 ~~~
 
+## Generating `package.ini` files
+
+The `--gen-ini` option is used to create `package.ini` files.
+
+For example, the following command will create a `package.ini` stub for each package
+that does not already have a one.
+
+~~~sh
+nitpackage --gen-ini lib/
+~~~
+
+The `--force` option can be used to force the creation of the INI stub even if the package
+already contains one.
+
+~~~sh
+nitpackage --gen-ini -f lib/
+~~~
+
 # OPTIONS
 
 ### `--expand`
 Move singleton packages to their own directory.
 
+### `--gen-ini`
+Generate package.ini files.
+
+### `--check-ini`
+Check package.ini files.
+
+### `-f`, `--force`
+Force update of existing files.
+
 ### `-h`, `-?`, `--help`
 Show Help (the list of options).
index 2ca4e04..4b08707 100644 (file)
                                        },
                                        controllerAs: 'vm',
                                })
+                               .state('doc.entity.license', {
+                                       url: '/license',
+                                       templateUrl: 'views/doc/license.html',
+                                       resolve: {
+                                               content: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityLicenseContent($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, content) {
+                                               this.mentity = mentity;
+                                               this.content = content;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.contrib', {
+                                       url: '/contrib',
+                                       templateUrl: 'views/doc/contrib.html',
+                                       resolve: {
+                                               content: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityContribContent($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, content) {
+                                               this.mentity = mentity;
+                                               this.content = content;
+                                       },
+                                       controllerAs: 'vm',
+                               })
                })
 
                /* Model */
                                                .error(cbErr);
                                },
 
+                               loadEntityLicenseContent: function(id, cb, cbErr) {
+                                       $http.get('/api/ini/license-content/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadEntityContribContent: function(id, cb, cbErr) {
+                                       $http.get('/api/ini/contrib-content/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadEntityGraph: function(id, cb, cbErr) {
+                                       $http.get('/api/graph/inheritance/' + id + '?format=svg&cdepth=3')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
                                search: function(q, p, n, cb, cbErr) {
                                        $http.get('/api/search?q=' + q + '&p=' + p + '&l=' + n)
                                                .success(cb)
diff --git a/share/nitweb/views/doc.html b/share/nitweb/views/doc.html
deleted file mode 100644 (file)
index abcc707..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<div class='container-fluid'>
-
-       <div ng-if='error' class='alert alert-danger' role='alert'>
-               <span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>
-               <span class='sr-only'>Error:</span>
-               <span ng-switch='error.status'>
-                       <span ng-switch-when='404'>Entity <code>{{entityId}}</code> not found!</span>
-                       <span ng-switch-default>An error occured<br/>{{error.status}}: {{error.message}}</span>
-               </span>
-       </div>
-
-       <div class='page-header'>
-               <h2><entity-signature mentity='mentity' /></h2>
-               <entity-namespace namespace='mentity.namespace' />
-       </div>
-       <div ng-switch='mentity.class_name'>
-               <div ng-switch-when='MPackage'>
-                       <div ng-include src='"/views/package.html"' />
-               </div>
-               <div ng-switch-when='MGroup'>
-                       <div ng-include src='"/views/group.html"' />
-               </div>
-               <div ng-switch-when='MModule'>
-                       <div ng-include src='"/views/module.html"' />
-               </div>
-               <div ng-switch-when='MClass'>
-                       <div ng-include src='"/views/class.html"' />
-               </div>
-               <div ng-switch-when='MClassDef'>
-                       <div ng-include src='"/views/classdef.html"' />
-               </div>
-               <div ng-switch-when='MMethod' ng-switch-when='MAttribute' ng-switch-when='MVirtualTypeProp'>
-                       <div ng-include src='"/views/property.html"' />
-               </div>
-               <div ng-switch-when='MMethodDef' ng-switch-when='MAttributeDef' ng-switch-when='MVirtualTypeDef'>
-                       <div ng-include src='"/views/propdef.html"' />
-               </div>
-       </div>
-</div>
diff --git a/share/nitweb/views/doc/contrib.html b/share/nitweb/views/doc/contrib.html
new file mode 100644 (file)
index 0000000..05f0477
--- /dev/null
@@ -0,0 +1,7 @@
+<div class='card'>
+       <div class='card-body'>
+
+               <p>Contributing rules from file <code>{{vm.content.file}}</code></p>
+               <pre ng-bind-html='vm.content.content' />
+       </div>
+</div>
index e6b559f..9480512 100644 (file)
                                <span class='glyphicon glyphicon-star'/> Grades
                        </a>
                </li>
+
+               <!-- license -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MPackage"'>
+                       <a ui-sref='.license'>
+                               <span class='glyphicon glyphicon-copyright-mark'/> License
+                       </a>
+               </li>
+
+               <!-- contrib -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MPackage"'>
+                       <a ui-sref='.contrib'>
+                               <span class='glyphicon glyphicon-gift'/> Contributing
+                       </a>
+               </li>
        </ul>
        <br>
        <ui-view />
diff --git a/share/nitweb/views/doc/license.html b/share/nitweb/views/doc/license.html
new file mode 100644 (file)
index 0000000..8644b88
--- /dev/null
@@ -0,0 +1,7 @@
+<div class='card'>
+       <div class='card-body'>
+
+               <p>License from file <code>{{vm.content.file}}</code></p>
+               <pre ng-bind-html='vm.content.content' />
+       </div>
+</div>
index 00f48af..08406a2 100644 (file)
@@ -254,3 +254,19 @@ redef class MVirtualType
        redef var web_url = mproperty.web_url is lazy
        redef var api_url = mproperty.api_url is lazy
 end
+
+redef class CmdLicenseFile
+       redef var file_url is lazy do
+               var mentity = self.mentity
+               if mentity == null then return super
+               return "{mentity.web_url}/license"
+       end
+end
+
+redef class CmdContribFile
+       redef var file_url is lazy do
+               var mentity = self.mentity
+               if mentity == null then return super
+               return "{mentity.web_url}/contrib"
+       end
+end
index e2b3473..5c92817 100644 (file)
@@ -48,6 +48,18 @@ redef class APIRouter
                use("/catalog/person/:pid", new APICatalogPerson(config))
                use("/catalog/person/:pid/maintaining", new APICatalogMaintaining(config))
                use("/catalog/person/:pid/contributing", new APICatalogContributing(config))
+
+               use("/ini/desc/:id", new APIIniDesc(config))
+               use("/ini/git/:id", new APIIniGit(config))
+               use("/ini/clone/:id", new APIIniClone(config))
+               use("/ini/issues/:id", new APIIniIssues(config))
+               use("/ini/maintainer/:id", new APIIniMaintainer(config))
+               use("/ini/contributors/:id", new APIIniContributors(config))
+               use("/ini/license/:id", new APIIniLicense(config))
+               use("/ini/license-file/:id", new APIIniLicenseFile(config))
+               use("/ini/license-content/:id", new APIIniLicenseFileContent(config))
+               use("/ini/contrib-file/:id", new APIIniContribFile(config))
+               use("/ini/contrib-content/:id", new APIIniContribFileContent(config))
        end
 end
 
@@ -299,3 +311,104 @@ class APICatalogContributing
 
        redef fun command do return new CmdCatalogContributing(config.view, config.catalog)
 end
+
+# CmdIni
+
+# Get the package description from the ini file
+#
+# `GET /ini/desc/:pid`: return the package description
+class APIIniDesc
+       super APICommand
+
+       redef fun command do return new CmdIniDescription(config.view)
+end
+
+# Get the package Git URL from the ini file
+#
+# `GET /ini/git/:pid`: return the package Git URL
+class APIIniGit
+       super APICommand
+
+       redef fun command do return new CmdIniGitUrl(config.view)
+end
+
+# Get the package Git clone command from the ini file
+#
+# `GET /ini/clone/:pid`: return the package Git clone command
+class APIIniClone
+       super APICommand
+
+       redef fun command do return new CmdIniCloneCommand(config.view)
+end
+
+# Get the package issues URL from the ini file
+#
+# `GET /ini/issues/:pid`: return the package issues URL
+class APIIniIssues
+       super APICommand
+
+       redef fun command do return new CmdIniIssuesUrl(config.view)
+end
+
+# Get the package maintainer from the ini file
+#
+# `GET /ini/maintainer/:pid`: return the package maintainer
+class APIIniMaintainer
+       super APICommand
+
+       redef fun command do return new CmdIniMaintainer(config.view)
+end
+
+# Get the package contributors from the ini file
+#
+# `GET /ini/clone/:pid`: return the package contributors
+class APIIniContributors
+       super APICommand
+
+       redef fun command do return new CmdIniContributors(config.view)
+end
+
+# Get the package license from the ini file
+#
+# `GET /ini/clone/:pid`: return the package license
+class APIIniLicense
+       super APICommand
+
+       redef fun command do return new CmdIniLicense(config.view)
+end
+
+# Get the package license file
+#
+# `GET /ini/license-file/:pid`: return the package license file
+class APIIniLicenseFile
+       super APICommand
+
+       redef fun command do return new CmdLicenseFile(config.view)
+end
+
+# Get the package contrib file
+#
+# `GET /ini/contrib-file/:pid`: return the package contrib file
+class APIIniContribFile
+       super APICommand
+
+       redef fun command do return new CmdContribFile(config.view)
+end
+
+# Get the package license file content
+#
+# `GET /ini/license-file/:pid`: return the package license file content
+class APIIniLicenseFileContent
+       super APICommand
+
+       redef fun command do return new CmdLicenseFileContent(config.view)
+end
+
+# Get the package contrib file content
+#
+# `GET /ini/contrib-file/:pid`: return the package contrib file content
+class APIIniContribFileContent
+       super APICommand
+
+       redef fun command do return new CmdContribFileContent(config.view)
+end
index 7822eb2..8cffb32 100644 (file)
@@ -17,6 +17,8 @@ module commands_html
 
 import commands::commands_graph
 import commands::commands_usage
+import commands::commands_ini
+import commands::commands_main
 
 import templates::templates_html
 import doc_down
@@ -171,3 +173,152 @@ redef class CmdGraph
                return output.write_to_string
        end
 end
+
+# Ini commands
+
+redef class CmdIniDescription
+       redef fun to_html do
+               var desc = self.desc
+               if desc == null then return ""
+
+               return "<p>{desc}</p>"
+       end
+end
+
+redef class CmdIniGitUrl
+       redef fun to_html do
+               var url = self.url
+               if url == null then return ""
+
+               return "<a href=\"{url}\">{url}</a>"
+       end
+end
+
+redef class CmdIniCloneCommand
+       redef fun to_html do
+               var command = self.command
+               if command == null then return ""
+
+               return "<pre>{command}</pre>"
+       end
+end
+
+redef class CmdIniIssuesUrl
+       redef fun to_html do
+               var url = self.url
+               if url == null then return ""
+
+               return "<a href=\"{url}\">{url}</a>"
+       end
+end
+
+redef class CmdIniMaintainer
+       redef fun to_html do
+               var name = self.maintainer
+               if name == null then return ""
+
+               return "<b>{name.html_escape}</b>"
+       end
+end
+
+redef class CmdIniContributors
+       redef fun to_html do
+               var names = self.contributors
+               if names == null or names.is_empty then return ""
+
+               var tpl = new Template
+               tpl.add "<ul>"
+               for name in names do
+                       tpl.add "<li><b>{name.html_escape}</b></li>"
+               end
+               tpl.add "</ul>"
+               return tpl.write_to_string
+       end
+end
+
+redef class CmdIniLicense
+       redef fun to_html do
+               var license = self.license
+               if license == null then return ""
+
+               return "<a href=\"https://opensource.org/licenses/{license}\">{license}</a>"
+       end
+end
+
+redef class CmdEntityFile
+
+       # URL to the file
+       #
+       # Can be refined in subtools.
+       var file_url: nullable String = file is lazy, writable
+
+       redef fun to_html do
+               var file = self.file
+               if file == null then return ""
+
+               return "<a href=\"{file_url or else ""}\">{file.basename}</a>"
+       end
+end
+
+redef class CmdEntityFileContent
+       redef fun to_html do
+               var content = self.content
+               if content == null then return ""
+
+               return "<pre>{content}</pre>"
+       end
+end
+
+# Main commands
+
+redef class CmdMains
+       redef fun to_html do return super # FIXME lin
+end
+
+redef class CmdMainCompile
+       redef fun to_html do
+               var command = self.command
+               if command == null then return ""
+
+               return "<pre>{command}</pre>"
+       end
+end
+
+redef class CmdManSynopsis
+       redef fun to_html do
+               var synopsis = self.synopsis
+               if synopsis == null then return ""
+
+               return "<pre>{synopsis}</pre>"
+       end
+end
+
+redef class CmdManOptions
+       redef fun to_html do
+               var options = self.options
+               if options == null or options.is_empty then return ""
+
+               var tpl = new Template
+               tpl.addn "<pre>"
+               tpl.addn "<table width='100%'>"
+               for opt, desc in options do
+                       tpl.addn "<tr>"
+                       tpl.addn "<th valign='top' width='30%'>{opt}</th>"
+                       tpl.addn "<td width='70%'>{desc}</td>"
+                       tpl.addn "</tr>"
+               end
+               tpl.addn "</table>"
+               tpl.addn "</pre>"
+
+               return tpl.write_to_string
+       end
+end
+
+redef class CmdTesting
+       redef fun to_html do
+               var command = self.command
+               if command == null then return ""
+
+               return "<pre>{command}</pre>"
+       end
+end
diff --git a/src/doc/commands/commands_ini.nit b/src/doc/commands/commands_ini.nit
new file mode 100644 (file)
index 0000000..9274fd0
--- /dev/null
@@ -0,0 +1,361 @@
+# 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.
+
+module commands_ini
+
+import doc::commands::commands_model
+
+# Cmd that finds the ini file related to an `mentity`
+abstract class CmdIni
+       super CmdEntity
+
+       # Ini file
+       var ini: nullable ConfigTree = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+
+               if not mentity isa MPackage then return new WarningNoIni(mentity)
+
+               var ini = mentity.ini
+               if ini == null then return new WarningNoIni(mentity)
+
+               self.ini = ini
+
+               return res
+       end
+end
+
+# No ini file for `mentity`
+class WarningNoIni
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No ini file for `{mentity.full_name}`"
+end
+
+# Cmd that finds the ini description related to an `mentity`
+class CmdIniDescription
+       super CmdIni
+
+       # Ini description
+       var desc: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var desc = ini["package.desc"]
+               if desc == null then return new WarningNoDescription(mentity)
+               self.desc = desc
+
+               return res
+       end
+end
+
+# No git clone url for `mentity`
+class WarningNoDescription
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No description for `{mentity.full_name}`"
+end
+
+# Cmd that finds the clone url related to an `mentity`
+class CmdIniGitUrl
+       super CmdIni
+
+       # Clone url
+       var url: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var url = ini["upstream.git"]
+               if url == null then return new WarningNoGitUrl(mentity)
+               self.url = url
+
+               return res
+       end
+end
+
+# No git url for `mentity`
+class WarningNoGitUrl
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No git url for `{mentity.full_name}`"
+end
+
+# Cmd that finds the git clone command related to an `mentity`
+class CmdIniCloneCommand
+       super CmdIniGitUrl
+
+       # Clone command
+       var command: nullable String is lazy do
+               var url = self.url
+               if url == null then return null
+               return "git clone {url}"
+       end
+end
+
+# Cmd that finds the issues link related to an `mentity`
+class CmdIniIssuesUrl
+       super CmdIni
+
+       # Issues url
+       var url: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var url = ini["upstream.issues"]
+               if url == null then return new WarningNoIssuesUrl(mentity)
+               self.url = url
+
+               return res
+       end
+end
+
+# No issues url for `mentity`
+class WarningNoIssuesUrl
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No issues url for `{mentity.full_name}`"
+end
+
+# Cmd that finds the maintainer name of an `mentity`
+class CmdIniMaintainer
+       super CmdIni
+
+       # Maintainer name
+       var maintainer: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var maintainer = ini["package.maintainer"]
+               if maintainer == null then return new WarningNoMaintainer(mentity)
+               self.maintainer = maintainer
+
+               return res
+       end
+end
+
+# No maintainer for `mentity`
+class WarningNoMaintainer
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No maintainer for `{mentity.full_name}`"
+end
+
+# Cmd that finds the contributors list of an `mentity`
+class CmdIniContributors
+       super CmdIni
+
+       # Contributors list
+       var contributors: nullable Array[String] = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var names = ini["package.more_contributors"]
+               if names == null then return new WarningNoContributor(mentity)
+
+               var contributors = new Array[String]
+               for name in names.split(",") do
+                       contributors.add name.trim
+               end
+               if contributors.is_empty then return new WarningNoContributor(mentity)
+               self.contributors = contributors
+
+               return res
+       end
+end
+
+# No contributor for `mentity`
+class WarningNoContributor
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No contributor for `{mentity.full_name}`"
+end
+
+# Cmd that finds the license related to an `mentity`
+class CmdIniLicense
+       super CmdIni
+
+       # License string
+       var license: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var mentity = self.mentity.as(not null)
+               var ini = self.ini.as(not null)
+
+               var license = ini["package.license"]
+               if license == null then return new WarningNoLicense(mentity)
+               self.license = license
+
+               return res
+       end
+end
+
+# No ini license string for `mentity`
+class WarningNoLicense
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No license for `{mentity.full_name}`"
+end
+
+abstract class CmdEntityFile
+       super CmdEntity
+
+       # File path
+       var file: nullable String = null is writable
+
+       # Accepted file names
+       fun file_names: Array[String] is abstract
+
+       # Init file related data
+       fun init_file: CmdMessage do
+               var mentity = self.mentity.as(not null)
+
+               var source_file = mentity.location.file
+               if source_file == null then return throw_warning
+
+               for file_name in file_names do
+                       var file = source_file.filename / file_name
+                       if not file.file_exists then continue
+                       self.file = file
+                       break
+               end
+
+               if file == null then return throw_warning
+
+               return new CmdSuccess
+       end
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               return init_file
+       end
+
+       fun throw_warning: CmdWarning is abstract
+end
+
+abstract class CmdEntityFileContent
+       super CmdEntityFile
+
+       # File content
+       var content: nullable String = null is writable
+
+       redef fun init_file do
+               var res = super
+               if not res isa CmdSuccess then return res
+
+               var file = self.file.as(not null)
+               content = file.to_path.read_all
+               return res
+       end
+end
+
+# Cmd that finds the license file related to an `mentity`
+class CmdLicenseFile
+       super CmdEntityFile
+
+       redef var file_names = ["LICENSE", "LICENSE.md", "LICENSE.txt"]
+       redef fun throw_warning do return new WarningNoLicenseFile(mentity.as(not null))
+end
+
+# Cmd that finds the license file content related to an `mentity`
+class CmdLicenseFileContent
+       super CmdEntityFileContent
+       super CmdLicenseFile
+end
+
+# No license file for `mentity`
+class WarningNoLicenseFile
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No license file for `{mentity.full_name}`"
+end
+
+# Cmd that finds the contributing file related to an `mentity`
+class CmdContribFile
+       super CmdEntityFile
+
+       redef var file_names = ["CONTRIBUTING", "CONTRIBUTING.md", "CONTRIBUTING.txt"]
+       redef fun throw_warning do return new WarningNoContribFile(mentity.as(not null))
+end
+
+# Cmd that finds the contrib file content related to an `mentity`
+class CmdContribFileContent
+       super CmdEntityFileContent
+       super CmdContribFile
+end
+
+# No license file for `mentity`
+class WarningNoContribFile
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No contributing file for `{mentity.full_name}`"
+end
index bb04ad8..b109c87 100644 (file)
@@ -19,6 +19,8 @@ import commands::commands_model
 import commands::commands_graph
 import commands::commands_usage
 import commands::commands_catalog
+import commands::commands_ini
+import commands::commands_main
 
 import templates::templates_json
 import catalog::catalog_json
@@ -161,3 +163,135 @@ redef class CmdCatalogContributing
                return obj
        end
 end
+
+# CmdIni
+
+redef class CmdIniDescription
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["desc"] = desc
+               return obj
+       end
+end
+
+redef class CmdIniGitUrl
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["url"] = url
+               return obj
+       end
+end
+
+redef class CmdIniCloneCommand
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["command"] = command
+               return obj
+       end
+end
+
+redef class CmdIniIssuesUrl
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["url"] = url
+               return obj
+       end
+end
+
+redef class CmdIniMaintainer
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["maintainer"] = maintainer
+               return obj
+       end
+end
+
+redef class CmdIniContributors
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["contributors"] = contributors
+               return obj
+       end
+end
+
+redef class CmdIniLicense
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["license"] = license
+               return obj
+       end
+end
+
+redef class CmdLicenseFile
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["file"] = file
+               return obj
+       end
+end
+
+redef class CmdLicenseFileContent
+       redef fun to_json do
+               var obj = super.as(JsonObject)
+               obj["content"] = content
+               return obj
+       end
+end
+
+redef class CmdContribFile
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["file"] = file
+               return obj
+       end
+end
+
+redef class CmdContribFileContent
+       redef fun to_json do
+               var obj = super.as(JsonObject)
+               obj["content"] = content
+               return obj
+       end
+end
+
+# CmdMain
+
+redef class CmdMains
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["results"] = results
+               return obj
+       end
+end
+
+redef class CmdMainCompile
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["command"] = command
+               return obj
+       end
+end
+
+redef class CmdTesting
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["command"] = command
+               return obj
+       end
+end
+
+redef class CmdManSynopsis
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["synopsis"] = synopsis
+               return obj
+       end
+end
+
+redef class CmdManOptions
+       redef fun to_json do
+               var obj = new JsonObject
+               obj["options"] = options
+               return obj
+       end
+end
diff --git a/src/doc/commands/commands_main.nit b/src/doc/commands/commands_main.nit
new file mode 100644 (file)
index 0000000..851b79e
--- /dev/null
@@ -0,0 +1,335 @@
+# 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.
+
+module commands_main
+
+import doc::commands::commands_model
+
+# Cmd that finds the mains of an `mentity`
+class CmdMains
+       super CmdEntityList
+
+       redef fun init_results do
+               if results != null then return new CmdSuccess
+
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+               var mentities = new Array[MEntity]
+
+               if mentity isa MPackage then
+                       for mmodule in mentity.collect_all_mmodules(view) do
+                               if mmodule_has_main(mmodule) then mentities.add mmodule
+                       end
+               else if mentity isa MGroup then
+                       for mmodule in mentity.collect_all_mmodules(view) do
+                               if mmodule_has_main(mmodule) then mentities.add mmodule
+                       end
+               else if mentity isa MModule then
+                       if mmodule_has_main(mentity) then mentities.add mentity
+               else
+                       return new WarningNoMains(mentity)
+               end
+
+               if mentities.is_empty then return new WarningNoMains(mentity)
+
+               self.results = mentities
+               return res
+       end
+
+       # Does `mmodule` has a `main` method?
+       private fun mmodule_has_main(mmodule: MModule): Bool do
+               for mclassdef in mmodule.collect_redef_mclassdefs(view) do
+                       if mclassdef.name != "Sys" then continue
+                       for mpropdef in mclassdef.collect_redef_mpropdefs(view) do
+                               if mpropdef.name == "main" then return true
+                       end
+               end
+               return false
+       end
+end
+
+# No tests for `mentity`
+class WarningNoMains
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No main found for `{mentity.full_name}`"
+end
+
+# Cmd that finds the nitc command related to an `mentity`
+class CmdMainCompile
+       super CmdEntity
+
+       var file: nullable SourceFile = null
+
+       var command: nullable String is lazy do
+               var path = test_path(file)
+               if path == null then return null
+               return "nitc {path}"
+       end
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+
+               if mentity isa MModule then
+                       file = mmodule_main(mentity)
+                       if file == null then return new WarningNoMain(mentity)
+               else
+                       return new WarningNoMain(mentity)
+               end
+               return res
+       end
+
+       # Does `mmodule` has a `main` method?
+       private fun mmodule_main(mmodule: MModule): nullable SourceFile do
+               for mclassdef in mmodule.mclassdefs do
+                       if mclassdef.name != "Sys" then continue
+                       for mpropdef in mclassdef.mpropdefs do
+                               if mpropdef.name == "main" then return mmodule.location.file
+                       end
+               end
+               return null
+       end
+
+       # Return the sourcefile path
+       #
+       # This method exists for the only purpose to be redefined by nitunit tests
+       # to avoid path diffs.
+       private fun test_path(file: nullable SourceFile): nullable String do
+               if file == null then return null
+               var base_path = mentity.as(MModule).mpackage.as(not null).location.file.as(not null).filename
+               return file.filename.replace(base_path, "")
+       end
+end
+
+# No tests for `mentity`
+class WarningNoMain
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No main to compile for `{mentity.full_name}`"
+end
+
+# Cmd that finds the nitunit command related to an `mentity`
+class CmdTesting
+       super CmdEntityList
+
+       var command: nullable String is lazy do
+               var results = self.results
+               if results == null then return null
+
+               var tpl = new Template
+               tpl.add "nitunit"
+               for result in results do
+                       var path = test_path(result)
+                       if path == null then continue
+                       tpl.add " {path}"
+               end
+               return tpl.write_to_string
+       end
+
+       redef fun init_results do
+               if results != null then return new CmdSuccess
+
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+
+               var mentities = new Array[MEntity]
+               if not mentity isa MPackage then return new WarningNoTest(mentity)
+
+               for mgroup in mentity.collect_all_mgroups(view) do
+                       if mgroup.is_test then
+                               mentities.add mgroup
+                               continue
+                       end
+                       for mmodule in mgroup.collect_mmodules(view) do
+                               if mmodule.is_test then mentities.add mmodule
+                       end
+               end
+
+               if mentities.is_empty then return new WarningNoTest(mentity)
+
+               self.results = mentities
+               return res
+       end
+
+       # Return the mentity path
+       #
+       # This method exists for the only purpose to be redefined by nitunit tests
+       # to avoid path diffs.
+       private fun test_path(mentity: MEntity): nullable String do
+               var file = mentity.location.file
+               if file == null then return null
+               var base_path = self.mentity.as(not null).location.file.as(not null).filename
+               return file.filename.replace(base_path, "")
+       end
+end
+
+# No tests for `mentity`
+class WarningNoTest
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No nitunit files for `{mentity.full_name}`"
+end
+
+# Cmd that finds the man file related to an `mentity`
+class CmdManFile
+       super CmdEntity
+
+       # Man file
+       var file: nullable String = null
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+
+               var mpackage = null
+               if mentity isa MPackage then
+                       mpackage = mentity
+               else if mentity isa MGroup then
+                       mpackage = mentity.mpackage
+               else if mentity isa MModule then
+                       mpackage = mentity.mpackage
+               end
+
+               if mpackage == null then return new WarningNoManFile(mentity)
+
+               var source_file = mpackage.location.file
+               if source_file == null then return new WarningNoManFile(mentity)
+
+               var man_dir = source_file.filename / "man"
+               if not man_dir.file_exists then return new WarningNoManFile(mentity)
+
+               var man_file = null
+               for file in man_dir.files do
+                       if not file.has_prefix(mentity.name) then continue
+                       man_file = man_dir / file
+               end
+               if man_file == null then return new WarningNoManFile(mentity)
+
+               self.file = man_file
+
+               return res
+       end
+end
+
+# No man file for `mentity`
+class WarningNoManFile
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No man file for `{mentity.full_name}`"
+end
+
+class CmdManSynopsis
+       super CmdManFile
+
+       # Synopsis string extracted from man
+       var synopsis: nullable String
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+               var file = self.file.as(not null)
+
+               var lines = file.to_path.read_lines
+               var in_synopsis = false
+               for line in lines do
+                       if in_synopsis and line.has_prefix(mentity.name) then
+                               synopsis = line
+                               break
+                       end
+                       if line != "# SYNOPSIS" then continue
+                       in_synopsis = true
+               end
+
+               if synopsis == null then return new WarningNoManSynopsis(mentity)
+
+               return res
+       end
+end
+
+# No synopsis found in the man file for `mentity`
+class WarningNoManSynopsis
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No synopsis found in the man file for `{mentity.full_name}`"
+end
+
+class CmdManOptions
+       super CmdManFile
+
+       # Options description
+       var options: nullable ArrayMap[String, String]
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+               var file = self.file.as(not null)
+
+               var options = new ArrayMap[String, String]
+
+               var lines = file.to_path.read_lines
+               var in_options = false
+               for i in [0 .. lines.length[ do
+                       var line = lines[i]
+                       if line == "# OPTIONS" then
+                               in_options = true
+                       else if in_options and line.has_prefix("### ") then
+                               var opt = line.substring(4, line.length).trim.replace("`", "")
+                               var desc = ""
+                               if i < lines.length - 1 then
+                                       desc = lines[i + 1].trim
+                               end
+                               options[opt] = desc
+                       else if line.has_prefix("# ") then
+                               in_options = false
+                       end
+               end
+
+               if options.is_empty then return new WarningNoManOptions(mentity)
+               self.options = options
+
+               return res
+       end
+end
+
+# No options description found in the man file for `mentity`
+class WarningNoManOptions
+       super CmdWarning
+
+       # MEntity provided
+       var mentity: MEntity
+
+       redef fun to_s do return "No options description found in the man file for `{mentity.full_name}`"
+end
index a6b439e..77fdd25 100644 (file)
@@ -21,6 +21,8 @@ import commands::commands_model
 import commands::commands_graph
 import commands::commands_usage
 import commands::commands_catalog
+import commands::commands_ini
+import commands::commands_main
 
 # Parse string commands to create DocQueries
 class CommandParser
@@ -39,6 +41,9 @@ class CommandParser
        "link", "doc", "code", "lin", "uml", "graph", "search",
        "parents", "ancestors", "children", "descendants",
        "param", "return", "new", "call", "defs", "list", "random",
+       "ini-desc", "ini-git", "ini-issues", "ini-maintainer", "ini-contributors", "ini-license",
+       "license-file", "contrib-file", "license-content", "contrib-content", "git-clone",
+       "mains", "main-compile", "main-run", "main-opts", "testing",
        "catalog", "stats", "tags", "tag", "person", "contrib", "maintain"] is writable
 
        # List of commands usage and documentation
@@ -68,6 +73,24 @@ class CommandParser
                usage["tag: <tag>"] = "list all packages with `tag`"
                usage["maintain: <person>"] = "list all packages maintained by `person`"
                usage["contrib: <person>"] = "list all packages contributed by `person`"
+               # Ini commands
+               usage["ini-desc: <package>"] = "display the description from the `package` ini file"
+               usage["ini-git: <package>"] = "display the git url from the `package` ini file"
+               usage["ini-issues: <package>"] = "display the issues url from the `package` ini file"
+               usage["ini-license: <package>"] = "display the license from the `package` ini file"
+               usage["ini-maintainer: <package>"] = "display the maintainer from the `package` ini file"
+               usage["ini-contributors: <package>"] = "display the contributors from the `package` ini file"
+               usage["license-file: <package>"] = "display the license file for the `package`"
+               usage["license-content: <package>"] = "display the license file content for the `package`"
+               usage["contrib-file: <package>"] = "display the contrib file for the `package`"
+               usage["contrib-content: <package>"] = "display the contrib file content for the `package`"
+               usage["git-clone: <package>"] = "display the git clone command for the `package`"
+               # Main
+               usage["mains: <name>"] = "display the list of main methods for `name`"
+               usage["main-compile: <name>"] = "display the nitc command to compile `name`"
+               usage["main-run: <name>"] = "display the command to run `name`"
+               usage["main-opts: <name>"] = "display the command options for `name`"
+               usage["testing: <name>"] = "display the nitunit command to test `name`"
                return usage
        end
 
@@ -174,6 +197,24 @@ class CommandParser
                # CmdModel
                if name == "list" then return new CmdModelEntities(view)
                if name == "random" then return new CmdRandomEntities(view)
+               # Ini
+               if name == "ini-desc" then return new CmdIniDescription(view)
+               if name == "ini-git" then return new CmdIniGitUrl(view)
+               if name == "ini-issues" then return new CmdIniIssuesUrl(view)
+               if name == "ini-license" then return new CmdIniLicense(view)
+               if name == "ini-maintainer" then return new CmdIniMaintainer(view)
+               if name == "ini-contributors" then return new CmdIniContributors(view)
+               if name == "license-file" then return new CmdLicenseFile(view)
+               if name == "license-content" then return new CmdLicenseFileContent(view)
+               if name == "contrib-file" then return new CmdContribFile(view)
+               if name == "contrib-content" then return new CmdContribFileContent(view)
+               if name == "git-clone" then return new CmdIniCloneCommand(view)
+               # CmdMain
+               if name == "mains" then return new CmdMains(view)
+               if name == "main-compile" then return new CmdMainCompile(view)
+               if name == "main-run" then return new CmdManSynopsis(view)
+               if name == "main-opts" then return new CmdManOptions(view)
+               if name == "testing" then return new CmdTesting(view)
                # CmdCatalog
                var catalog = self.catalog
                if catalog != null then
index d91701b..c5d03a3 100644 (file)
@@ -58,7 +58,7 @@ class TestCommands
                var filters = new ModelFilter(
                        private_visibility,
                        accept_fictive = false,
-                       accept_test = false)
+                       accept_test = true)
 
                test_builder = modelbuilder
                test_view = new ModelView(model, mainmodule, filters)
index 9d60706..07e82d8 100644 (file)
@@ -57,7 +57,7 @@ class TestCommandsCatalog
        end
 
        fun test_cmd_catalog_search is test do
-               var cmd = new CmdCatalogSearch(test_view, test_catalog, "test")
+               var cmd = new CmdCatalogSearch(test_view, test_catalog, "testprog")
                var res = cmd.init_command
                assert res isa CmdSuccess
                assert cmd.results.as(not null).first.full_name == "test_prog"
index fefb1c7..4b2373b 100644 (file)
@@ -15,6 +15,7 @@
 module test_commands_html is test
 
 import test_commands
+intrude import doc::commands::commands_main
 import doc::commands::commands_html
 
 class TestCommandsHtml
@@ -129,4 +130,125 @@ class TestCommandsHtml
                cmd.init_command
                print_html cmd.to_html
        end
+
+       # CmdIni
+
+       fun test_cmd_ini_desc is test do
+               var cmd = new CmdIniDescription(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_git is test do
+               var cmd = new CmdIniGitUrl(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_clone is test do
+               var cmd = new CmdIniCloneCommand(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_issues is test do
+               var cmd = new CmdIniIssuesUrl(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_maintainer is test do
+               var cmd = new CmdIniMaintainer(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_contributors is test do
+               var cmd = new CmdIniContributors(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_license is test do
+               var cmd = new CmdIniLicense(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_license_file is test do
+               var cmd = new CmdLicenseFile(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_license_file_content is test do
+               var cmd = new CmdLicenseFileContent(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_contrib_file is test do
+               var cmd = new CmdContribFile(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_ini_contrib_file_content is test do
+               var cmd = new CmdContribFileContent(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_html cmd.to_html
+       end
+
+       # CmdMain
+
+       fun test_cmd_mains is test do
+               var cmd = new CmdMains(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_main_compile is test do
+               var cmd = new CmdMainCompile(test_view, mentity_name = "test_prog::test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_testing is test do
+               var cmd = new CmdTesting(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_man_synopsis is test do
+               var cmd = new CmdManSynopsis(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+
+       fun test_cmd_man_options is test do
+               var cmd = new CmdManOptions(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_html cmd.to_html
+       end
+end
+
+# Avoid path diff
+redef class CmdMainCompile
+       redef fun test_path(file) do
+               if file == null then return null
+               return file.filename.basename
+       end
+end
+
+# Avoid path diff
+redef class CmdTesting
+       redef fun test_path(mentity) do
+               var file = mentity.location.file
+               if file == null then return null
+               return file.filename.basename
+       end
 end
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_clone.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_clone.res
new file mode 100644 (file)
index 0000000..10b2095
--- /dev/null
@@ -0,0 +1 @@
+<pre>git clone https://github.com/nitlang/nit.git</pre>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file.res
new file mode 100644 (file)
index 0000000..f5a98d5
--- /dev/null
@@ -0,0 +1 @@
+<a href="CONTRIBUTING.md">CONTRIBUTING.md</a>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file_content.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contrib_file_content.res
new file mode 100644 (file)
index 0000000..263fd6e
--- /dev/null
@@ -0,0 +1,6 @@
+<pre># Contributing rules
+
+* Be nice
+* Be polite
+* Code well
+</pre>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contributors.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_contributors.res
new file mode 100644 (file)
index 0000000..b7d0788
--- /dev/null
@@ -0,0 +1 @@
+<ul><li><b>Riri &lt;riri@example.com&gt;</b></li><li><b>Fifi (http:&#47;&#47;www.example.com&#47;~fifi)</b></li><li><b>Loulou</b></li></ul>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_desc.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_desc.res
new file mode 100644 (file)
index 0000000..9d0fc44
--- /dev/null
@@ -0,0 +1 @@
+<p>Dummy program used for testing Nit tools</p>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_git.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_git.res
new file mode 100644 (file)
index 0000000..eea5e14
--- /dev/null
@@ -0,0 +1 @@
+<a href="https://github.com/nitlang/nit.git">https://github.com/nitlang/nit.git</a>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_issues.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_issues.res
new file mode 100644 (file)
index 0000000..d8061a2
--- /dev/null
@@ -0,0 +1 @@
+<a href="https://github.com/nitlang/nit/issues">https://github.com/nitlang/nit/issues</a>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license.res
new file mode 100644 (file)
index 0000000..ad3fca1
--- /dev/null
@@ -0,0 +1 @@
+<a href="https://opensource.org/licenses/Apache-2.0">Apache-2.0</a>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file.res
new file mode 100644 (file)
index 0000000..a8582ab
--- /dev/null
@@ -0,0 +1 @@
+<a href="LICENSE.md">LICENSE.md</a>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file_content.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_license_file_content.res
new file mode 100644 (file)
index 0000000..3e31799
--- /dev/null
@@ -0,0 +1,4 @@
+<pre># My Custom License
+
+This is the license content.
+</pre>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_maintainer.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_ini_maintainer.res
new file mode 100644 (file)
index 0000000..bef5956
--- /dev/null
@@ -0,0 +1 @@
+<b>John Doe &lt;jdoe@example.com&gt; (http:&#47;&#47;www.example.com&#47;~jdoe), Spider-Man</b>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_main_compile.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_main_compile.res
new file mode 100644 (file)
index 0000000..2a95dcb
--- /dev/null
@@ -0,0 +1 @@
+<pre>nitc test_prog.nit</pre>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_mains.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_mains.res
new file mode 100644 (file)
index 0000000..e00f6c0
--- /dev/null
@@ -0,0 +1 @@
+<ul><li><a href="test_prog_58d_58dtest_prog" title="A test program with a fake model to check model tools.">test_prog</a> - <span class="synopsys nitdoc">A test program with a fake model to check model tools.</span></li></ul>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_man_options.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_man_options.res
new file mode 100644 (file)
index 0000000..876cee2
--- /dev/null
@@ -0,0 +1,13 @@
+<pre>
+<table width='100%'>
+<tr>
+<th valign='top' width='30%'>--opt1</th>
+<td width='70%'>Option 1.</td>
+</tr>
+<tr>
+<th valign='top' width='30%'>--opt2</th>
+<td width='70%'>Option 2.</td>
+</tr>
+</table>
+</pre>
+
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_man_synopsis.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_man_synopsis.res
new file mode 100644 (file)
index 0000000..ca4525e
--- /dev/null
@@ -0,0 +1 @@
+<pre>test_prog [*options*] ARGS...</pre>
index 91afe93..59e52b3 100644 (file)
@@ -1 +1 @@
-<ul><li><a href="test_prog_58d_58dcareers" title="Careers of the game.">careers</a> - <span class="synopsys nitdoc">Careers of the game.</span></li><li><a href="test_prog_58d_58dcharacter" title="Characters are playable entity in the world.">character</a> - <span class="synopsys nitdoc">Characters are playable entity in the world.</span></li><li><a href="test_prog_58d_58dcombat" title="COmbat interactions between characters.">combat</a> - <span class="synopsys nitdoc">COmbat interactions between characters.</span></li><li><a href="excluded_58d_58dexcluded">excluded</a></li><li><a href="test_prog_58d_58dgame" title="A game abstraction for RPG.">game</a> - <span class="synopsys nitdoc">A game abstraction for RPG.</span></li><li><a href="test_prog_58d_58dgame_examples">game_examples</a></li><li><a href="test_prog_58d_58dplatform" title="Declares base types allowed on the platform.">platform</a> - <span class="synopsys nitdoc">Declares base types allowed on the platform.</span></li><li><a href="test_prog_58d_58draces" title="Races of the game.">races</a> - <span class="synopsys nitdoc">Races of the game.</span></li><li><a href="test_prog_58d_58drpg" title="A worlg RPG abstraction.">rpg</a> - <span class="synopsys nitdoc">A worlg RPG abstraction.</span></li><li><a href="test_prog_58d_58dtest_prog" title="A test program with a fake model to check model tools.">test_prog</a> - <span class="synopsys nitdoc">A test program with a fake model to check model tools.</span></li></ul>
+<ul><li><a href="test_prog_58d_58dcareers" title="Careers of the game.">careers</a> - <span class="synopsys nitdoc">Careers of the game.</span></li><li><a href="test_prog_58d_58dcharacter" title="Characters are playable entity in the world.">character</a> - <span class="synopsys nitdoc">Characters are playable entity in the world.</span></li><li><a href="test_prog_58d_58dcombat" title="COmbat interactions between characters.">combat</a> - <span class="synopsys nitdoc">COmbat interactions between characters.</span></li><li><a href="excluded_58d_58dexcluded">excluded</a></li><li><a href="test_prog_58d_58dgame" title="A game abstraction for RPG.">game</a> - <span class="synopsys nitdoc">A game abstraction for RPG.</span></li><li><a href="test_prog_58d_58dgame_examples">game_examples</a></li><li><a href="test_prog_58d_58dplatform" title="Declares base types allowed on the platform.">platform</a> - <span class="synopsys nitdoc">Declares base types allowed on the platform.</span></li><li><a href="test_prog_58d_58draces" title="Races of the game.">races</a> - <span class="synopsys nitdoc">Races of the game.</span></li><li><a href="test_prog_58d_58drpg" title="A worlg RPG abstraction.">rpg</a> - <span class="synopsys nitdoc">A worlg RPG abstraction.</span></li><li><a href="test_prog_58d_58dtest_game">test_game</a></li><li><a href="test_prog_58d_58dtest_prog" title="A test program with a fake model to check model tools.">test_prog</a> - <span class="synopsys nitdoc">A test program with a fake model to check model tools.</span></li></ul>
diff --git a/src/doc/commands/tests/test_commands_html.sav/test_cmd_testing.res b/src/doc/commands/tests/test_commands_html.sav/test_cmd_testing.res
new file mode 100644 (file)
index 0000000..e569191
--- /dev/null
@@ -0,0 +1 @@
+<pre>nitunit tests</pre>
index c081699..f2d5e18 100644 (file)
@@ -287,7 +287,7 @@ class TestCommandsHttp
        # CmdCatalog
 
        fun test_cmd_http_catalog_search is test do
-               var req = new_request("/?q=test&l=1")
+               var req = new_request("/?q=testprog&l=1")
                var cmd = new CmdCatalogSearch(test_view, test_catalog)
                var res = cmd.http_init(req)
                assert res isa CmdSuccess
diff --git a/src/doc/commands/tests/test_commands_ini.nit b/src/doc/commands/tests/test_commands_ini.nit
new file mode 100644 (file)
index 0000000..e2c02b7
--- /dev/null
@@ -0,0 +1,118 @@
+# 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.
+
+module test_commands_ini is test
+
+import test_commands
+import doc::commands::commands_ini
+
+class TestCommandsIni
+       super TestCommands
+       test
+
+       # CmdIni
+
+       fun test_cmd_ini_desc is test do
+               var cmd = new CmdIniDescription(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.desc == "Dummy program used for testing Nit tools"
+       end
+
+       fun test_cmd_ini_git is test do
+               var cmd = new CmdIniGitUrl(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.url == "https://github.com/nitlang/nit.git"
+       end
+
+       fun test_cmd_ini_clone is test do
+               var cmd = new CmdIniCloneCommand(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.url == "https://github.com/nitlang/nit.git"
+               assert cmd.command == "git clone https://github.com/nitlang/nit.git"
+       end
+
+       fun test_cmd_ini_issues is test do
+               var cmd = new CmdIniIssuesUrl(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.url == "https://github.com/nitlang/nit/issues"
+       end
+
+       fun test_cmd_ini_maintainer is test do
+               var cmd = new CmdIniMaintainer(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.maintainer == "John Doe <jdoe@example.com> (http://www.example.com/~jdoe), Spider-Man"
+       end
+
+       fun test_cmd_ini_contributors is test do
+               var cmd = new CmdIniContributors(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.contributors == [
+                       "Riri <riri@example.com>",
+                       "Fifi (http://www.example.com/~fifi)",
+                       "Loulou"]
+       end
+
+       fun test_cmd_ini_license is test do
+               var cmd = new CmdIniLicense(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.license == "Apache-2.0"
+       end
+
+       fun test_cmd_ini_license_file is test do
+               var cmd = new CmdLicenseFile(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var file = cmd.file
+               assert file != null
+               assert file.basename == "LICENSE.md"
+       end
+
+       fun test_cmd_ini_license_file_content is test do
+               var cmd = new CmdLicenseFileContent(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var content = cmd.content
+               assert content != null
+               assert not content.is_empty
+       end
+
+       fun test_cmd_ini_contrib_file is test do
+               var cmd = new CmdContribFile(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var file = cmd.file
+               assert file != null
+               assert file.basename == "CONTRIBUTING.md"
+       end
+
+       fun test_cmd_ini_contrib_file_content is test do
+               var cmd = new CmdContribFileContent(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var content = cmd.content
+               assert content != null
+               assert not content.is_empty
+       end
+end
index be2c235..2d55a3d 100644 (file)
@@ -15,6 +15,7 @@
 module test_commands_json is test
 
 import test_commands
+intrude import doc::commands::commands_main
 import doc::commands::commands_json
 
 class TestCommandsJson
@@ -129,6 +130,110 @@ class TestCommandsJson
                cmd.init_command
                print_json cmd.to_json
        end
+
+       # CmdIni
+
+       fun test_cmd_ini_desc is test do
+               var cmd = new CmdIniDescription(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_git is test do
+               var cmd = new CmdIniGitUrl(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_clone is test do
+               var cmd = new CmdIniCloneCommand(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_issues is test do
+               var cmd = new CmdIniIssuesUrl(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_maintainer is test do
+               var cmd = new CmdIniMaintainer(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_contributors is test do
+               var cmd = new CmdIniContributors(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_license is test do
+               var cmd = new CmdIniLicense(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_license_file is test do
+               var cmd = new CmdLicenseFile(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_license_file_content is test do
+               var cmd = new CmdLicenseFileContent(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_contrib_file is test do
+               var cmd = new CmdContribFile(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_ini_contrib_file_content is test do
+               var cmd = new CmdContribFileContent(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               cmd.file = cmd.file.as(not null).basename # for testing path
+               print_json cmd.to_json
+       end
+
+       # CmdMain
+
+       fun test_cmd_mains is test do
+               var cmd = new CmdMains(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_main_compile is test do
+               var cmd = new CmdMainCompile(test_view, mentity_name = "test_prog::test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_testing is test do
+               var cmd = new CmdTesting(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_man_synopsis is test do
+               var cmd = new CmdManSynopsis(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
+
+       fun test_cmd_man_options is test do
+               var cmd = new CmdManOptions(test_view, mentity_name = "test_prog")
+               cmd.init_command
+               print_json cmd.to_json
+       end
 end
 
 redef class nitc::Location
@@ -146,3 +251,20 @@ redef class nitc::Location
                end
        end
 end
+
+# Avoid path diff
+redef class CmdMainCompile
+       redef fun test_path(file) do
+               if file == null then return null
+               return file.filename.basename
+       end
+end
+
+# Avoid path diff
+redef class CmdTesting
+       redef fun test_path(mentity) do
+               var file = mentity.location.file
+               if file == null then return null
+               return file.filename.basename
+       end
+end
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_clone.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_clone.res
new file mode 100644 (file)
index 0000000..5b79f05
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "command": "git clone https://github.com/nitlang/nit.git"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file.res
new file mode 100644 (file)
index 0000000..3208b3c
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "file": "CONTRIBUTING.md"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file_content.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contrib_file_content.res
new file mode 100644 (file)
index 0000000..9428e33
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "file": "CONTRIBUTING.md",
+       "content": "# Contributing rules\n\n* Be nice\n* Be polite\n* Code well\n"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contributors.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_contributors.res
new file mode 100644 (file)
index 0000000..a0059f2
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "contributors": ["Riri <riri@example.com>", "Fifi (http://www.example.com/~fifi)", "Loulou"]
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_desc.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_desc.res
new file mode 100644 (file)
index 0000000..53d7451
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "desc": "Dummy program used for testing Nit tools"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_git.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_git.res
new file mode 100644 (file)
index 0000000..35a5579
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "url": "https://github.com/nitlang/nit.git"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_issues.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_issues.res
new file mode 100644 (file)
index 0000000..d0f97ad
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "url": "https://github.com/nitlang/nit/issues"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license.res
new file mode 100644 (file)
index 0000000..ac64bfe
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "license": "Apache-2.0"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file.res
new file mode 100644 (file)
index 0000000..900a7ad
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "file": "LICENSE.md"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file_content.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_license_file_content.res
new file mode 100644 (file)
index 0000000..1ec98c7
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "file": "LICENSE.md",
+       "content": "# My Custom License\n\nThis is the license content.\n"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_maintainer.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_ini_maintainer.res
new file mode 100644 (file)
index 0000000..226c66d
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "maintainer": "John Doe <jdoe@example.com> (http://www.example.com/~jdoe), Spider-Man"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_main_compile.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_main_compile.res
new file mode 100644 (file)
index 0000000..2c5663c
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "command": "nitc test_prog.nit"
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_mains.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_mains.res
new file mode 100644 (file)
index 0000000..529d91b
--- /dev/null
@@ -0,0 +1,18 @@
+{
+       "results": [{
+               "name": "test_prog",
+               "synopsis": "A test program with a fake model to check model tools.",
+               "namespace": [{
+                       "name": "test_prog",
+                       "synopsis": "Test program for model tools."
+               }, "::", {
+                       "name": "test_prog",
+                       "synopsis": "A test program with a fake model to check model tools."
+               }],
+               "class_name": "MModule",
+               "full_name": "test_prog::test_prog",
+               "visibility": "public",
+               "html_synopsis": "<span class=\"synopsys nitdoc\">A test program with a fake model to check model tools.</span>",
+               "modifiers": ["module"]
+       }]
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_man_options.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_man_options.res
new file mode 100644 (file)
index 0000000..3253e3a
--- /dev/null
@@ -0,0 +1,6 @@
+{
+       "options": {
+               "--opt1": "Option 1.",
+               "--opt2": "Option 2."
+       }
+}
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_man_synopsis.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_man_synopsis.res
new file mode 100644 (file)
index 0000000..c7ff136
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "synopsis": "test_prog [*options*] ARGS..."
+}
index 07d815d..5d6c8d9 100644 (file)
                "html_synopsis": "<span class=\"synopsys nitdoc\">A worlg RPG abstraction.</span>",
                "modifiers": ["module"]
        }, {
+               "name": "test_game",
+               "namespace": [{
+                       "name": "test_prog",
+                       "synopsis": "Test program for model tools."
+               }, "::", {
+                       "name": "test_game"
+               }],
+               "class_name": "MModule",
+               "full_name": "test_prog::test_game",
+               "visibility": "public",
+               "modifiers": ["module"]
+       }, {
                "name": "test_prog",
                "synopsis": "A test program with a fake model to check model tools.",
                "namespace": [{
index c392050..d58aef9 100644 (file)
                }
        }],
        "page": 1,
-       "count": 113,
+       "count": 121,
        "limit": 10,
-       "max": 11
+       "max": 12
 }
diff --git a/src/doc/commands/tests/test_commands_json.sav/test_cmd_testing.res b/src/doc/commands/tests/test_commands_json.sav/test_cmd_testing.res
new file mode 100644 (file)
index 0000000..b46dce7
--- /dev/null
@@ -0,0 +1,3 @@
+{
+       "command": "nitunit tests"
+}
diff --git a/src/doc/commands/tests/test_commands_main.nit b/src/doc/commands/tests/test_commands_main.nit
new file mode 100644 (file)
index 0000000..5715cc2
--- /dev/null
@@ -0,0 +1,73 @@
+# 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.
+
+module test_commands_main is test
+
+import test_commands
+import doc::commands::commands_main
+
+class TestCommandsMain
+       super TestCommands
+       test
+
+       fun test_cmd_mains is test do
+               var cmd = new CmdMains(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               var results = cmd.results
+               assert results != null
+               assert results.length == 1
+               assert results.first.full_name == "test_prog::test_prog"
+       end
+
+       fun test_cmd_main_compile is test do
+               var cmd = new CmdMainCompile(test_view, mentity_name = "test_prog::test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var command = cmd.command
+               assert command != null
+               assert command.has_prefix("nitc ")
+               assert command.has_suffix("test_prog.nit")
+       end
+
+       fun test_cmd_testing is test do
+               var cmd = new CmdTesting(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var command = cmd.command
+               assert command != null
+               assert command.has_prefix("nitunit ")
+               assert command.has_suffix("/tests")
+       end
+
+       fun test_cmd_man_synopsis is test do
+               var cmd = new CmdManSynopsis(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+               assert cmd.synopsis == "test_prog [*options*] ARGS..."
+       end
+
+       fun test_cmd_man_options is test do
+               var cmd = new CmdManOptions(test_view, mentity_name = "test_prog")
+               var res = cmd.init_command
+               assert res isa CmdSuccess
+
+               var options = cmd.options
+               assert options != null
+               assert options["--opt1"] == "Option 1."
+               assert options["--opt2"] == "Option 2."
+       end
+end
index 901dd3e..88d5e5e 100644 (file)
@@ -204,7 +204,7 @@ class TestCommandsModel
                var cmd = new CmdModelEntities(test_view, kind = "modules")
                var res = cmd.init_command
                assert res isa CmdSuccess
-               assert cmd.results.as(not null).length == 10
+               assert cmd.results.as(not null).length == 11
        end
 
        fun test_cmd_results_random is test do
index 1091d1d..e9f299c 100644 (file)
@@ -179,7 +179,7 @@ class TestCommandsParser
                var cmd = parser.parse("descendants: Object")
                assert cmd isa CmdDescendants
                assert parser.error == null
-               assert cmd.results.as(not null).length == 20
+               assert cmd.results.as(not null).length == 22
        end
 
        fun test_cmd_parser_descendants_without_children is test do
@@ -187,7 +187,7 @@ class TestCommandsParser
                var cmd = parser.parse("descendants: Object | children: false")
                assert cmd isa CmdDescendants
                assert parser.error == null
-               assert cmd.results.as(not null).length == 8
+               assert cmd.results.as(not null).length == 9
        end
 
        # CmdSearch
@@ -402,4 +402,165 @@ class TestCommandsParser
                assert cmd.person.as(not null).name == "Alexandre Terrasa"
                assert cmd.results != null
        end
+
+       # CmdInit
+
+       fun test_cmd_parser_ini_desc is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-desc: test_prog")
+               assert cmd isa CmdIniDescription
+               assert parser.error == null
+               assert cmd.desc.as(not null) == "Dummy program used for testing Nit tools"
+       end
+
+       fun test_cmd_parser_ini_git is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-git: test_prog")
+               assert cmd isa CmdIniGitUrl
+               assert parser.error == null
+               assert cmd.url == "https://github.com/nitlang/nit.git"
+       end
+
+       fun test_cmd_parser_ini_clone is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("git-clone: test_prog")
+               assert cmd isa CmdIniCloneCommand
+               assert parser.error == null
+               assert cmd.url == "https://github.com/nitlang/nit.git"
+               assert cmd.command == "git clone https://github.com/nitlang/nit.git"
+       end
+
+       fun test_cmd_parser_ini_issues is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-issues: test_prog")
+               assert cmd isa CmdIniIssuesUrl
+               assert parser.error == null
+               assert cmd.url == "https://github.com/nitlang/nit/issues"
+       end
+
+       fun test_cmd_parser_ini_maintainer is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-maintainer: test_prog")
+               assert cmd isa CmdIniMaintainer
+               assert parser.error == null
+               assert cmd.maintainer == "John Doe <jdoe@example.com> (http://www.example.com/~jdoe), Spider-Man"
+       end
+
+       fun test_cmd_parser_ini_contributors is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-contributors: test_prog")
+               assert cmd isa CmdIniContributors
+               assert parser.error == null
+               assert cmd.contributors == [
+                       "Riri <riri@example.com>",
+                       "Fifi (http://www.example.com/~fifi)",
+                       "Loulou"]
+       end
+
+       fun test_cmd_parser_ini_license is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("ini-license: test_prog")
+               assert cmd isa CmdIniLicense
+               assert parser.error == null
+               assert cmd.license == "Apache-2.0"
+       end
+
+       fun test_cmd_parser_ini_license_file is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("license-file: test_prog")
+               assert cmd isa CmdLicenseFile
+               assert parser.error == null
+               var file = cmd.file
+               assert file != null
+               assert file.basename == "LICENSE.md"
+       end
+
+       fun test_cmd_parser_ini_license_content is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("license-content: test_prog")
+               assert cmd isa CmdLicenseFileContent
+               assert parser.error == null
+               var content = cmd.content
+               assert content != null
+               assert not content.is_empty
+       end
+
+       fun test_cmd_parser_ini_contrib_file is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("contrib-file: test_prog")
+               assert cmd isa CmdContribFile
+               assert parser.error == null
+               var file = cmd.file
+               assert file != null
+               assert file.basename == "CONTRIBUTING.md"
+       end
+
+       fun test_cmd_parser_ini_contrib_content is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("contrib-content: test_prog")
+               assert cmd isa CmdContribFileContent
+               assert parser.error == null
+               var content = cmd.content
+               assert content != null
+               assert not content.is_empty
+       end
+
+       # CmdMain
+
+       fun test_cmd_parser_mains is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("mains: test_prog")
+               assert cmd isa CmdMains
+               assert parser.error == null
+
+               var results = cmd.results
+               assert results != null
+               assert results.length == 1
+               assert results.first.full_name == "test_prog::test_prog"
+       end
+
+       fun test_cmd_parser_main_compile is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("main-compile: test_prog::test_prog")
+               assert cmd isa CmdMainCompile
+               assert parser.error == null
+
+               var command = cmd.command
+               assert command != null
+               assert command.has_prefix("nitc ")
+               assert command.has_suffix("test_prog.nit")
+       end
+
+       fun test_cmd_parser_testing is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("testing: test_prog")
+               assert cmd isa CmdTesting
+               assert parser.error == null
+
+               var command = cmd.command
+               assert command != null
+               assert command.has_prefix("nitunit ")
+               assert command.has_suffix("/tests")
+       end
+
+       fun test_cmd_man_synopsis is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("main-run: test_prog")
+               assert cmd isa CmdManSynopsis
+               assert parser.error == null
+
+               assert cmd.synopsis == "test_prog [*options*] ARGS..."
+       end
+
+       fun test_cmd_man_opions is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               var cmd = parser.parse("main-opts: test_prog")
+               assert cmd isa CmdManOptions
+               assert parser.error == null
+
+               var options = cmd.options
+               assert options != null
+               assert options["--opt1"] == "Option 1."
+               assert options["--opt2"] == "Option 2."
+       end
 end
index 241e975..42e562f 100644 (file)
        }]
 }
 {
+       "name": "Sys",
+       "synopsis": "Sys",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }],
+       "class_name": "MClassDef",
+       "full_name": "test_prog$Sys",
+       "visibility": "public",
+       "html_synopsis": "<span class=\"synopsys nitdoc\">Sys</span>",
+       "modifiers": ["class"],
+       "is_intro": true
+}
+{
+       "name": "Sys",
+       "synopsis": "Sys",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "test_prog",
+               "synopsis": "A test program with a fake model to check model tools."
+       }, "$", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }],
+       "class_name": "MClassDef",
+       "full_name": "test_prog::test_prog$Sys",
+       "visibility": "public",
+       "html_synopsis": "<span class=\"synopsys nitdoc\">Sys</span>",
+       "modifiers": ["redef", "class"]
+}
+{
        "name": "Career",
        "synopsis": "A `Career` gives a characteristic bonus or malus to the character.",
        "namespace": [{
        "is_intro": true
 }
 {
-       "name": "Sys",
+       "name": "TestGame",
        "namespace": [{
                "name": "test_prog",
                "synopsis": "Test program for model tools."
        }, "$", {
-               "name": "Sys"
+               "name": "TestGame"
        }],
        "class_name": "MClassDef",
-       "full_name": "test_prog$Sys",
+       "full_name": "test_prog$TestGame",
+       "visibility": "public",
+       "modifiers": ["class"],
+       "is_intro": true
+}
+{
+       "name": "GameTest",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "GameTest"
+       }],
+       "class_name": "MClassDef",
+       "full_name": "test_prog$GameTest",
        "visibility": "public",
        "modifiers": ["class"],
        "is_intro": true
index 7e7c7ad..18c77c4 100644 (file)
        }]
 }
 {
+       "name": "Sys",
+       "synopsis": "Sys",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }],
+       "class_name": "MClass",
+       "full_name": "test_prog::Sys",
+       "visibility": "public",
+       "html_synopsis": "<span class=\"synopsys nitdoc\">Sys</span>",
+       "modifiers": ["class"]
+}
+{
        "name": "Career",
        "synopsis": "A `Career` gives a characteristic bonus or malus to the character.",
        "namespace": [{
        "modifiers": ["class"]
 }
 {
-       "name": "Sys",
+       "name": "TestGame",
        "namespace": [{
                "name": "test_prog",
                "synopsis": "Test program for model tools."
        }, "::", {
-               "name": "Sys"
+               "name": "TestGame"
        }],
        "class_name": "MClass",
-       "full_name": "test_prog::Sys",
+       "full_name": "test_prog::TestGame",
+       "visibility": "public",
+       "modifiers": ["class"]
+}
+{
+       "name": "GameTest",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "GameTest"
+       }],
+       "class_name": "MClass",
+       "full_name": "test_prog::GameTest",
        "visibility": "public",
        "modifiers": ["class"]
 }
index 3fc95f5..885eefe 100644 (file)
        "modifiers": ["group"]
 }
 {
+       "name": "man",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, ">", {
+               "name": "man"
+       }, ">"],
+       "class_name": "MGroup",
+       "full_name": "test_prog>man>",
+       "visibility": "public",
+       "modifiers": ["group"]
+}
+{
        "name": "platform",
        "synopsis": "Fictive Crappy Platform.",
        "namespace": [{
        "modifiers": ["group"]
 }
 {
+       "name": "tests",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, ">", {
+               "name": "tests"
+       }, ">"],
+       "class_name": "MGroup",
+       "full_name": "test_prog>tests>",
+       "visibility": "public",
+       "modifiers": ["group"]
+}
+{
        "name": "excluded",
        "namespace": [{
                "name": "excluded"
index 6b46961..857fcb1 100644 (file)
        "modifiers": ["module"]
 }
 {
+       "name": "test_game",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "test_game"
+       }],
+       "class_name": "MModule",
+       "full_name": "test_prog::test_game",
+       "visibility": "public",
+       "modifiers": ["module"]
+}
+{
        "name": "test_prog-m",
        "namespace": [{
                "name": "test_prog-m"
index dea3470..ea14337 100644 (file)
        }
 }
 {
+       "name": "main",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }, "$", {
+               "name": "main"
+       }],
+       "class_name": "MMethodDef",
+       "full_name": "test_prog$Sys$main",
+       "visibility": "public",
+       "modifiers": ["intern", "fun"],
+       "is_intro": true,
+       "msignature": {
+               "arity": 0,
+               "mparameters": [],
+               "return_mtype": null
+       }
+}
+{
+       "name": "main",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "test_prog",
+               "synopsis": "A test program with a fake model to check model tools."
+       }, "$", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }, "$", {
+               "name": "main"
+       }],
+       "class_name": "MMethodDef",
+       "full_name": "test_prog::test_prog$Sys$main",
+       "visibility": "public",
+       "modifiers": ["redef", "fun"],
+       "msignature": {
+               "arity": 0,
+               "mparameters": [],
+               "return_mtype": null
+       }
+}
+{
        "name": "_strength_bonus",
        "namespace": [{
                "name": "test_prog",
        }
 }
 {
+       "name": "player_characters",
+       "synopsis": "Characters played by human players.",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "TestGame"
+       }, "$", {
+               "name": "Game",
+               "synopsis": "This is the interface you have to implement to use ure gaming platform."
+       }, "::", {
+               "name": "player_characters",
+               "synopsis": "Characters played by human players."
+       }],
+       "class_name": "MMethodDef",
+       "full_name": "test_prog$TestGame$Game::player_characters",
+       "visibility": "public",
+       "html_synopsis": "<span class=\"synopsys nitdoc\">Characters played by human players.</span>",
+       "modifiers": ["redef", "fun"],
+       "msignature": {
+               "arity": 0,
+               "mparameters": [],
+               "return_mtype": {
+                       "name": "List[Character]",
+                       "synopsis": "List of things.",
+                       "html_synopsis": "<span class=\"synopsys nitdoc\">List of things.</span>"
+               }
+       }
+}
+{
        "name": "computer_characters",
        "synopsis": "Characters players by computer.",
        "namespace": [{
        }
 }
 {
-       "name": "main",
+       "name": "_player_characters",
        "namespace": [{
                "name": "test_prog",
                "synopsis": "Test program for model tools."
        }, "$", {
-               "name": "Sys"
+               "name": "TestGame"
        }, "$", {
-               "name": "main"
+               "name": "_player_characters"
+       }],
+       "class_name": "MAttributeDef",
+       "full_name": "test_prog$TestGame$_player_characters",
+       "visibility": "private",
+       "modifiers": ["private", "var"],
+       "is_intro": true,
+       "static_mtype": {
+               "name": "List[Character]",
+               "synopsis": "List of things.",
+               "html_synopsis": "<span class=\"synopsys nitdoc\">List of things.</span>"
+       }
+}
+{
+       "name": "player_characters=",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "TestGame"
+       }, "$", {
+               "name": "player_characters="
        }],
        "class_name": "MMethodDef",
-       "full_name": "test_prog$Sys$main",
+       "full_name": "test_prog$TestGame$player_characters=",
+       "visibility": "protected",
+       "modifiers": ["protected", "fun"],
+       "is_intro": true,
+       "msignature": {
+               "arity": 1,
+               "mparameters": [{
+                       "is_vararg": false,
+                       "name": "player_characters",
+                       "mtype": {
+                               "name": "List[Character]",
+                               "synopsis": "List of things.",
+                               "html_synopsis": "<span class=\"synopsys nitdoc\">List of things.</span>"
+                       }
+               }],
+               "return_mtype": null
+       }
+}
+{
+       "name": "test_game",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "$", {
+               "name": "GameTest"
+       }, "$", {
+               "name": "test_game"
+       }],
+       "class_name": "MMethodDef",
+       "full_name": "test_prog$GameTest$test_game",
        "visibility": "public",
        "modifiers": ["fun"],
        "is_intro": true,
index bb15a19..961fa79 100644 (file)
        }
 }
 {
+       "name": "main",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "Sys",
+               "synopsis": "Sys"
+       }, "::", {
+               "name": "main"
+       }],
+       "class_name": "MMethod",
+       "full_name": "test_prog::Sys::main",
+       "visibility": "public",
+       "modifiers": ["intern", "fun"],
+       "msignature": {
+               "arity": 0,
+               "mparameters": [],
+               "return_mtype": null
+       }
+}
+{
        "name": "_strength_bonus",
        "namespace": [{
                "name": "test_prog",
        }
 }
 {
-       "name": "main",
+       "name": "_player_characters",
        "namespace": [{
                "name": "test_prog",
                "synopsis": "Test program for model tools."
        }, "::", {
-               "name": "Sys"
+               "name": "test_game"
        }, "::", {
-               "name": "main"
+               "name": "TestGame"
+       }, "::", {
+               "name": "_player_characters"
+       }],
+       "class_name": "MAttribute",
+       "full_name": "test_prog::test_game::TestGame::_player_characters",
+       "visibility": "private",
+       "modifiers": ["private", "var"],
+       "static_mtype": {
+               "name": "List[Character]",
+               "synopsis": "List of things.",
+               "html_synopsis": "<span class=\"synopsys nitdoc\">List of things.</span>"
+       }
+}
+{
+       "name": "player_characters=",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "TestGame"
+       }, "::", {
+               "name": "player_characters="
        }],
        "class_name": "MMethod",
-       "full_name": "test_prog::Sys::main",
+       "full_name": "test_prog::TestGame::player_characters=",
+       "visibility": "protected",
+       "modifiers": ["protected", "fun"],
+       "msignature": {
+               "arity": 1,
+               "mparameters": [{
+                       "is_vararg": false,
+                       "name": "player_characters",
+                       "mtype": {
+                               "name": "List[Character]",
+                               "synopsis": "List of things.",
+                               "html_synopsis": "<span class=\"synopsys nitdoc\">List of things.</span>"
+                       }
+               }],
+               "return_mtype": null
+       }
+}
+{
+       "name": "test_game",
+       "namespace": [{
+               "name": "test_prog",
+               "synopsis": "Test program for model tools."
+       }, "::", {
+               "name": "GameTest"
+       }, "::", {
+               "name": "test_game"
+       }],
+       "class_name": "MMethod",
+       "full_name": "test_prog::GameTest::test_game",
        "visibility": "public",
        "modifiers": ["fun"],
        "msignature": {
index 200d93f..58ad127 100644 (file)
@@ -347,3 +347,196 @@ redef class CmdCatalogContributing
                print_list("Packages contributed by `{name}`:", results, no_color)
        end
 end
+
+# CmdIni
+
+redef class CmdIni
+       # Print ini data
+       fun print_ini(title: String, data: nullable String, no_color: nullable Bool) do
+               if data == null then return
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+               print ""
+               print data
+       end
+end
+
+redef class CmdIniDescription
+       redef fun execute(no_color) do
+               var title = "Description from ini file:"
+               print_ini(title, desc, no_color)
+       end
+end
+
+redef class CmdIniGitUrl
+       redef fun execute(no_color) do
+               var title = "Git URL from ini file:"
+               print_ini(title, url, no_color)
+       end
+end
+
+redef class CmdIniCloneCommand
+       redef fun execute(no_color) do
+               var title = "Git clone command from ini file:"
+               print_ini(title, command, no_color)
+       end
+end
+
+redef class CmdIniIssuesUrl
+       redef fun execute(no_color) do
+               var title = "Issues URL from ini file:"
+               print_ini(title, url, no_color)
+       end
+end
+
+redef class CmdIniMaintainer
+       redef fun execute(no_color) do
+               var title = "Maintainer from ini file:"
+               print_ini(title, maintainer, no_color)
+       end
+end
+
+redef class CmdIniContributors
+       redef fun execute(no_color) do
+               var contributors = self.contributors
+               if contributors == null then return
+               var title = "Contributors list from ini file:"
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+               print ""
+               for contributor in contributors do
+                       print " * {contributor}"
+               end
+       end
+end
+
+redef class CmdIniLicense
+       redef fun execute(no_color) do
+               var title = "License from ini file:"
+               print_ini(title, license, no_color)
+       end
+end
+
+redef class CmdEntityFile
+
+       # Print file
+       fun print_file(title: String, no_color: nullable Bool) do
+               var file = self.file
+               if file == null then return
+               title = "{title} `{file}`:"
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+               print ""
+               print file.to_path.read_all
+               print ""
+       end
+end
+
+redef class CmdLicenseFile
+       redef fun execute(no_color) do
+               print_file("License from", no_color)
+       end
+end
+
+redef class CmdContribFile
+       redef fun execute(no_color) do
+               print_file("Contributing rules from", no_color)
+       end
+end
+
+# CmdMain
+
+redef class CmdMains
+       redef fun execute(no_color) do
+               var mentity = self.mentity.as(not null).full_name
+               if no_color == null or not no_color then mentity = mentity.blue.bold
+               print_list("Mains in `{mentity}`:", results, no_color)
+       end
+end
+
+redef class CmdMainCompile
+       redef fun execute(no_color) do
+               var mentity = self.mentity.as(not null).full_name
+               if no_color == null or not no_color then mentity = mentity.blue.bold
+               var title = "Compiling `{mentity}`:"
+
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+
+               print ""
+               var command = self.command
+               if command != null then print command
+       end
+end
+
+redef class CmdTesting
+       redef fun execute(no_color) do
+               var mentity = self.mentity.as(not null).full_name
+               if no_color == null or not no_color then mentity = mentity.blue.bold
+               var title = "Testing `{mentity}`:"
+
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+
+               print ""
+               var command = self.command
+               if command != null then print command
+       end
+end
+
+redef class CmdManSynopsis
+       redef fun execute(no_color) do
+               var mentity = self.mentity.as(not null).full_name
+               if no_color == null or not no_color then mentity = mentity.blue.bold
+               var title = "Synopsis for `{mentity}`:"
+
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+
+               print ""
+               var synopsis = self.synopsis
+               if synopsis != null then print synopsis
+       end
+end
+
+redef class CmdManOptions
+       redef fun execute(no_color) do
+               var mentity = self.mentity.as(not null).full_name
+               if no_color == null or not no_color then mentity = mentity.blue.bold
+               var title = "Options for `{mentity}`:"
+
+               if no_color == null or not no_color then
+                       print title.bold
+               else
+                       print title
+               end
+
+               print ""
+               var options = self.options.as(not null)
+               for opt, desc in options do
+                       if no_color == null or not no_color then
+                               print " * {opt.blue.bold}: {desc}"
+                       else
+                               print " * {opt}: {desc}"
+                       end
+               end
+       end
+end
index 08530da..997037c 100644 (file)
@@ -15,6 +15,7 @@
 module test_term is test
 
 import term
+intrude import commands::commands_main
 import commands::test_commands_catalog
 
 # Nitunit test suite specific to commands
@@ -194,9 +195,90 @@ class TestTerm
                var parser = new CommandParser(test_view, test_builder, test_catalog)
                parser.execute("contrib: Alexandre Terrasa", true)
        end
+
+       # CmdIni
+
+       fun test_term_ini_desc is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-desc: test_prog", true)
+       end
+
+       fun test_term_ini_git is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-git: test_prog", true)
+       end
+
+       fun test_term_ini_clone is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("git-clone: test_prog", true)
+       end
+
+       fun test_term_ini_issues is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-issues: test_prog", true)
+       end
+
+       fun test_term_ini_maintainer is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-maintainer: test_prog", true)
+       end
+
+       fun test_term_ini_contributors is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-contributors: test_prog", true)
+       end
+
+       fun test_term_ini_license is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("ini-license: test_prog", true)
+       end
+
+       # CmdMain
+
+       fun test_term_mains is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("mains: test_prog", true)
+       end
+
+       fun test_term_main_compile is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("main-compile: test_prog::test_prog", true)
+       end
+
+       fun test_term_man_synopsis is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("main-run: test_prog::test_prog", true)
+       end
+
+       fun test_term_man_options is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("main-opts: test_prog::test_prog", true)
+       end
+
+       fun test_term_testing is test do
+               var parser = new CommandParser(test_view, test_builder, test_catalog)
+               parser.execute("testing: test_prog", true)
+       end
 end
 
 redef class nitc::Location
        # Avoid location diffs
        redef fun to_s do return "test_location"
 end
+
+# Avoid path diff
+redef class CmdMainCompile
+       redef fun test_path(file) do
+               if file == null then return null
+               return file.filename.basename
+       end
+end
+
+# Avoid path diff
+redef class CmdTesting
+       redef fun test_path(mentity) do
+               var file = mentity.location.file
+               if file == null then return null
+               return file.filename.basename
+       end
+end
index fd8b8ba..c8a157d 100644 (file)
@@ -1,9 +1,9 @@
 Catalog statistics:
  * 2 packages
- * 10 modules
- * 75 methods
- * 23 classes
- * 471 lines of code
+ * 11 modules
+ * 79 methods
+ * 26 classes
+ * 509 lines of code
  * 6 contributors
  * 1 maintainers
  * 2 tags
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_clone.res b/src/doc/term/tests/test_term.sav/test_term_ini_clone.res
new file mode 100644 (file)
index 0000000..9fd2554
--- /dev/null
@@ -0,0 +1,3 @@
+Git clone command from ini file:
+
+git clone https://github.com/nitlang/nit.git
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_contributors.res b/src/doc/term/tests/test_term.sav/test_term_ini_contributors.res
new file mode 100644 (file)
index 0000000..7a4a3e8
--- /dev/null
@@ -0,0 +1,5 @@
+Contributors list from ini file:
+
+ * Riri <riri@example.com>
+ * Fifi (http://www.example.com/~fifi)
+ * Loulou
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_desc.res b/src/doc/term/tests/test_term.sav/test_term_ini_desc.res
new file mode 100644 (file)
index 0000000..2fbbad6
--- /dev/null
@@ -0,0 +1,3 @@
+Description from ini file:
+
+Dummy program used for testing Nit tools
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_git.res b/src/doc/term/tests/test_term.sav/test_term_ini_git.res
new file mode 100644 (file)
index 0000000..998e12e
--- /dev/null
@@ -0,0 +1,3 @@
+Git URL from ini file:
+
+https://github.com/nitlang/nit.git
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_issues.res b/src/doc/term/tests/test_term.sav/test_term_ini_issues.res
new file mode 100644 (file)
index 0000000..6c44924
--- /dev/null
@@ -0,0 +1,3 @@
+Issues URL from ini file:
+
+https://github.com/nitlang/nit/issues
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_license.res b/src/doc/term/tests/test_term.sav/test_term_ini_license.res
new file mode 100644 (file)
index 0000000..ebd3e21
--- /dev/null
@@ -0,0 +1,3 @@
+License from ini file:
+
+Apache-2.0
diff --git a/src/doc/term/tests/test_term.sav/test_term_ini_maintainer.res b/src/doc/term/tests/test_term.sav/test_term_ini_maintainer.res
new file mode 100644 (file)
index 0000000..193379f
--- /dev/null
@@ -0,0 +1,3 @@
+Maintainer from ini file:
+
+John Doe <jdoe@example.com> (http://www.example.com/~jdoe), Spider-Man
diff --git a/src/doc/term/tests/test_term.sav/test_term_main_compile.res b/src/doc/term/tests/test_term.sav/test_term_main_compile.res
new file mode 100644 (file)
index 0000000..fdcc93b
--- /dev/null
@@ -0,0 +1,3 @@
+Compiling `test_prog::test_prog`:
+
+nitc test_prog.nit
diff --git a/src/doc/term/tests/test_term.sav/test_term_mains.res b/src/doc/term/tests/test_term.sav/test_term_mains.res
new file mode 100644 (file)
index 0000000..f72eff0
--- /dev/null
@@ -0,0 +1,7 @@
+Mains in `test_prog`:
+
+ + test_prog::test_prog
+   # A test program with a fake model to check model tools.
+   module test_prog
+   test_location
+
diff --git a/src/doc/term/tests/test_term.sav/test_term_man_options.res b/src/doc/term/tests/test_term.sav/test_term_man_options.res
new file mode 100644 (file)
index 0000000..71b984b
--- /dev/null
@@ -0,0 +1,4 @@
+Options for `test_prog::test_prog`:
+
+ * --opt1: Option 1.
+ * --opt2: Option 2.
diff --git a/src/doc/term/tests/test_term.sav/test_term_man_synopsis.res b/src/doc/term/tests/test_term.sav/test_term_man_synopsis.res
new file mode 100644 (file)
index 0000000..f58027d
--- /dev/null
@@ -0,0 +1,3 @@
+Synopsis for `test_prog::test_prog`:
+
+test_prog [*options*] ARGS...
diff --git a/src/doc/term/tests/test_term.sav/test_term_testing.res b/src/doc/term/tests/test_term.sav/test_term_testing.res
new file mode 100644 (file)
index 0000000..bef162c
--- /dev/null
@@ -0,0 +1,3 @@
+Testing `test_prog`:
+
+nitunit tests
index 45032fe..f7b765b 100644 (file)
@@ -21,7 +21,6 @@ import literal
 import semantize
 private import parser::tables
 import mixin
-import primitive_types
 private import model::serialize_model
 private import frontend::explain_assert_api
 
diff --git a/src/interpreter/primitive_types.nit b/src/interpreter/primitive_types.nit
deleted file mode 100644 (file)
index ba058c1..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Encapsulates all primitive data types of nit
-#
-# Ensures that the use in the interpreter is independant of the
-# underlying implementation and that the services are semantically correct.
-module primitive_types
-
-intrude import core::file
-intrude import core::text::flat
-
-# Wrapper for `NativeFile`
-class PrimitiveNativeFile
-
-       var file: Stream
-
-       init native_stdin do
-               init(sys.stdin)
-       end
-
-       init native_stdout do
-               init(sys.stdout)
-       end
-
-       init native_stderr do
-               init(sys.stderr)
-       end
-
-       init io_open_read(path: String) do
-               init(new FileReader.open(path.to_s))
-       end
-
-       init io_open_write(path: String) do
-               init(new FileWriter.open(path.to_s))
-       end
-
-       fun address_is_null: Bool do
-               if file isa FileStream then return file.as(FileStream)._file.address_is_null
-               return false
-       end
-
-       fun io_read(buf: CString, len: Int): Int do
-               if file isa FileStream then return file.as(FileStream)._file.io_read(buf, len)
-               var str = file.as(Reader).read(len)
-               str.to_cstring.copy_to(buf, str.length, 0, 0)
-               return str.length
-       end
-
-       fun io_write(buf: CString, from, len: Int): Int do
-               if file isa FileStream then return file.as(FileStream)._file.io_write(buf, from, len)
-               file.as(Writer).write(buf.to_s_unsafe(len, copy=false).substring_from(from))
-               return len
-       end
-
-       fun io_close: Int do
-               if file isa FileStream then return file.as(FileStream)._file.io_close
-               file.close
-               return 0
-       end
-
-       fun fileno: Int do
-               if file isa FileStream then return file.as(FileStream)._file.fileno
-               return 0
-       end
-
-       fun flush: Int do
-               if file isa FileStream then return file.as(FileStream)._file.flush
-               return 0
-       end
-
-       fun set_buffering_type(size, mode: Int): Int do
-               if file isa FileStream then return file.as(FileStream)._file.set_buffering_type(size, mode)
-               return 0
-       end
-end
index 6edd044..4df13c6 100644 (file)
@@ -380,6 +380,15 @@ redef class MGroup
        end
 
        # Collect all modules contained in `self`
+       fun collect_all_mmodules(view: ModelView): HashSet[MModule] do
+               var res = new HashSet[MModule]
+               for mgroup in collect_mgroups(view) do
+                       res.add_all mgroup.collect_all_mmodules(view)
+               end
+               return res
+       end
+
+       # Collect all modules contained in `self`
        fun collect_mmodules(view: ModelView): HashSet[MModule] do
                var res = new HashSet[MModule]
                for mmodule in mmodules do
index bb6856b..3157233 100644 (file)
@@ -61,6 +61,37 @@ class MPackage
                if root != null then return root.mdoc_or_fallback
                return null
        end
+
+       # Does `self` have a source file?
+       fun has_source: Bool do return location.file != null
+
+       # The path to `self`
+       fun package_path: nullable String do
+               if not has_source then return null
+               return location.file.as(not null).filename
+       end
+
+       # Is `self` in its own directory?
+       fun is_expanded: Bool do
+               var path = package_path
+               if path == null then return false
+               return not path.has_suffix(".nit")
+       end
+
+       # The path to `self` ini file
+       fun ini_path: nullable String do
+               var path = package_path
+               if path == null then return null
+               if is_expanded then return path / "package.ini"
+               return path.dirname / "{name}.ini"
+       end
+
+       # Does `self` have a ini file?
+       fun has_ini: Bool do
+               var ini_path = self.ini_path
+               if ini_path == null then return false
+               return ini_path.file_exists
+       end
 end
 
 # A group of modules in a package
index 5373ae0..0e29e89 100644 (file)
@@ -21,12 +21,22 @@ redef class ToolContext
        # --expand
        var opt_expand = new OptionBool("Move singleton packages to their own directory", "--expand")
 
+       # --check-ini
+       var opt_check_ini = new OptionBool("Check package.ini files", "--check-ini")
+
+       # --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_check_ini, opt_gen_ini)
        end
 end
 
@@ -34,10 +44,8 @@ private class ReadmePhase
        super Phase
 
        redef fun process_mainmodule(mainmodule, mmodules) do
-               var expand_packages = toolcontext.opt_expand.value
-               var model = toolcontext.modelbuilder.model
-
-               for mpackage in model.mpackages do
+               var mpackages = extract_mpackages(mmodules)
+               for mpackage in mpackages do
 
                        # Fictive and buggy packages are ignored
                        if not mpackage.has_source then
@@ -46,41 +54,52 @@ private class ReadmePhase
                                continue
                        end
 
+                       # Check package INI files
+                       if toolcontext.opt_check_ini.value then
+                               mpackage.check_ini(toolcontext)
+                               continue
+                       end
+
                        # Expand packages
+                       if toolcontext.opt_expand.value and not mpackage.is_expanded then
+                               var path = mpackage.expand
+                               toolcontext.info("{mpackage} moved to {path}", 0)
+                       end
                        if not mpackage.is_expanded then
-                               if expand_packages then
-                                       var path = mpackage.expand
-                                       toolcontext.info("{mpackage} moved to {path}", 0)
-                               else
-                                       toolcontext.warning(mpackage.location, "no-dir",
-                                               "Warning: `{mpackage}` has no package directory")
-                                       continue
+                               toolcontext.warning(mpackage.location, "no-dir",
+                                       "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
-end
-
-redef class MPackage
 
-       # Does `self` have a source file?
-       private var has_source: Bool is lazy do
-               return location.file != null
+       # Extract the list of packages from the mmodules passed as arguments
+       fun extract_mpackages(mmodules: Collection[MModule]): Collection[MPackage] do
+               var mpackages = new ArraySet[MPackage]
+               for mmodule in mmodules do
+                       var mpackage = mmodule.mpackage
+                       if mpackage == null then continue
+                       mpackages.add mpackage
+               end
+               return mpackages.to_a
        end
+end
 
-       # Is `self` in its own directory?
-       private var is_expanded: Bool is lazy do
-               if not has_source then return false
-               var path = location.file.as(not null).filename
-               if path.has_suffix(".nit") then return false
-               return true
-       end
+redef class MPackage
 
        # Expand `self` in its own directory
        private fun expand: String do
                assert not is_expanded
 
-               var ori_path = location.file.as(not null).filename
+               var ori_path = package_path.as(not null)
                var new_path = ori_path.dirname / name
 
                new_path.mkdir
@@ -93,6 +112,179 @@ 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 var allowed_ini_keys = [
+               "package.name", "package.desc", "package.tags", "package.license",
+               "package.maintainer", "package.more_contributors",
+               "upstream.browse", "upstream.git", "upstream.git.directory",
+               "upstream.homepage", "upstream.issues"
+               ]
+
+       private fun check_ini(toolcontext: ToolContext) do
+               if not has_ini then
+                       toolcontext.error(location, "No `package.ini` file for `{name}`")
+                       return
+               end
+
+               var pkg_path = package_path
+               if pkg_path == null then return
+
+               var ini_path = ini_path
+               if ini_path == null then return
+
+               var ini = new ConfigTree(ini_path)
+
+               ini.check_key(toolcontext, self, "package.name", name)
+               ini.check_key(toolcontext, self, "package.desc")
+               ini.check_key(toolcontext, self, "package.tags")
+
+               # FIXME since `git reflog --follow` seems bugged
+               ini.check_key(toolcontext, self, "package.maintainer")
+               # var maint = mpackage.maintainer
+               # if maint != null then
+                       # ini.check_key(toolcontext, self, "package.maintainer", maint)
+               # end
+
+               # FIXME since `git reflog --follow` seems bugged
+               # var contribs = mpackage.contributors
+               # if contribs.not_empty then
+                       # ini.check_key(toolcontext, self, "package.more_contributors", contribs.join(", "))
+               # end
+
+               ini.check_key(toolcontext, self, "package.license", license)
+               ini.check_key(toolcontext, self, "upstream.browse", browse_url)
+               ini.check_key(toolcontext, self, "upstream.git", git_url)
+               ini.check_key(toolcontext, self, "upstream.git.directory", git_dir)
+               ini.check_key(toolcontext, self, "upstream.homepage", homepage_url)
+               ini.check_key(toolcontext, self, "upstream.issues", issues_url)
+
+               for key in ini.to_map.keys do
+                       if not allowed_ini_keys.has(key) then
+                               toolcontext.warning(location, "unknown-ini-key",
+                                       "Warning: ignoring unknown `{key}` key in `{ini.ini_file}`")
+                       end
+               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 check_key(toolcontext: ToolContext, mpackage: MPackage, key: String, value: nullable String) do
+               if not has_key(key) then
+                       toolcontext.warning(mpackage.location, "missing-ini-key",
+                               "Warning: missing `{key}` key in `{ini_file}`")
+                       return
+               end
+               if self[key].as(not null).is_empty then
+                       toolcontext.warning(mpackage.location, "missing-ini-value",
+                               "Warning: empty `{key}` key in `{ini_file}`")
+                       return
+               end
+               if value != null and self[key] != value then
+                       toolcontext.warning(mpackage.location, "wrong-ini-value",
+                               "Warning: wrong value for `{key}` in `{ini_file}`. " +
+                               "Expected `{value}`, got `{self[key] or else ""}`")
+               end
+       end
+
+       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
index 8524fc6..7ab7a71 100644 (file)
 </ul>
 </li>
 <li><strong>test_prog</strong>: <span class="synopsys nitdoc">A test program with a fake model to check model tools.</span> (test_prog/test_prog.nit)</li>
+<li><strong>tests</strong> (test_prog/tests)<ul>
+<li><strong>test_game</strong> (test_prog/tests/test_game.nit)</li>
+</ul>
+</li>
 </ul>
 </li>
 </ul>
@@ -80,8 +84,8 @@
 </ul>
 <h3>Quality</h3>
 <ul class="box">
-<li>28 warnings (59/kloc)</li>
-<li>82% documented</li>
+<li>28 warnings (55/kloc)</li>
+<li>73% documented</li>
 </ul>
 <h3>Tags</h3>
 <a href="../index.html#tag_test">test</a>, <a href="../index.html#tag_game">game</a><h3>Requirements</h3>
@@ -89,10 +93,10 @@ none<h3>Clients</h3>
 none<h3>Contributors</h3>
 <ul class="box"><li><a href="http:&#47;&#47;www.example.com&#47;~jdoe"><img src="https://secure.gravatar.com/avatar/694ea0904ceaf766c6738166ed89bafb?size=20&amp;default=retro">&nbsp;John Doe</a></li><li><img src="https://secure.gravatar.com/avatar/db3f2909768694ad2bb6409b44627182?size=20&amp;default=retro">&nbsp;Riri</li><li>Fifi (http:&#47;&#47;www.example.com&#47;~fifi)</li><li>Loulou</li></ul><h3>Stats</h3>
 <ul class="box">
-<li>9 modules</li>
-<li>23 classes</li>
-<li>75 methods</li>
-<li>471 lines of code</li>
+<li>10 modules</li>
+<li>26 classes</li>
+<li>79 methods</li>
+<li>509 lines of code</li>
 </ul>
 </div>
 </div> <!-- container-fluid -->
index 9fdb265..e764a49 100644 (file)
@@ -1,6 +1,8 @@
 Empty README for group `examples` (readme-warning)
+Empty README for group `man` (readme-warning)
+Empty README for group `tests` (readme-warning)
 Empty README for group `excluded` (readme-warning)
-Errors: 0. Warnings: 2.
+Errors: 0. Warnings: 4.
 MGroupPage excluded
        # excluded.section
                ## excluded.intro
@@ -39,12 +41,16 @@ ReadmePage examples
 ReadmePage game
        # mdarticle-0
 
+ReadmePage man
+
 ReadmePage platform
        # mdarticle-0
 
 ReadmePage rpg
        # mdarticle-0
 
+ReadmePage tests
+
 SearchPage Index
        # index.article
 
@@ -79,7 +85,10 @@ MModulePage test_prog
                                                ###### list.group
                                                        ####### test_prog-__Starter.intros
                                                        ####### test_prog-__Starter.redefs
-                       ### test_prog-__Sys.definition-list
+               ## test_prog__platform.concern
+               ## test_prog__platform-.concern
+                       ### test_prog__platform-__Sys.definition-list
+                               #### test_prog__platform-__Sys.definition
                                #### test_prog-__Sys.definition
                                        ##### test_prog-__Sys.intros_redefs
                                                ###### list.group
@@ -108,27 +117,6 @@ MPropertyPage start
        # start.section
                ## test_prog-__Starter__start.intro
 
-MClassPage Sys
-       # Sys.section
-               ## test_prog-__Sys.intro
-               ## test_prog-__Sys.inheritance
-                       ### test_prog-__Sys.graph
-                       ### list.group
-                               #### test_prog-__Sys.parents
-                               #### test_prog-__Sys.ancestors
-                               #### test_prog-__Sys.children
-                               #### test_prog-__Sys.descendants
-               ## test_prog-__Sys.constructors
-               ## test_prog-__Sys.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog-.concern
-                       ### test_prog-__Sys__main.definition
-
-MPropertyPage main
-       # main.section
-               ## test_prog-__Sys__main.intro
-
 MGroupPage examples
        # examples.section
                ## test_prog__examples.intro
@@ -287,6 +275,9 @@ MPropertyPage player_characters
                ## test_prog__examples.concern
                ## test_prog__examples-.concern
                        ### test_prog__examples-__MyGame__player_characters.definition
+               ## test_prog__tests.concern
+               ## test_prog__tests-.concern
+                       ### test_prog__tests-__TestGame__player_characters.definition
 
 MPropertyPage start_game
        # start_game.section
@@ -308,6 +299,10 @@ MPropertyPage stop_game
                ## test_prog__examples-.concern
                        ### test_prog__examples-__MyGame__stop_game.definition
 
+MGroupPage man
+       # man.section
+               ## test_prog__man.intro
+
 MGroupPage platform
        # platform.section
                ## test_prog__platform.intro
@@ -371,6 +366,12 @@ MModulePage platform
                                                ###### list.group
                                                        ####### test_prog__platform-__String.intros
                                                        ####### test_prog__platform-__String.redefs
+                       ### test_prog__platform-__Sys.definition-list
+                               #### test_prog__platform-__Sys.definition
+                                       ##### test_prog__platform-__Sys.intros_redefs
+                                               ###### list.group
+                                                       ####### test_prog__platform-__Sys.intros
+                                                       ####### test_prog__platform-__Sys.redefs
 
 MClassPage Bool
        # Bool.section
@@ -554,6 +555,38 @@ MClassPage String
                                #### test_prog__platform-__String.children
                                #### test_prog__platform-__String.descendants
 
+MClassPage Sys
+       # Sys.section
+               ## test_prog__platform-__Sys.intro
+               ## test_prog__platform-__Sys.inheritance
+                       ### test_prog__platform-__Sys.graph
+                       ### list.group
+                               #### test_prog__platform-__Sys.parents
+                               #### test_prog__platform-__Sys.ancestors
+                               #### test_prog__platform-__Sys.children
+                               #### test_prog__platform-__Sys.descendants
+               ## test_prog__platform-__Sys.constructors
+                       ### test_prog__platform-__Object__init.definition
+               ## test_prog__platform-__Sys.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog__platform.concern
+               ## test_prog__platform-.concern
+                       ### test_prog__platform-__Sys__main.definition
+                               #### test_prog__platform-__Sys__main.lin
+               ## test_prog-.concern
+                       ### test_prog-__Sys__main.definition
+                               #### test_prog-__Sys__main.lin
+
+MPropertyPage main
+       # main.section
+               ## test_prog__platform-__Sys__main.intro
+               ## test_prog__platform-__Sys__main.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog-.concern
+                       ### test_prog-__Sys__main.definition
+
 MGroupPage rpg
        # rpg.section
                ## test_prog__rpg.intro
@@ -1139,24 +1172,112 @@ MModulePage rpg
                                #### test_prog__rpg__rpg.imports
                                #### test_prog__rpg__rpg.clients
 
-Generated 105 pages
+MGroupPage tests
+       # tests.section
+               ## test_prog__tests.intro
+               ## test_prog__tests.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog__tests.concern
+               ## test_prog__tests-.concern
+                       ### test_prog__tests-.definition
+                               #### test_prog__tests-.intros_redefs
+                                       ##### list.group
+                                               ###### test_prog__tests-.intros
+                                               ###### test_prog__tests-.redefs
+
+MModulePage test_game
+       # test_game.section
+               ## test_prog__tests-.intro
+               ## test_prog__tests-.importation
+                       ### test_prog__tests-.graph
+                       ### list.group
+                               #### test_prog__tests-.imports
+                               #### test_prog__tests-.clients
+               ## test_prog__tests-.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog__tests.concern
+               ## test_prog__tests-.concern
+                       ### test_prog__tests-__GameTest.definition-list
+                               #### test_prog__tests-__GameTest.definition
+                                       ##### test_prog__tests-__GameTest.intros_redefs
+                                               ###### list.group
+                                                       ####### test_prog__tests-__GameTest.intros
+                                                       ####### test_prog__tests-__GameTest.redefs
+                       ### test_prog__tests-__TestGame.definition-list
+                               #### test_prog__tests-__TestGame.definition
+                                       ##### test_prog__tests-__TestGame.intros_redefs
+                                               ###### list.group
+                                                       ####### test_prog__tests-__TestGame.intros
+                                                       ####### test_prog__tests-__TestGame.redefs
+
+MClassPage GameTest
+       # GameTest.section
+               ## test_prog__tests-__GameTest.intro
+               ## test_prog__tests-__GameTest.inheritance
+                       ### test_prog__tests-__GameTest.graph
+                       ### list.group
+                               #### test_prog__tests-__GameTest.parents
+                               #### test_prog__tests-__GameTest.ancestors
+                               #### test_prog__tests-__GameTest.children
+                               #### test_prog__tests-__GameTest.descendants
+               ## test_prog__tests-__GameTest.constructors
+                       ### test_prog__platform-__Object__init.definition
+               ## test_prog__tests-__GameTest.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog__tests.concern
+               ## test_prog__tests-.concern
+                       ### test_prog__tests-__GameTest__test_game.definition
+
+MPropertyPage test_game
+       # test_game.section
+               ## test_prog__tests-__GameTest__test_game.intro
+
+MClassPage TestGame
+       # TestGame.section
+               ## test_prog__tests-__TestGame.intro
+               ## test_prog__tests-__TestGame.inheritance
+                       ### test_prog__tests-__TestGame.graph
+                       ### list.group
+                               #### test_prog__tests-__TestGame.parents
+                               #### test_prog__tests-__TestGame.ancestors
+                               #### test_prog__tests-__TestGame.children
+                               #### test_prog__tests-__TestGame.descendants
+               ## test_prog__tests-__TestGame.constructors
+                       ### test_prog__platform-__Object__init.definition
+               ## test_prog__tests-__TestGame.concerns
+               ## test_prog.concern
+               ## test_prog.concern
+               ## test_prog__tests.concern
+               ## test_prog__tests-.concern
+                       ### test_prog__tests-__TestGame__player_characters.definition
+                               #### test_prog__tests-__TestGame__player_characters.lin
+                       ### test_prog__tests-__TestGame__player_characters_61d.definition
+
+MPropertyPage player_characters=
+       # player_characters=.section
+               ## test_prog__tests-__TestGame__player_characters_61d.intro
+
+Generated 114 pages
  list:
-  MPropertyPage: 60 (57.14%)
-  MClassPage: 21 (20.00%)
-  MModulePage: 10 (9.52%)
-  ReadmePage: 6 (5.71%)
-  MGroupPage: 6 (5.71%)
-  SearchPage: 1 (0.95%)
-  OverviewPage: 1 (0.95%)
-Found 198 mentities
+  MPropertyPage: 62 (54.38%)
+  MClassPage: 23 (20.17%)
+  MModulePage: 11 (9.64%)
+  ReadmePage: 8 (7.01%)
+  MGroupPage: 8 (7.01%)
+  SearchPage: 1 (0.87%)
+  OverviewPage: 1 (0.87%)
+Found 212 mentities
  list:
-  MMethodDef: 75 (37.87%)
-  MMethod: 59 (29.79%)
-  MClassDef: 23 (11.61%)
-  MClass: 21 (10.60%)
-  MModule: 10 (5.05%)
-  MGroup: 6 (3.03%)
-  MPackage: 2 (1.01%)
-  MVirtualTypeDef: 1 (0.50%)
-  MVirtualTypeProp: 1 (0.50%)
+  MMethodDef: 79 (37.26%)
+  MMethod: 61 (28.77%)
+  MClassDef: 26 (12.26%)
+  MClass: 23 (10.84%)
+  MModule: 11 (5.18%)
+  MGroup: 8 (3.77%)
+  MPackage: 2 (0.94%)
+  MVirtualTypeDef: 1 (0.47%)
+  MVirtualTypeProp: 1 (0.47%)
 quicksearch-list.js
index 49f93f6..d5326c0 100644 (file)
@@ -11,4 +11,6 @@ test_prog: Test program for model tools. (test_prog)
 |  |--combat: COmbat interactions between characters. (test_prog/rpg/combat.nit)
 |  |--races: Races of the game. (test_prog/rpg/races.nit)
 |  `--rpg: A worlg RPG abstraction. (test_prog/rpg/rpg.nit)
-`--test_prog: A test program with a fake model to check model tools. (test_prog/test_prog.nit)
+|--test_prog: A test program with a fake model to check model tools. (test_prog/test_prog.nit)
+`--tests (test_prog/tests)
+   `--test_game (test_prog/tests/test_game.nit)
index 109e74a..6bf7b3d 100644 (file)
@@ -7,4 +7,12 @@ Long method:  Average 1 lines
                -total_strengh has 2 lines
                -total_endurance has 2 lines
                -total_intelligence has 2 lines
-Large class: 6 attributes and 18 methods (4.581A 7.153M Average)
+Large class: 6 attributes and 18 methods (4.673A 6.923M Average)
+--------------------
+Full name: test_prog$GameTest Location: test_prog/tests/test_game.nit:25,1--33,3
+Feature envy:
+       Affected method(s):
+               -test_game() 0/1 move to TestGame
+Long method:  Average 1 lines
+       Affected method(s):
+               -test_game has 3 lines
index c237e27..830f160 100644 (file)
@@ -14,8 +14,8 @@ scan_full found 6 modules
   model: mpackages=1 mmodules=5
   mb: identified modules=5; parsed modules=0
 parse found 2 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=6
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=6
 parse_full found 5 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=6
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=6
index 4650fe7..1f0568d 100644 (file)
@@ -22,20 +22,20 @@ test_prog::test_prog: module?
        module test_prog::test_prog at test_prog/test_prog.nit
 test_prog::test_prog: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 test_prog/: module?
        module test_prog::test_prog at test_prog/test_prog.nit
 test_prog/: group?
        group test_prog> at test_prog
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
-scan_full found 20 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
+scan_full found 22 modules
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 parse found 1 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=8
-parse_full found 9 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=9
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=8
+parse_full found 10 modules
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=10
index fea9069..384c032 100644 (file)
@@ -6,26 +6,26 @@ test_prog::races: module?
        module test_prog::races at test_prog/rpg/races.nit
 test_prog::races: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 test_prog::races:rpg: module?
        Error: cannot find module `test_prog::races:rpg`. Did you mean test_prog::races?
 test_prog::races:rpg: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 test_prog::races::combat: module?
        Error: cannot find module `test_prog::races::combat`. Did you mean test_prog::combat?
 test_prog::races::combat: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 scan_full found 1 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 parse found 1 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=2
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=2
 parse_full found 1 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=2
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=2
index 4c9789a..63492e1 100644 (file)
@@ -8,26 +8,26 @@ test_prog::fail::races: module?
        Error: cannot find module `test_prog::fail::races`. Did you mean test_prog::races?
 test_prog::fail::races: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 test_prog::fail: module?
        Error: cannot find module `test_prog::fail`. Did you mean test_prog::game?
 test_prog::fail: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 fail::fail: module?
        nothing
 fail::fail: group?
        nothing
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 scan_full found 0 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 parse found 0 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
 parse_full found 0 modules
-  model: mpackages=2 mmodules=10
-  mb: identified modules=10; parsed modules=0
+  model: mpackages=2 mmodules=11
+  mb: identified modules=11; parsed modules=0
index cfee574..d68740c 100644 (file)
@@ -5,8 +5,8 @@
  * 5: careers (test_prog::careers)
  * 5: examples (test_prog>examples>)
  * 5: excluded (excluded>)
- * 5: excluded (excluded::excluded)
  * 5: excluded (excluded)
- * 5: game (test_prog::game)
+ * 5: excluded (excluded::excluded)
  * 5: game (test_prog>game>)
+ * 5: game (test_prog::game)
  * 4: races (test_prog::races)
index f969724..02cba00 100644 (file)
@@ -1,12 +1,12 @@
 # Dwarves
 
- * 13: Int (test_prog::Int)
  * 12: Sys (test_prog::Sys)
  * 8: excluded (excluded>)
  * 7: excluded (excluded)
  * 13: game (test_prog>game>)
+ * 13: man (test_prog>man>)
  * 13: races (test_prog::races)
  * 13: rpg (test_prog>rpg>)
  * 13: rpg (test_prog::rpg)
- * 9: test_prog (test_prog>)
  * 9: test_prog (test_prog)
+ * 9: test_prog (test_prog>)
index 000025b..fe5bfd3 100644 (file)
@@ -1,12 +1,12 @@
 # Obj
 
  * 3: + (test_prog::Int::+)
- * 3: - (test_prog::Int::-)
  * 3: > (test_prog::Int::>)
  * 3: Elf (test_prog::Elf)
  * 3: Int (test_prog::Int)
  * 1: Object (test_prog::Object)
  * 3: Sys (test_prog::Sys)
  * 3: age (test_prog::Character::age)
+ * 3: man (test_prog>man>)
  * 3: rpg (test_prog::rpg)
  * 3: rpg (test_prog>rpg>)
index fc68d39..bd3e0ad 100644 (file)
@@ -1,11 +1,11 @@
 # Dwa
 
  * 13: Dwarf (test_prog::Dwarf)
- * 14: Game (test_prog::Game)
  * 9: excluded (excluded>)
  * 8: excluded (excluded)
  * 14: game (test_prog>game>)
  * 14: game (test_prog::game)
+ * 13: man (test_prog>man>)
  * 14: rpg (test_prog>rpg>)
  * 14: rpg (test_prog::rpg)
  * 10: test_prog (test_prog>)
index dd17043..41184bb 100644 (file)
@@ -1,12 +1,12 @@
 # Foo
 
- * 3: != (test_prog::Object::!=)
- * 3: == (test_prog::Object::==)
- * 3: > (test_prog::Int::>)
+ * 3: * (test_prog::Int::*)
  * 2: Bool (test_prog::Bool)
  * 3: Elf (test_prog::Elf)
  * 3: Float (test_prog::Float)
  * 3: Int (test_prog::Int)
  * 3: Sys (test_prog::Sys)
- * 3: rpg (test_prog::rpg)
+ * 3: dps (test_prog::Weapon::dps)
+ * 3: man (test_prog>man>)
  * 3: rpg (test_prog>rpg>)
+ * 3: rpg (test_prog::rpg)
index c06776c..0c44100 100644 (file)
@@ -7,6 +7,6 @@
  * 3: Int (test_prog::Int)
  * 3: Sys (test_prog::Sys)
  * 3: rpg (test_prog::rpg)
- * 3: test_prog (test_prog::test_prog)
- * 3: test_prog (test_prog)
  * 3: test_prog (test_prog>)
+ * 3: test_prog (test_prog)
+ * 3: test_prog (test_prog::test_prog)
index 191fd72..6381895 100644 (file)
@@ -6,7 +6,7 @@
  * 1: + (test_prog::Float::+)
  * 1: - (test_prog::Int::-)
  * 1: - (test_prog::Float::-)
- * 1: / (test_prog::Float::/)
  * 1: / (test_prog::Int::/)
- * 1: > (test_prog::Float::>)
+ * 1: / (test_prog::Float::/)
  * 1: > (test_prog::Int::>)
+ * 1: > (test_prog::Float::>)
index a4c370f..d8bc532 100644 (file)
@@ -1,12 +1,12 @@
 # Foo
 
- * 3: + (test_prog::Int::+)
- * 3: + (test_prog::Float::+)
  * 2: Bool (test_prog::Bool)
  * 3: Elf (test_prog::Elf)
  * 3: Float (test_prog::Float)
  * 3: Int (test_prog::Int)
  * 3: Sys (test_prog::Sys)
  * 3: age (test_prog::Character::age)
+ * 3: dps (test_prog::Weapon::dps)
+ * 3: man (test_prog>man>)
  * 3: rpg (test_prog::rpg)
  * 3: rpg (test_prog>rpg>)
index e907ec7..92b6106 100644 (file)
@@ -4,9 +4,9 @@ excluded test_prog
 excluded test_prog
 
 # mmodules:
-careers character combat excluded game game_examples platform races rpg test_prog
+careers character combat excluded game game_examples platform races rpg test_game test_prog
 ------------------------------------
-careers character combat excluded game game_examples platform races rpg test_prog
+careers character combat excluded game game_examples platform races rpg test_game test_prog
 
 # mclasses:
 Alcoholic Bool Career Character Combatable Dwarf Elf Float Game Human Int List Magician Object Race Starter String Sys Warrior Weapon
index ab1d9c6..6a7da0f 100644 (file)
@@ -1,4 +1,6 @@
 test_prog/
+|--test_prog/CONTRIBUTING.md
+|--test_prog/LICENSE.md
 |--test_prog/README.md
 |--test_prog/examples
 |  `--test_prog/examples/game_examples.nit
@@ -8,6 +10,8 @@ test_prog/
 |  |--test_prog/game/excluded_dir
 |  |  `--test_prog/game/excluded_dir/more.nit
 |  `--test_prog/game/game.nit
+|--test_prog/man
+|  `--test_prog/man/test_prog.man
 |--test_prog/package.ini
 |--test_prog/platform
 |  |--test_prog/platform/README.md
@@ -19,4 +23,6 @@ test_prog/
 |  |--test_prog/rpg/combat.nit
 |  |--test_prog/rpg/races.nit
 |  `--test_prog/rpg/rpg.nit
-`--test_prog/test_prog.nit
+|--test_prog/test_prog.nit
+`--test_prog/tests
+   `--test_prog/tests/test_game.nit
diff --git a/tests/test_prog/CONTRIBUTING.md b/tests/test_prog/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..9339f67
--- /dev/null
@@ -0,0 +1,5 @@
+# Contributing rules
+
+* Be nice
+* Be polite
+* Code well
diff --git a/tests/test_prog/LICENSE.md b/tests/test_prog/LICENSE.md
new file mode 100644 (file)
index 0000000..7b2f880
--- /dev/null
@@ -0,0 +1,3 @@
+# My Custom License
+
+This is the license content.
diff --git a/tests/test_prog/man/test_prog.man b/tests/test_prog/man/test_prog.man
new file mode 100644 (file)
index 0000000..813265b
--- /dev/null
@@ -0,0 +1,16 @@
+# NAME
+
+test_prog - a test program.
+
+
+# SYNOPSIS
+
+test_prog [*options*] ARGS...
+
+# OPTIONS
+
+### `--opt1`
+Option 1.
+
+### `--opt2`
+Option 2.
index bfcd472..f35fa33 100644 (file)
@@ -1,5 +1,6 @@
 [package]
 name=test_prog
+desc=Dummy program used for testing Nit tools
 version=0.1
 tags=test,game
 maintainer=John Doe <jdoe@example.com> (http://www.example.com/~jdoe), Spider-Man
index 175e6fc..7bd604f 100644 (file)
@@ -57,3 +57,8 @@ class String end
 
 # List of things.
 class List[E] end
+
+# Sys
+class Sys
+       fun main is intern
+end
diff --git a/tests/test_prog/tests/test_game.nit b/tests/test_prog/tests/test_game.nit
new file mode 100644 (file)
index 0000000..6d667a0
--- /dev/null
@@ -0,0 +1,33 @@
+# 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.
+
+module test_game is test
+
+import game
+
+class TestGame
+       super Game
+
+       redef var player_characters = new List[Character]
+end
+
+class GameTest
+       test
+
+       fun test_game is test do
+               var game1 = new TestGame
+               var game2 = new TestGame
+               assert game1 != game2
+       end
+end