sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/genyaml/README.md (about)

     1  # Genyaml
     2  
     3  ## Description
     4  `genyaml` is a simple documentation tool used to marshal YAML from Golang structs. It extracts *doc comments* from `.go` sources files and adds them as *comment nodes* in the YAML output.
     5  
     6  ## Usage
     7  
     8  TODOs are ignored (e.g. TODO(clarketm)... or TODO...) if and only if they are on a **single** line.
     9  
    10  ```go
    11  type Employee struct {
    12  	// Name of employee
    13  	Name string
    14  	// Age of employee
    15  	Age int
    16      // TODO(clarketm): change this to a float64
    17  	// Salary of employee
    18  	Salary int
    19  }
    20  ```
    21  
    22  ```yaml
    23  # Age of employee
    24  Age: 22
    25  
    26  # Name of employee
    27  Name: Jim
    28  
    29  # Salary of employee
    30  Salary: 100000
    31  ```
    32  
    33  Multiline comments are preserved, albeit *tabs* are converted to *spaces* and *multiple* spaces are compressed into a *single* line.
    34  
    35  ```go
    36  type Multiline struct {
    37  	// StringField1 comment
    38  	// second line
    39  	// third line
    40  	StringField1 string `json:"string1"`
    41  
    42  	/* StringField2 comment
    43  	second line
    44  	third line
    45  	*/
    46  	StringField2 string `json:"string2"`
    47  
    48  	/* StringField3 comment
    49  			second line
    50  			third line
    51  	*/
    52  	StringField3 string `json:"string3"`
    53  }
    54  ```
    55  
    56  ```yaml
    57  # StringField1 comment
    58  # second line
    59  # third line
    60  string1: string1
    61  
    62  # StringField2 comment
    63  # second line
    64  # third line
    65  string2: string2
    66  
    67  # StringField3 comment
    68  # second line
    69  # third line
    70  string3: string3
    71  ```
    72  
    73  All subsequent lines and blocks after a `---` will be ignored.
    74  
    75  ```go
    76  type Person struct {
    77  	// Name of person
    78  	// ---
    79  	// The name of the person is both the first and last name separated
    80  	// by a space character
    81  	Name string
    82  }
    83  ```
    84  
    85  ```yaml
    86  # Name of person
    87  Name: Frank
    88  ```
    89  
    90  Generator instructions prefixed with a `+` are ignored.
    91  
    92  ```go
    93  type Dog struct {
    94  	// Gender of dog (male|female)
    95  	// +optional
    96  	Gender string `json:"gender,omitempty"`
    97  	// Weight in pounds of dog
    98  	Weight int `json:"weight,omitempty"`
    99  }
   100  ```
   101  
   102  ```yaml
   103  # Gender of dog (male|female)
   104  gender: male
   105  
   106  # Weight in pounds of dog
   107  weight: 150
   108  ```
   109  
   110  ## Example
   111  
   112  First, assume there is a Go file `config.go` with the following contents:
   113  > NOTE: `genyaml` reads **json** tags for maximum portability.
   114  
   115  ```go
   116  // config.go
   117  
   118  package example
   119  
   120  type Configuration struct {
   121  	// Plugin comment
   122  	Plugin []Plugin `json:"plugin,omitempty"`
   123  }
   124  
   125  type Plugin struct {
   126  	// StringField comment
   127  	StringField string `json:"string,omitempty"`
   128  	// BooleanField comment
   129  	BooleanField bool `json:"boolean,omitempty"`
   130  	// IntegerField comment
   131  	IntegerField int `json:"integer,omitempty"`
   132  }
   133  //...
   134  ```
   135  
   136  Next, in a separate `example.go` file, initialize a `Configuration` struct and marshal it to *commented* YAML.
   137  
   138  ```go
   139  // example.go
   140  
   141  package example
   142  
   143  // Import genyaml
   144  import "sigs.k8s.io/prow/pkg/genyaml"
   145  
   146  //...
   147  
   148  // Initialize a `Configuration` struct:
   149  config := &example.Configuration{
   150      Plugin: []example.Plugin{
   151          {
   152              StringField:  "string",
   153              BooleanField: true,
   154              IntegerField: 1,
   155          },
   156      },
   157  }
   158  
   159  // Initialize a CommentMap instance from the `config.go` source file:
   160  cm, err := genyaml.NewCommentMap(nil, "config.go")
   161  
   162  // Generate a commented YAML snippet:
   163  yamlSnippet, err := cm.GenYaml(config)
   164  ```
   165  
   166  The doc comments are extracted from the `config.go` file and attached to the corresponding YAML fields:
   167  
   168  ```go
   169  fmt.Println(yamlSnippet)
   170  ```
   171  
   172  ```yaml
   173  # Plugin comment
   174  plugin:
   175    - # BooleanField comment
   176      boolean: true
   177  
   178      # IntegerField comment
   179      integer: 1
   180  
   181      # StringField comment
   182      string: string
   183  
   184  ```
   185  
   186  ## Limitations / Going Forward
   187  
   188  - [ ] Embedded structs must include a tag name (i.e. must not be *spread*), otherwise the type can not be inferred from the YAML output.
   189  - [ ] Interface types, more specifically concrete types implementing a particular interface, can can not be inferred from the YAML output.
   190  - [ ] Upstream this functionality to `go-yaml` (or a fork) to leverage custom formatting of YAML and direct reflection on types for resolving embedded structs and interface types across multiple source files.