Skip to content

Commit

Permalink
feat: if article hasn't been updated don't publish an update
Browse files Browse the repository at this point in the history
This will avoid to update the date of latest update on an article while publishing others

Closes #6
  • Loading branch information
maxime1992 committed Aug 26, 2019
1 parent 1d7a972 commit 88df767
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 19 deletions.
38 changes: 34 additions & 4 deletions src/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ export class Article {
constructor(private articleConfig: ArticleConfig) {}

private updateLocalImageLinks(article: string): string {
let searchImageResult,
localImagesToReplace: ImageToReplace[] = [];
let searchImageResult;
let localImagesToReplace: ImageToReplace[] = [];

// tslint:disable-next-line: no-conditional-assignment
while ((searchImageResult = imagesRe.exec(article))) {
const [image] = searchImageResult;

Expand Down Expand Up @@ -53,7 +54,14 @@ export class Article {
return this.updateLocalImageLinks(article);
}

public publishArticle(token: string): Promise<ArticlePublishedStatus> {
private fetchArticleBodyMarkdown(articleId: number): Promise<string | null> {
return got(`https://dev.to/api/articles/${articleId}`, {
json: true,
method: 'GET',
}).then((x: got.Response<ArticleApi>) => x.body.body_markdown);
}

public async publishArticle(token: string): Promise<ArticlePublishedStatus> {
const body: ArticleApi = {
body_markdown: this.readArticleOnDisk(),
};
Expand All @@ -69,6 +77,27 @@ export class Article {
});
}

let remoteArticleBodyMarkdown: string | null;

try {
remoteArticleBodyMarkdown = await this.fetchArticleBodyMarkdown(this.articleConfig.id);
} catch (error) {
return {
updateStatus: UpdateStatus.ERROR as UpdateStatus.ERROR,
articleId: this.articleConfig.id,
articleTitle: frontMatter.title,
error,
};
}

if (remoteArticleBodyMarkdown && remoteArticleBodyMarkdown.trim() === body.body_markdown.trim()) {
return {
articleId: this.articleConfig.id,
updateStatus: UpdateStatus.ALREADY_UP_TO_DATE as UpdateStatus.ALREADY_UP_TO_DATE,
articleTitle: frontMatter.title,
};
}

return got(`https://dev.to/api/articles/${this.articleConfig.id}`, {
json: true,
method: 'PUT',
Expand All @@ -80,10 +109,11 @@ export class Article {
articleTitle: frontMatter.title,
updateStatus: UpdateStatus.UPDATED as UpdateStatus.UPDATED,
}))
.catch(() => ({
.catch(error => ({
articleId: this.articleConfig.id,
articleTitle: frontMatter.title,
updateStatus: UpdateStatus.ERROR as UpdateStatus.ERROR,
error,
}));
}

Expand Down
12 changes: 8 additions & 4 deletions src/dev-to-git.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ export interface ArticleApi {

export enum UpdateStatus {
UPDATED = 'Updated',
ERROR = 'Error',
// @todo handle that case
ALREADY_UP_TO_DATE = 'AlreadyUpToDate',
ERROR = 'Error',
FAILED_TO_EXTRACT_FRONT_MATTER = 'FailedToExtractFrontMatter',
}

Expand All @@ -35,10 +34,15 @@ export interface ConfigurationOptions {
export type ArticlePublishedStatus = {
articleId: number;
} & (
| {
updateStatus: UpdateStatus.FAILED_TO_EXTRACT_FRONT_MATTER;
}
| {
articleTitle: string;
updateStatus: Exclude<UpdateStatus, UpdateStatus.FAILED_TO_EXTRACT_FRONT_MATTER>;
updateStatus: Exclude<UpdateStatus, UpdateStatus.ERROR | UpdateStatus.FAILED_TO_EXTRACT_FRONT_MATTER>;
}
| {
updateStatus: UpdateStatus.FAILED_TO_EXTRACT_FRONT_MATTER;
articleTitle: string;
updateStatus: UpdateStatus.ERROR;
error: Error;
});
25 changes: 19 additions & 6 deletions src/dev-to-git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ArticlePublishedStatus,
ConfigurationOptions,
Repository,
UpdateStatus,
} from './dev-to-git.interface';
import { formatArticlePublishedStatuses, logBuilder, Logger } from './helpers';

Expand Down Expand Up @@ -60,8 +61,8 @@ export class DevToGit {
}

return {
username: match![1],
name: match![2],
username: match[1],
name: match[2],
};
}

Expand Down Expand Up @@ -120,10 +121,22 @@ export class DevToGit {
const devToGit = new DevToGit();
devToGit
.publishArticles()
.then(formatArticlePublishedStatuses)
.then(statuses => devToGit.logger(statuses))
.catch(err => {
.then(articles => ({ articles, text: formatArticlePublishedStatuses(articles) }))
.then(res => {
devToGit.logger(res.text);

res.articles.forEach(article => {
if (
article.updateStatus === UpdateStatus.ERROR ||
article.updateStatus === UpdateStatus.FAILED_TO_EXTRACT_FRONT_MATTER
) {
// if there's been at least one error, exit and fail
process.exit(1);
}
});
})
.catch(error => {
devToGit.logger(chalk.red(`An error occurred while publishing the articles`));
console.error(err);
console.error(error);
process.exit(1);
});
14 changes: 9 additions & 5 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@ export const formatArticlePublishedStatuses = (articlePublishedStatuses: Article
let text: string = `Article "${articleStatus.articleTitle}" `;

switch (articleStatus.updateStatus) {
case UpdateStatus.ALREADY_UP_TO_DATE:
case UpdateStatus.ALREADY_UP_TO_DATE as UpdateStatus.ALREADY_UP_TO_DATE:
text += `is already up to date`;
break;
case UpdateStatus.ERROR:
text += `encountered an error while updating`;
case UpdateStatus.ERROR as UpdateStatus.ERROR:
text +=
`encountered an error:\n` +
`Error name: "${articleStatus.error.name}"\n` +
`Error message: "${articleStatus.error.message}"\n` +
`Error stack: "${articleStatus.error.stack}"`;
break;
case UpdateStatus.UPDATED:
case UpdateStatus.UPDATED as UpdateStatus.UPDATED:
text += `has been successfully updated`;
break;

default:
throw new UnreachabelCase(articleStatus.updateStatus);
throw new UnreachabelCase(articleStatus);
}

return text;
Expand Down

0 comments on commit 88df767

Please sign in to comment.