Repository: cekit/cekit

Issue:
Suport description and example in Args
**Describe the solution you'd like**
Similar to env, args must support description or example params for documentation.

Discussion:
@jmtd: Here's the documentation for Args:
https://docs.cekit.io/en/latest/descriptor/image.html#args

Is the problem that it isn't clear enough, or that it's hard to find?@jmtd: It's also rendered in this page: https://docs.cekit.io/en/latest/descriptor/module.html#args@migueltercero: `Documentation` is clear and easy to find. I haven't explained myself clearly.

I like to do something like this:

```
args:
   - name: PARAM
     value: value
     example: value example
     description: this param is for ... 
```

example and description is supported in envs for documentation, but not for args. I think can be useful for documentation too.

Thank you.




Solution patch:
diff --git a/cekit/descriptor/arg.py b/cekit/descriptor/arg.py
index 67f880c..040f2a9 100644
--- a/cekit/descriptor/arg.py
+++ b/cekit/descriptor/arg.py
@@ -7,7 +7,8 @@ arg_schemas = yaml.safe_load(
 map:
   name: {type: str, required: True}
   value: {type: str}
-"""
+  example: {type: str}
+  description: {type: str}"""
 )
 
 
@@ -37,3 +38,19 @@ class Arg(Descriptor):
     @value.setter
     def value(self, value: str):
         self._descriptor["value"] = value
+
+    @property
+    def example(self) -> str:
+        return self.get("example")
+
+    @example.setter
+    def example(self, value: str):
+        self._descriptor["example"] = value
+
+    @property
+    def description(self) -> str:
+        return self.get("description")
+
+    @description.setter
+    def description(self, value: str):
+        self._descriptor["description"] = value
diff --git a/cekit/descriptor/env.py b/cekit/descriptor/env.py
index 5d7949b..6d8a176 100644
--- a/cekit/descriptor/env.py
+++ b/cekit/descriptor/env.py
@@ -8,7 +8,7 @@ env_schema = yaml.safe_load(
     """
 type: map
 allowempty: True
-mapping:
+map:
   name: {type: str, required: True}
   value: {type: any}
   example: {type: any}
diff --git a/docs/descriptor/includes/args.rst b/docs/descriptor/includes/args.rst
index 7f88231..bb343b6 100644
--- a/docs/descriptor/includes/args.rst
+++ b/docs/descriptor/includes/args.rst
@@ -19,3 +19,6 @@ details. CEKit makes it easy to do so with the ``args`` section. An optional def
         - name: "user1"
           value: "someuser"
         - name: "QUARKUS_EXTENSION"
+        - name: "ARG_WITH_DESCRIPTION"
+          example: "ARG_WITH_DESCRIPTION=a-value"
+          description: "Example argument."
diff --git a/docs/handbook/modules/merging.rst b/docs/handbook/modules/merging.rst
index dfc7c4a..ddde631 100644
--- a/docs/handbook/modules/merging.rst
+++ b/docs/handbook/modules/merging.rst
@@ -73,6 +73,7 @@ This section will go through it and explain how we combine everything together i
         node [shape="box", fontname="Open Sans", fontsize="10", style="filled", fillcolor="white"];
         bgcolor="transparent";
 
+        artifacts [label="Artifact Copying", href="#artifacts"];
         packages [label="Package installation", href="#packages"];
         envs [label="Environment variables", href="#environment-variables"];
         labels [label="Labels", href="#labels"];
@@ -80,14 +81,30 @@ This section will go through it and explain how we combine everything together i
         execs [label="Executions", href="#executions"];
         volumes [label="Volumes", href="#volumes"];
 
-        packages -> envs -> labels -> ports -> execs -> volumes [color="red"];
+        artifacts -> packages -> envs -> labels -> ports -> execs -> volumes [color="red"];
      }
 
 
+Artifacts
+^^^^^^^^^^^
+
+The first thing done for each module is the copying of any defined :ref:`artifacts <descriptor/module:Artifacts>`.
+This is useful to ensure files are copied into the container. This can avoid needing an explicit script (triggered
+by ``execute:``) that copies the files. Instead the files can be listed:
+
+.. code-block:: yaml
+
+    artifacts:
+      - path: artifacts/maven.module
+        dest: /etc/dnf/modules.d`
+
+.. note::
+    It is recommended to set the chmod/chown permissions correctly on the initial files so they are preserved upon copy.
+
 Packages
 ^^^^^^^^^^^
 
-The first thing done for each module is the package installation for all :ref:`packages defined in the module <descriptor/module:Packages to install>`.
+Next is the package installation for all :ref:`packages defined in the module <descriptor/module:Packages to install>`.
 We do not clean the cache on each run, because this
 would slow subsequent package manager executions. You should also not worry about it taking too much space,
 because every image is squashed (depends on builder though).


Test patch:
diff --git a/tests/test_unit_descriptor.py b/tests/test_unit_descriptor.py
index c5bfb1c..c0d856b 100644
--- a/tests/test_unit_descriptor.py
+++ b/tests/test_unit_descriptor.py
@@ -43,6 +43,7 @@ def test_arg():
     )
     assert arg.name == "QUARKUS_EXTENSIONS"
     assert arg.value is None
+    assert arg.description is None
 
 
 def test_env():
@@ -200,6 +201,11 @@ def test_image():
     from: foo
     name: test/foo
     version: 1.9
+    args:
+      - name: "user1"
+        value: "someuser"
+        description: "Some description"
+        example: "Set this example"
     labels:
       - name: test
         value: val1
@@ -210,6 +216,7 @@ def test_image():
         value: env1val
         required: false
         usage: build-time
+        description: "Env description"
     """
         ),
         "foo",
@@ -219,6 +226,9 @@ def test_image():
     assert isinstance(image["labels"][0], Label)
     assert image["labels"][0]["name"] == "test"
     assert image["envs"][0]["required"] is False
+    assert image["envs"][0].description == "Env description"
+    assert image["args"][0].description == "Some description"
+    assert image["args"][0].example == "Set this example"
 
 
 def test_image_missing_name():