Skip to content

Commit

Permalink
Closes #78: Generate TODO.md from @todo (and similar) comments (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
Búgvi Benjamin Magnussen authored and kasperisager committed Jun 28, 2019
1 parent bb9bff7 commit 43fe125
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 5 deletions.
38 changes: 38 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## [@siteimprove/alfa-css](packages/alfa-css)

### @todo

- [src/properties/text-decoration/color/property.ts:21](packages/alfa-css/src/properties/text-decoration/color/property.ts#L21): Should be currentColor when supported in colorGrammar

## [@siteimprove/alfa-dom](packages/alfa-dom)

### @todo

- [src/is-rendered.ts:19](packages/alfa-dom/src/is-rendered.ts#L19): Handle `display: contents` once it gains wider support.

## [@siteimprove/alfa-aria](packages/alfa-aria)

### @todo

- [src/features/html/th.ts:6](packages/alfa-aria/src/features/html/th.ts#L6): Need to handle the auto state
- [src/features/svg/a.ts:21](packages/alfa-aria/src/features/svg/a.ts#L21): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/circle.ts:10](packages/alfa-aria/src/features/svg/circle.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/ellipse.ts:10](packages/alfa-aria/src/features/svg/ellipse.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/foreign-object.ts:10](packages/alfa-aria/src/features/svg/foreign-object.ts#L10): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/g.ts:10](packages/alfa-aria/src/features/svg/g.ts#L10): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/image.ts:10](packages/alfa-aria/src/features/svg/image.ts#L10): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/line.ts:10](packages/alfa-aria/src/features/svg/line.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/mesh.ts:10](packages/alfa-aria/src/features/svg/mesh.ts#L10): In certain rare circumstances the role will in this case be img. Investigate.
- [src/features/svg/path.ts:10](packages/alfa-aria/src/features/svg/path.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/polygon.ts:10](packages/alfa-aria/src/features/svg/polygon.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/polyline.ts:10](packages/alfa-aria/src/features/svg/polyline.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/rect.ts:10](packages/alfa-aria/src/features/svg/rect.ts#L10): In certain rare circumstances the role will in this case be graphics-symbol. Investigate.
- [src/features/svg/symbol.ts:10](packages/alfa-aria/src/features/svg/symbol.ts#L10): In certain rare circumstances the role will in this case be graphics-object. Investigate.
- [src/features/svg/text-path.ts:10](packages/alfa-aria/src/features/svg/text-path.ts#L10): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/tspan.ts:10](packages/alfa-aria/src/features/svg/tspan.ts#L10): In certain rare circumstances the role will in this case be group. Investigate.
- [src/features/svg/use.ts:10](packages/alfa-aria/src/features/svg/use.ts#L10): In certain rare circumstances the role will in this case be graphics-object. Investigate.

### @bug

- [src/features/svg/text-path.ts:11](packages/alfa-aria/src/features/svg/text-path.ts#L11): There is an open issue regarding the role mapping for textPath
- [src/features/svg/tspan.ts:11](packages/alfa-aria/src/features/svg/tspan.ts#L11): There is an open issue regarding the role mapping for tspan
57 changes: 57 additions & 0 deletions scripts/helpers/iterable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,60 @@ function forEach(iterable, iteratee) {
}

exports.forEach = forEach;

/**
* @template T
* @template G
* @param {Iterable<T>} iterable
* @param {(item: T) => G} grouper
* @return {Iterable<[G, Iterable<T>]>}
*/
function groupBy(iterable, grouper) {
const result = new Map();
for (const item of iterable) {
const group = grouper(item);
const retrieved = result.get(group);
if (retrieved === undefined) {
result.set(group, [item]);
} else {
retrieved.push(item);
}
}
return result;
}

exports.groupBy = groupBy;

/**
* @template T
* @template G
* @param {Iterable<T>} iterable
* @param {(item: T) => G} mapper
* @return {Iterable<G>}
*/
function map(iterable, mapper) {
const result = [];
for (const item of iterable) {
result.push(mapper(item));
}
return result;
}

exports.map = map;

/**
* @template T
* @template G
* @param {Iterable<T>} iterable
* @param {(item: T) => Iterable<G>} mapper
* @return {Iterable<G>}
*/
function flatMap(iterable, mapper) {
const result = [];
for (const item of iterable) {
result.push(...mapper(item));
}
return result;
}

exports.flatMap = flatMap;
9 changes: 9 additions & 0 deletions scripts/helpers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,15 @@ class Project {
return TypeScript.forEachChild(node, visit);
}
}

/**
* @param {string} file
* @param {Iterable<TypeScript.TodoCommentDescriptor>} descriptors
* @return {Iterable<TypeScript.TodoComment>}
*/
getTodos(file, descriptors) {
return this.service.getTodoComments(file, [...descriptors]);
}
}

exports.Project = Project;
Expand Down
104 changes: 104 additions & 0 deletions scripts/helpers/todos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const path = require("path");
const prettier = require("prettier");
const TypeScript = require("typescript");

const { readFile, writeFile } = require("./file-system");
const { getLineAtOffset, parseLines } = require("./text");
const { flatMap, groupBy, map } = require("./iterable");
const { Project } = require("../helpers/project");

/**
* @typedef {import("./text").Line} Line
*/

/**
* @typedef {Object} Todo
* @property {string} file
* @property {string} pkg
* @property {TypeScript.TodoComment} comment
*/

/**
* @type {Array<TypeScript.TodoCommentDescriptor>}
*/
const checks = [
{ text: "@todo", priority: 1 },
{ text: "@hack", priority: 1 },
{ text: "@bug", priority: 1 },
{ text: "@fixme", priority: 1 }
];

/**
* @param {string} file
* @param {string} pkg
* @param {Project} project
* @return {Iterable<Todo>}
*/
function getTodos(file, pkg, project) {
return [...project.getTodos(file, checks)].map(comment => ({
file,
pkg,
comment
}));
}

exports.getTodos = getTodos;

/**
* @param {string} file
* @param {Iterable<Todo>} todos
*/
function writeTodos(file, todos) {
const todosByPackage = groupBy(todos, todo => todo.pkg);

const contentByPackage = map(todosByPackage, ([pkg, todos]) => {
const todosByFile = groupBy(todos, todo => todo.file);

const contentByFile = flatMap(todosByFile, ([file, todos]) => {
const lines = parseLines(readFile(file));

file = file.split(path.sep).join("/");

return map(todos, todo => {
const line = getLineAtOffset(lines, todo.comment.position).index + 1;
const message = todo.comment.message.substring(
todo.comment.descriptor.text.length + 1
);
const type = todo.comment.descriptor.text.toLowerCase();
const content = `* [${file.replace(
`packages/${todo.pkg}/`,
""
)}:${line}](${file}#L${line}): ${message}\n`;
return { type, content };
});
});

const contentByTypeGrouped = groupBy(contentByFile, todo => todo.type);

return { pkg, contentByTypeGrouped };
});

let content = "";

for (const item of contentByPackage) {
content += `## [@siteimprove/${item.pkg}](packages/${item.pkg})\n`;

for (const [type, todos] of item.contentByTypeGrouped) {
content += `### ${type}\n`;

for (const todo of todos) {
content += todo.content;
}

content += "\n";
}
}

content = prettier.format(content, {
parser: "markdown"
});

writeFile(file, content);
}

exports.writeTodos = writeTodos;
33 changes: 28 additions & 5 deletions scripts/prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@ const { endsWith } = require("./helpers/predicates");
const { workspace } = require("./helpers/workspace");
const { packages } = require("./helpers/meta");
const { forEach } = require("./helpers/iterable");
const { getTodos, writeTodos } = require("./helpers/todos");
const time = require("./helpers/time");
const notify = require("./helpers/notify");

const { build } = require("./tasks/build");
const { diagnose } = require("./tasks/diagnose");
const { clean } = require("./tasks/clean");

/**
* @typedef {import("./helpers/todos").Todo} Todo
*/

/**
* @type {Array<Todo>}
*/
const todos = [];

/**
* @param {string} file
* @param {string} pkg
*/
function handle(file) {
function handle(file, pkg) {
const start = time.now();

const project = workspace.projectFor(file);
Expand All @@ -33,18 +44,30 @@ function handle(file) {
} else {
process.exit(1);
}

todos.push(...getTodos(file, pkg, project));
}

forEach(findFiles("scripts", endsWith(".js")), handle);
forEach(findFiles("scripts", endsWith(".js")), file => {
handle(file, "scripts");
});

for (const pkg of packages) {
const root = `packages/${pkg}`;

clean(root);

forEach(findFiles(`${root}/scripts`, endsWith(".js")), handle);
forEach(findFiles(`${root}/scripts`, endsWith(".js")), file => {
handle(file, pkg);
});

forEach(findFiles(root, endsWith(".ts", ".tsx")), handle);
forEach(findFiles(root, endsWith(".ts", ".tsx")), file => {
handle(file, pkg);
});
}

forEach(findFiles("docs", endsWith(".ts", ".tsx")), handle);
forEach(findFiles("docs", endsWith(".ts", ".tsx")), file => {
handle(file, "docs");
});

writeTodos("TODO.md", todos);
1 change: 1 addition & 0 deletions scripts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"helpers/project.js",
"helpers/text.js",
"helpers/time.js",
"helpers/todos.js",
"helpers/typescript.js",
"helpers/workspace.js",
"precommit.js",
Expand Down

0 comments on commit 43fe125

Please sign in to comment.