Skip to content

Commit

Permalink
Docs: adding API reference documentation support for the packages lib…
Browse files Browse the repository at this point in the history
…raries. (grafana#21931)

* trying out api-extractor.

* works with our setup of build.

* wip.

* changed the packages so it works better with the api-extractor.

* Changes to make the api-extractor to work.

* cleaned up the api-extractor config files.

* added some more documentation.

* added tsdoc-metadata to gitignore.

* removed the generated docs (will do that in another PR).

* added execute permission to script for generating dosc.

* added so we will push generated docs to branch.

* will clean packages_api on abort.

* Fixed failing tests.

* fixed formatting issue with typedoc comment.

* temporarily disabled tslint rules about namespace until microsoft/rushstack#1029 is resolved

* temporary enabled bable namespaces.

* updated build script.

* updated script.

* updated script with some colors.

* changed to camelCase.

* removed spacing.

* Starting to add documentation guidelines.

* added examples headline.

* added parameters and return values.

* Fixed merge error.

* changed so we use the eslint ignore syntax.

* changed to correct eslint ingnore comment.

* fixed some spelling errors reported by codespell.

* added script to generate docs in current folder.

* lerna bootstrap.

* removed file that should be ignored.

* updated locKFILE.

* referenced the code comments guidelines.

* updated packages.

* updated deps.
  • Loading branch information
mckn authored Feb 25, 2020
1 parent 002d211 commit e2038e0
Show file tree
Hide file tree
Showing 39 changed files with 899 additions and 389 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ debug.test
/packages/**/dist
/packages/**/compiled
/packages/**/.rpt2_cache
/packages/**/tsdoc-metadata.json

# Ignore go local build dependencies
/scripts/go/bin/**
Expand Down
34 changes: 34 additions & 0 deletions api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
"bundledPackages": [],
"compiler": {},
"apiReport": {
"enabled": false
},
"docModel": {
"enabled": true,
"apiJsonFilePath": "<projectFolder>/../../reports/docs/<unscopedPackageName>.api.json"
},
"dtsRollup": {
"enabled": false
},
"tsdocMetadata": {},
"messages": {
"compilerMessageReporting": {
"default": {
"logLevel": "warning"
}
},
"extractorMessageReporting": {
"default": {
"logLevel": "warning"
}
},
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
}
}
}
}
209 changes: 209 additions & 0 deletions contribute/style-guides/code-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Guidelines for code comments in grafana-* packages

This document aims to give you some recommendation on how to add code comments to the exported code in the grafana packages.

## Table of Contents

1. [Add package description](#add-package-description)
1. [Set stability of an API](#set-stability-of-an-api)
1. [Deprecate an API](#deprecate-an-api)
1. [Specify parameters](#specify-parameters)
1. [Set return values](#set-return-values)
____

## Add package description

Each package has an overview explaining the overall responsibility and usage of the package.

You can document this description with [`@packageDocumentation`](https://api-extractor.com/pages/tsdoc/tag_packagedocumentation/) tag.

Add this tag to the `<packageRoot>/src/index.ts` entry file to have one place for the package description.

## Set stability of an API

All `exported` apis from the package should have a release tag to indicate its stability.

- [`@alpha`](https://api-extractor.com/pages/tsdoc/tag_alpha/) - early draft of api and will probably change.
- [`@beta`](https://api-extractor.com/pages/tsdoc/tag_beta/) - close to being stable but might change.
- [`@public`](https://api-extractor.com/pages/tsdoc/tag_public/) - ready for useage in production.
- [`@internal`](https://api-extractor.com/pages/tsdoc/tag_internal/) - for internal use only.

### Main stability of APIs

Add a tag to mark the stability of the whole exported `class/interface/function/type` etc.

Please place the `release tag` at the bottom of the comment to make it consistent among files and easier to read.

**Do:**

```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
*
* @public
**/
export class DataFrameFactory {
create(): DataFrame { }
}
```

**Don't**
```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @public
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
**/
export class DataFrameFactory {
create(): DataFrame { }
}
```

### Partial stability of APIs

Add the main stability of the API at the top according to [Main stability of API](#main-stability-of-api).

Then override the non-stable parts of the API with the proper [release tag](#release-tags). This should also be place at the bottom of the comment block.

**Do:**

```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
*
* @public
**/
export class DataFrameFactory {
create(): DataFrame { }

/**
* @beta
**/
createMany(): DataFrames[] {}
}
```

**Don't**

```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
**/
export class DataFrameFactory {
/**
* @public
**/
create(): DataFrame { }

/**
* @beta
**/
createMany(): DataFrame[] {}
}
```

## Deprecate an API
If you want to mark an API as deprecated to signal that this API will be removed in the future, then add the [`@deprecated`](https://api-extractor.com/pages/tsdoc/tag_deprecated/) tag.

If applicable add a reason why the API is deprecated directly after the `@deprecated tag`.

## Specify parameters
If you want to specify the possible parameters that can be passed to an API, then add the [`@param`](https://api-extractor.com/pages/tsdoc/tag_param/) tag.

This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the parameters are.

**Do:**

```typescript
/**
* Will help to create a resource resovler depending
* on the current execution context.
*
* @param context - The current execution context.
* @returns FileResolver if executed on the server otherwise a HttpResolver.
* @public
**/
export const factory = (context: Context): IResolver => {
if (context.isServer) {
return new FileResolver();
}
return new HttpResolver();
}
```

**Don't**

```typescript
/**
* Will compare two numbers to see if they are equal to each others.
*
* @param x - The first number
* @param y - The second number
* @public
**/
export const isEqual = (x: number, y: number): boolean => {
return x === y;
}
```


## Set return values
If you want to specify the return value from a function you can use the [`@returns`](https://api-extractor.com/pages/tsdoc/tag_returns/) tag.

This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the function returns.

**Do:**

```typescript
/**
* Will help to create a resource resovler depending
* on the current execution context.
*
* @param context - The current execution context.
* @returns FileResolver if executed on the server otherwise a HttpResolver.
* @public
**/
export const factory = (context: Context): IResolver => {
if (context.isServer) {
return new FileResolver();
}
return new HttpResolver();
}
```

**Don't**

```typescript
/**
* Will compare two numbers to see if they are equal to each others.
*
* @returns true if values are equal
* @public
**/
export const isEqual = (x: number, y: number): boolean => {
return x === y;
}
```
1 change: 1 addition & 0 deletions contribute/style-guides/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ For code that needs to be used by external plugin:
- Use [TSDoc](https://github.com/microsoft/tsdoc) comments to document your code.
- Use [react-docgen](https://github.com/reactjs/react-docgen) comments (`/** ... */`) for props documentation.
- Use inline comments for comments inside functions, classes etc.
- Please try to follow the [code comment guidelines](./code-comments.md) when adding comments.

### Linting

Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"@babel/preset-react": "7.8.3",
"@babel/preset-typescript": "7.8.3",
"@emotion/core": "10.0.10",
"@grafana/api-documenter": "0.9.3",
"@microsoft/api-extractor": "7.7.8",
"@rtsao/plugin-proposal-class-properties": "7.0.1-patch.1",
"@testing-library/react-hooks": "^3.2.1",
"@types/angular": "1.6.56",
Expand Down Expand Up @@ -183,7 +185,9 @@
"packages:publish": "lerna publish from-package --contents dist",
"packages:publishLatest": "lerna publish from-package --contents dist --yes",
"packages:publishNext": "lerna publish from-package --contents dist --dist-tag next --yes",
"packages:publishCanary": "lerna publish from-package --contents dist --dist-tag canary --yes"
"packages:publishCanary": "lerna publish from-package --contents dist --dist-tag canary --yes",
"packages:docsExtract": "rm -rf ./scripts/docs && lerna run docsExtract",
"packages:docsToMarkdown": "api-documenter markdown --input-folder ./reports/docs/ --output-folder ./docs/sources/packages_api/ --hugo --draft"
},
"husky": {
"hooks": {
Expand Down
3 changes: 3 additions & 0 deletions packages/grafana-data/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../api-extractor.json"
}
3 changes: 2 additions & 1 deletion packages/grafana-data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"typecheck": "tsc --noEmit",
"clean": "rimraf ./dist ./compiled",
"bundle": "rollup -c rollup.config.ts",
"build": "grafana-toolkit package:build --scope=data"
"build": "grafana-toolkit package:build --scope=data",
"docsExtract": "api-extractor run 2>&1 | tee ../../reports/docs/$(basename $(pwd)).log"
},
"dependencies": {
"apache-arrow": "0.15.1",
Expand Down
41 changes: 28 additions & 13 deletions packages/grafana-data/src/dataframe/DataFrameView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@ import { DisplayProcessor } from '../types';
* This abstraction will present the contents of a DataFrame as if
* it were a well typed javascript object Vector.
*
* NOTE: The contents of the object returned from `view.get(index)`
* are optimized for use in a loop. All calls return the same object
* but the index has changed.
* @remarks
* The {@link DataFrameView.get} is optimized for use in a loop and will return same object.
* See function for more details.
*
* For example, the three objects:
* const first = view.get(0);
* const second = view.get(1);
* const third = view.get(2);
* will point to the contents at index 2
*
* If you need three different objects, consider something like:
* const first = { ... view.get(0) };
* const second = { ... view.get(1) };
* const third = { ... view.get(2) };
* @typeParam T - Type of object stored in the DataFrame.
* @beta
*/
export class DataFrameView<T = any> implements Vector<T> {
private index = 0;
Expand Down Expand Up @@ -56,6 +48,10 @@ export class DataFrameView<T = any> implements Vector<T> {
return this.data.length;
}

/**
* Helper function to return the {@link DisplayProcessor} for a given field column.
* @param colIndex - the field column index for the data frame.
*/
getFieldDisplayProcessor(colIndex: number): DisplayProcessor | null {
if (!this.dataFrame || !this.dataFrame.fields) {
return null;
Expand All @@ -70,6 +66,25 @@ export class DataFrameView<T = any> implements Vector<T> {
return field.display;
}

/**
* The contents of the object returned from this function
* are optimized for use in a loop. All calls return the same object
* but the index has changed.
*
* @example
* ```typescript
* // `first`, `second` and `third` will all point to the same contents at index 2:
* const first = view.get(0);
* const second = view.get(1);
* const third = view.get(2);
*
* // If you need three different objects, consider something like:
* const first = { ...view.get(0) };
* const second = { ...view.get(1) };
* const third = { ...view.get(2) };
* ```
* @param idx - The index of the object you currently are inspecting
*/
get(idx: number) {
this.index = idx;
return this.obj;
Expand Down
2 changes: 1 addition & 1 deletion packages/grafana-data/src/datetime/datemath.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sinon, { SinonFakeTimers } from 'sinon';
import each from 'lodash/each';

import * as dateMath from './datemath';
import { dateMath } from './datemath';
import { dateTime, DurationUnit, DateTime } from './moment_wrapper';

describe('DateMath', () => {
Expand Down
Loading

0 comments on commit e2038e0

Please sign in to comment.