Skip to content

Commit

Permalink
supported csv
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshixmk committed Aug 21, 2020
1 parent e9416a0 commit c321741
Show file tree
Hide file tree
Showing 11 changed files with 854 additions and 93 deletions.
10 changes: 10 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"deno.enable": true,
"deno.unstable": true,
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno",
},
"[typescriptreact]": {
"editor.defaultFormatter": "denoland.vscode-deno",
},
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ https://yoshixmk.github.io/deno-x-ranking
Prepare an access token for Github public access permission only from the following URL. When public access setting permissions, you can leave all check boxes cleared.
https://github.com/settings/tokens/new

### Tsv output
### Tsv / Csv output
```Shell
$ deno run --allow-net --allow-write --allow-env https://deno.land/x/ranking/mod.ts -u <github username> -t <github token> -f tsv
$ deno run --allow-net --allow-write --allow-env https://deno.land/x/ranking/mod.ts -u <github username> -t <github token> -f <tsv | csv>
```

### Console output
Expand Down
694 changes: 694 additions & 0 deletions examples/ranking_result.csv

Large diffs are not rendered by default.

81 changes: 13 additions & 68 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,17 @@
import {
args,
EarlyExitFlag,
Option,
Choice,
green,
PARSE_FAILURE,
red,
PartialOption,
} from "./deps.ts";
import { consoleTable } from "./src/console_table.ts";
import { generateTsvFile } from "./src/tsv_file_creator.ts";
import { Csv, MarkdownFile, Table, Tsv } from "./src/domains/Format.ts";
import { SeparatedFileCreator } from "./src/file_creator.ts";
import { generateMarkdownFile } from "./src/markdown_file_creator.ts";
import { green, Text } from "./deps.ts";
import { registryService } from "./src/services/registry_service.ts";
import { parseArgs } from "./src/services/arg_service.ts";
import { githubService } from "./src/services/github_service.ts";
import { registryService } from "./src/services/registry_service.ts";

const Tsv = "tsv";
const Table = "table";
const MarkdownFile = "markdown";
type Format = typeof Tsv | typeof Table | typeof MarkdownFile;

const parser = args
.describe("Add or subtract two numbers")
.with(
EarlyExitFlag("help", {
describe: "Show help",
alias: ["h"],
exit() {
console.log(parser.help());
return Deno.exit();
},
}),
)
.with(
Option("username", {
type: Text,
describe: "Github account username without '@'. required token",
alias: ["u"],
}),
)
.with(
Option("token", {
type: Text,
describe: "Github account token. required username",
alias: ["t"],
}),
)
.with(
Option("format", {
type: Choice<Format>(
{
value: Tsv,
describe: "Output tsv file",
},
{
value: Table,
describe: "Output console table",
},
{
value: MarkdownFile,
describe: "Output markdown file",
},
),
alias: ["f"],
describe: "Choice output format",
}),
).with(
PartialOption("sampling", {
type: Text,
describe: "For testing, fetch a little sample from API. --sampling true",
default: "false",
}),
);
const parser = parseArgs();

const res = parser.parse(Deno.args);

Expand All @@ -80,7 +21,7 @@ if (res.tag === PARSE_FAILURE) {
Deno.exit(1);
}
console.dir(res.value);
const { help, username, token, format, sampling } = res.value;
const { help, username, token, format, outputFile, sampling } = res.value;

if (username === undefined || token === undefined) {
console.log(red("Needs to input both username and token."));
Expand All @@ -93,7 +34,8 @@ if (format === undefined) {

console.debug(green(`Started. format = ${format}`));

const githubEntries = await registryService.getGithubEntries(sampling);
const isSampling = sampling !== "false";
const githubEntries = await registryService.getGithubEntries(isSampling);

const githubRepositories = githubService.getGithubRepositories(
githubEntries,
Expand All @@ -107,11 +49,14 @@ switch (format) {
consoleTable(rankingEntries);
break;
case Tsv:
await generateTsvFile(rankingEntries);
case Csv:
await new SeparatedFileCreator(format, outputFile).generateFile(rankingEntries);
break;
case MarkdownFile:
await generateMarkdownFile(rankingEntries);
break;
default:
throw Error(`Cannot use the format, ${format}`);
}

console.debug(green(`End. format = ${format}`));
6 changes: 6 additions & 0 deletions src/domains/Format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const Tsv = "tsv";
export const Csv = "csv";
export const Table = "table";
export const MarkdownFile = "markdown";
export type FileFormat = typeof Tsv | typeof Csv
export type Format = FileFormat | typeof Table | typeof MarkdownFile;
2 changes: 1 addition & 1 deletion src/domains/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface Repository {
watchers: number;
subscribers_count: number;
archived: boolean;
description: string;
description?: string;
}

export type Repositories = Array<Repository>;
47 changes: 47 additions & 0 deletions src/file_creator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Repository } from "./domains/repository.ts";
import { FileFormat, Tsv, Csv } from "./domains/Format.ts";

export class SeparatedFileCreator {
private format: FileFormat;
private separator: string;
private outputFilePath: string;

constructor(format: FileFormat, outputFilePath: string) {
this.format = format;
this.outputFilePath = outputFilePath === ""
? `./examples/ranking_result.${format}`
: outputFilePath;
switch (format) {
case Tsv:
this.separator = '"\t"';
break;
case Csv:
this.separator = ', ';
break;
default:
throw Error(`Cannot use the format, ${format}`);
}
}

generateFile = async (result: Repository[]) => {
const encoder = new TextEncoder();
const escapeQuote = (s: string) => s.replaceAll('"', '""');
const doubleQuote = (s: string) => `"${escapeQuote(s)}"`;
const data = result.map((r) =>
[
r.name,
r.full_name,
r.html_url,
r.stargazers_count,
r.forks,
r.watchers,
r.subscribers_count,
r.archived,
r.description ?? "",
]
.map((s) => doubleQuote(s.toString()))
.join(this.separator)
).join("\n");
await Deno.writeFile(this.outputFilePath, encoder.encode(data));
};
}
2 changes: 1 addition & 1 deletion src/markdown_file_creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function generateMarkdownFile(
link(r.full_name, r.html_url),
r.stargazers_count?.toString(),
r.forks?.toString(),
r.description,
r.description ?? "",
],
);
});
Expand Down
78 changes: 78 additions & 0 deletions src/services/arg_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
args,
EarlyExitFlag,
Option,
Choice,
PartialOption,
} from "../../deps.ts";
import { Text } from "../../deps.ts";
import { Format, Tsv, Table, MarkdownFile, Csv } from "../domains/Format.ts";

export const parseArgs = () => {
const parser = args
.describe("Add or subtract two numbers")
.with(
EarlyExitFlag("help", {
describe: "Show help",
alias: ["h"],
exit() {
console.log(parser.help());
return Deno.exit();
},
}),
)
.with(
Option("username", {
type: Text,
describe: "Github account username without '@'. required token",
alias: ["u"],
}),
)
.with(
Option("token", {
type: Text,
describe: "Github account token. required username",
alias: ["t"],
}),
)
.with(
Option("format", {
type: Choice<Format>(
{
value: Tsv,
describe: "Output tsv file",
},
{
value: Csv,
describe: "Output csv file",
},
{
value: Table,
describe: "Output console table",
},
{
value: MarkdownFile,
describe: "Output markdown file",
},
),
alias: ["f"],
describe: "Choice output format",
}),
).with(
PartialOption("outputFile", {
type: Text,
describe:
"Output file path. Only file like tsv and csv.",
alias: ["o"],
default: "",
}),
).with(
PartialOption("sampling", {
type: Text,
describe:
"For testing, fetch a little sample from API. --sampling true",
default: "false",
}),
);
return parser;
};
4 changes: 2 additions & 2 deletions src/services/registry_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class RegistryService {
}

public async getGithubEntries(
sampling: string,
isSampling: boolean,
): Promise<GithubEntries> {
const modules = await fetchAll();
const moduleNames = modules
Expand All @@ -39,7 +39,7 @@ class RegistryService {
"latestVersion": meta.upload_options.ref,
};
});
if (sampling === "true") {
if (isSampling) {
return githubEntries.splice(0, 10);
}
return githubEntries;
Expand Down
19 changes: 0 additions & 19 deletions src/tsv_file_creator.ts

This file was deleted.

0 comments on commit c321741

Please sign in to comment.