Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / platform / app_annotations.nit
index 4862c9b..6f09790 100644 (file)
@@ -21,19 +21,31 @@ import literal
 import semantize
 private import annotation
 
-# Metadata associated to an Android project
+# Metadata associated to an `app.nit` project
 class AppProject
-       # Name of the resulting application
-       var name: nullable String = null
+       # Pretty name of the resulting application
+       var name: String = mainmodule.first_real_mmodule.name is lazy
+
+       # Short project name used in `namespace` and configuration files
+       var short_name: String = mainmodule.name.replace("-", "_") is lazy
 
        # Namespace/package used to identify the application
-       var namespace: nullable String = null
+       var namespace = "org.nitlanguage.{short_name}" is lazy
 
        # Version of the application
-       var version: nullable String = null
+       var version = "0.1"
 
        # Numerical version code of the application
-       var version_code: Int = 0
+       var version_code: Int is lazy do
+
+               # Get the date and time (down to the minute) as string
+               var gmtime = new Tm.gmtime
+               var local_time_s = gmtime.strftime("%y%m%d%H%M")
+               return local_time_s.to_i
+       end
+
+       # Extra folders where to find platform specific resource files
+       var files = new Array[String]
 
        private var modelbuilder: ModelBuilder
        private var mainmodule: MModule
@@ -41,26 +53,30 @@ class AppProject
        init
        do
                var annot = modelbuilder.lookup_annotation_on_modules("app_name", mainmodule)
-               if annot != null then name = annot.arg_as_string(modelbuilder)
+               if annot != null then
+                       var val = annot.arg_as_string(modelbuilder)
+                       if val != null then name = val
+               end
 
                annot = modelbuilder.lookup_annotation_on_modules("app_version", mainmodule)
                if annot != null then version = annot.as_version(modelbuilder)
 
                annot = modelbuilder.lookup_annotation_on_modules("app_namespace", mainmodule)
-               if annot != null then namespace = annot.arg_as_string(modelbuilder)
+               if annot != null then
+                       var val = annot.arg_as_string(modelbuilder)
+                       if val != null then namespace = val
+               end
 
-               # Get the date and time (down to the minute) as string
-               var local_time = new Tm.localtime
-               var local_time_s = local_time.strftime("%y%m%d%H%M")
-               version_code = local_time_s.to_i
+               var annots = modelbuilder.collect_annotations_on_modules("app_files", mainmodule)
+               for a in annots do files.add_all a.as_relative_paths(modelbuilder)
 
                modelbuilder.toolcontext.check_errors
        end
 
        redef fun to_s do return """
-name: {{{name or else "null"}}}
-namespace: {{{namespace or else "null"}}}
-version: {{{version or else "null"}}}"""
+name: {{{name}}}
+namespace: {{{namespace}}}
+version: {{{version}}}"""
 end
 
 redef class AAnnotation
@@ -74,12 +90,10 @@ redef class AAnnotation
 
                var args = n_args
                if args.length < 1 then
-                       modelbuilder.error(self, "Annotation error: \"{name}\" expects at least a single argument.")
+                       modelbuilder.error(self, "Syntax Error: `{name}` expects at least one argument.")
                        return ""
                else
                        for arg in args do
-                               var format_error = "Annotation error: \"{name}\" expects its arguments to be of type Int or a call to `git_revision`"
-
                                var value
                                value = arg.as_int
                                if value != null then
@@ -97,7 +111,13 @@ redef class AAnnotation
                                        # Get Git short revision
                                        var proc = new ProcessReader("git", "rev-parse", "--short", "HEAD")
                                        proc.wait
-                                       assert proc.status == 0
+                                       if proc.status != 0 then
+                                               # Fallback if this is not a git repository or git bins are missing
+                                               version_fields.add "0"
+                                               modelbuilder.warning(self, "git_revision", "Warning: `git_revision` used outside of a git repository or git binaries not available")
+                                               continue
+                                       end
+
                                        var lines = proc.read_all
                                        var revision = lines.split("\n").first
 
@@ -112,6 +132,7 @@ redef class AAnnotation
                                        continue
                                end
 
+                               var format_error = "Syntax Error: `{name}` expects its arguments to be of type Int or a call to `git_revision`."
                                modelbuilder.error(self, format_error)
                                return ""
                        end
@@ -119,4 +140,29 @@ redef class AAnnotation
 
                return version_fields.join(".")
        end
+
+       # Parse all arguments as paths relative to the declaring module
+       #
+       # If no arguments are given, then use the parent directory of the module.
+       private fun as_relative_paths(modelbuilder: ModelBuilder): Array[String]
+       do
+               var paths = new Array[String]
+
+               var file = location.file
+               if file == null then return paths
+
+               var args = n_args
+               if args.is_empty then
+                       paths.add file.filename.dirname
+               else
+                       for arg in args do
+                               var val = arg.as_string
+                               if val != null then
+                                       paths.add file.filename.dirname/val
+                               else modelbuilder.error(arg, "Syntax Error: `app_files` expects String literals as arguments.")
+                       end
+               end
+
+               return paths
+       end
 end