esp-idf-lib/Metadata.md

changeset 1
1c9894662795
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp-idf-lib/Metadata.md	Mon Mar 27 22:13:21 2023 +0200
@@ -0,0 +1,309 @@
+# Metadata
+
+## Table of Contents
+
+<!-- vim-markdown-toc GFM -->
+
+* [Purpose](#purpose)
+* [Files](#files)
+    * [`.eil.yml`](#eilyml)
+    * [`persons.yml`](#personsyml)
+    * [`groups.yml`](#groupsyml)
+    * [`targets.yml`](#targetsyml)
+* [Resources](#resources)
+    * [Person](#person)
+    * [Target](#target)
+    * [License](#license)
+    * [Copyright](#copyright)
+    * [Group](#group)
+    * [Metadata](#metadata)
+    * [Component](#component)
+* [Usages of metadata in the project](#usages-of-metadata-in-the-project)
+    * [Validating metadata of components](#validating-metadata-of-components)
+    * [Generating `README.md`](#generating-readmemd)
+* [Known issues](#known-issues)
+    * [conditional `depends`](#conditional-depends)
+
+<!-- vim-markdown-toc -->
+
+This document describes metadata used in the project. The status of the
+document is beta.
+
+## Purpose
+
+The purpose of metadata in the project is to automate works in development and
+project management, to ensure the project policies, and to extend the project
+to support third-party projects.
+
+## Files
+
+### `.eil.yml`
+
+The metadata file of a component.  Each component must have `.eil.yml` in the
+root directory of the component. The file format is YAML.
+
+An example path: `components/ads111x/.eil.yml`.
+
+### `persons.yml`
+
+`persons.yml` is a YAML file that contains a list of `Person`s.
+
+### `groups.yml`
+
+`groups.yml` is a YAML file that contains a list of `Group`s.
+
+### `targets.yml`
+
+`targets.yml` is a YAML file that contains a list of `Target`s.
+
+## Resources
+
+Resources defined here represents various objects used in the metadata.
+
+A resource has unique `name` as a primary key.
+
+When referring to a resource in another resource, use `name` as key and its
+value to identify the resource. As a shorthand, you may use the name of a
+resource as `String`. In this case, the value is assumed to be `name: $VALUE`.
+
+When a resource expects a `Person` as a value,
+
+```yaml
+foo:
+  name: trombik
+```
+
+This is a shorthand version of the above example:
+
+```yaml
+foo: trombik
+```
+
+### Person
+
+A `Person` represents a person. `Person` is used to describe a copyrights
+holder and a code owner. A `Person` must be defined in `persons.yml` file.
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `name` | `String` | A unique ID string of the person. Use GitHub account or GitHub project if the person has one | Yes |
+| `full_name` | `String` | Full name of the person or the project | No |
+| `gh_id` | `String` | GitHub account name or project name | No |
+| `email` | `String` | Email address of the person | No |
+| `website` | `String` | Web site URL | No |
+
+When any of `gh_id`, `email`, or `website` is not available, `person` must
+have a full name because it is used to identify the source of code.
+
+If the person does not have `gh_id`, use the full name for `name`. For example,
+when the full name is "Foo Bar", use `name: FooB`.
+
+`Person` should have one or more of optional keys so that one can contact the
+person.
+
+Examples:
+
+```yaml
+name: trombik
+gh_id: trombik
+full_name: Tomoyuki Sakurai
+email: y@trombik.org
+website: https://github.com/trombik
+```
+
+```yaml
+name: foo
+full_name: Foo `bar` buz
+# XXX other keys are optional, but strongly recommended.
+```
+
+### Target
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `name` | `String` | Name of the build target in `esp-idf`, or `esp8266`. | Yes |
+
+An example:
+
+```yaml
+name: esp32
+```
+
+### License
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `name` | `String` | SPDX License Identifier (see [the list of licenses](https://spdx.org/licenses/)) | Yes |
+
+An example:
+
+```yaml
+name: BSD-3
+```
+
+### Copyright
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `author` | `Person` | Copyrights holder. See also `Person`. | No |
+| `name` | `String` | The value of `name` of `Person`. A shorthand for `author` | No |
+| `year` | `Integer` | Registration year of the copyrights | Yes |
+
+`Copyright` must have only one of `author` and `name`, not both.
+
+Examples:
+
+```yaml
+name: trombik
+year: 2021
+```
+
+The above example is a shorthand form of:
+
+```yaml
+author:
+  name: trombik
+year: 2021
+```
+
+### Group
+
+A `Group` represents a group of `Component`s. A `Group` must be in
+`groups.yml`.
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `name` | `String` | A unique ID of the group | Yes |
+| `description` | `String` | Description of the group | Yes |
+
+`name` should be short, and memorable. Use `-` as a word separator. It must
+not include spaces (`[0-9a-zA-Z-]+` in regular expression).
+
+An example:
+
+```yaml
+name: adc-dac
+description: ADC/DAC libraries
+```
+
+### Metadata
+
+`Metadata` is the content of `.eil.yml`. `Metadata` includes non-empty list of
+`Component` under `components` top level key.
+
+An example:
+
+```yaml
+---
+components:
+  - name: foo
+  # ... other keys go here ...
+```
+
+### Component
+
+| Name | Type | Description | Required |
+|------|------|-------------|----------|
+| `name` | `String` | The name of the component. Must be unique. | Yes |
+| `description` | `String` | A short description of the component. | Yes |
+| `group` | `Group` | The primary group name of the component. | Yes |
+| `groups` | A list of `Group` | A list of zero or more of `Group` | No |
+| `code_owners` | A list of `Person` | A list of one or more of `Person` | Yes |
+| `depends` | A list of `Component` | Zero or more of `component` that the component depends on | No |
+| `thread_safe` | `Strnig` | One of `yes`, `no`, and `N/A` | Yes |
+| `targets` | A list of `Target` | One or more of supported `target` | Yes |
+| `licenses` | A list of `License` | One or more of licenses used in the component | Yes |
+| `copyrights` | A list of `Copyright` | One or more of copyright holder | Yes |
+
+FIXME `depends` must be a list because some drivers have conditional `REQUIRES`
+in `CMakeLists.txt`.
+
+## Usages of metadata in the project
+
+The current implementation uses `ruby` and `rspec` ruby gem to validate
+metadata in all components, and generate `README.md`.
+
+Requirements are:
+
+* `ruby` 2.7 (other version should also work)
+* [`bundler`](https://bundler.io/)
+
+After installing requirements, run:
+
+```console
+bundle install
+```
+
+### Validating metadata of components
+
+To validate metadata, run:
+
+```console
+bundle exec rake -C devtools rspec
+```
+
+The implementation uses `rspec` to validate metadata because:
+
+1. the output is readable
+2. requires less `ruby` knowledge to maintain the spec than validating
+   everything in ruby code
+3. porting tests to other languages is easier than porting ruby code
+
+Under `spec` directory, there are:
+
+* `spec_helper.rb`, which is a helper for the test
+* `*_spec.rb`, which is a test script
+* other ruby files, such as `person.rb`, which are class definitions used in
+  the test
+
+The ruby classes for the test validate minimum requirements only, such as the
+`.eil.yml` file exists, or a resource has a required primary key. Actual
+test should be performed in `*_spec.rb` files.
+
+### Generating `README.md`
+
+`README.md` is generated from the metadata and `README.md.erb`. To update
+`README.md`, run the following command at the repository root directory:
+
+```console
+bundle exec rake -C devtools readme > README.md
+```
+
+## Known issues
+
+### conditional `depends`
+
+Some `CMakeLists.txt` conditionally sets `REQUIRES`. `depends` does not handle
+the following case.
+
+```yaml
+# for esp32
+depends:
+  - name: driver
+  - name: freertos
+  - name: log
+```
+
+```yaml
+# for esp8266
+depends:
+  - name: esp8266
+  - name: freertos
+  - name: log
+```
+
+A possible solution:
+
+```yaml
+depends:
+  - name: driver
+    target:
+      - name: esp32
+      - name: esp32s2
+      - name: esp32c3
+  - name: esp8266
+    target:
+      - name: esp8266
+  - name: freertos
+  - name: log
+```

mercurial