Skip to content

Commit

Permalink
feat: change script to support more than 1 git repository gf-589 (#590)
Browse files Browse the repository at this point in the history
* feat: script should support more than 1 local git repository gf-589 (#589)

* feat: script should support more than 1 local git repository gf-589 (#589)

- moved helpers into src/libs/helpers
- changed functions to arrow functions
  • Loading branch information
ArtemZag authored Oct 3, 2024
1 parent 33d95b3 commit a7e9082
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const SetupAnalyticsModal = ({
const apiKey = project.apiKey as string;
const userId = String(authenticatedUser.id);

return `npx @git-fit/analytics@latest track ${apiKey} ${userId} <project-path>`;
return `npx @git-fit/analytics@latest track ${apiKey} ${userId} <project-path-1> <project-path-2> ...`;
}, [hasProjectApiKey, hasAuthenticatedUser, project, authenticatedUser]);

const { control, errors, handleSubmit, handleValueSet } = useAppForm({
Expand Down Expand Up @@ -233,8 +233,9 @@ const SetupAnalyticsModal = ({
Prepare the script.
</span>
<p className={styles["list-item-text"]}>
Copy the command below and replace &lt;project-path&gt;
placeholder with your local repository&apos;s path:
Copy the command below and replace &lt;project-path-1&gt;,
&lt;project-path-2&gt;, ... placeholder with your local
repositories paths:
</p>
<Input
control={control}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import pm2 from "pm2";

import { executeCommand } from "~/libs/helpers/helpers.js";
import { type Logger } from "~/libs/modules/logger/logger.js";
import { EMPTY_LENGTH } from "~/modules/analytics/libs/constants/constants.js";
import { type AuthAnalyticsService } from "~/modules/auth-analytics/auth-analytics.js";

type Constructor = {
Expand Down Expand Up @@ -46,10 +47,10 @@ class BaseAnalyticsCli {

private setupCommands(): void {
this.program
.command("track <apiKey> <userId> <repoPath>")
.command("track <apiKey> <userId> <repoPaths...>")
.description("Start the background job for collecting statistics")
.action(async (apiKey: string, userId: string, repoPath: string) => {
if (!apiKey || !userId || !repoPath) {
.action(async (apiKey: string, userId: string, repoPaths: string[]) => {
if (!apiKey || !userId || repoPaths.length === EMPTY_LENGTH) {
this.logger.error("Not all command arguments are provided.");

return;
Expand Down Expand Up @@ -80,7 +81,7 @@ class BaseAnalyticsCli {

pm2.start(
{
args: [apiKey, userId, repoPath],
args: [apiKey, userId, ...repoPaths],
autorestart: false,
error: `${project.projectName}-err.log`,
name: project.projectName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@ import {
CRON_SCHEDULE,
} from "./libs/constants/constants.js";

const [apiKey, userId, repoPath] = process.argv.slice(ARGUMENT_START_INDEX) as [
string,
string,
string,
];
const [apiKey, userId, ...repoPaths] = process.argv.slice(
ARGUMENT_START_INDEX,
) as [string, string, string];

const analyticsService = new AnalyticsService({
analyticsApi,
apiKey,
gitService,
repoPath,
repoPaths,
userId,
});

Expand Down
33 changes: 20 additions & 13 deletions scripts/analytics/src/modules/analytics/analytics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EMPTY_LENGTH,
FIRST_ARRAY_INDEX,
} from "./libs/constants/constants.js";
import { mergeStats } from "./libs/helpers/helpers.js";
import {
type ActivityLogCreateItemRequestDto,
type CommitStatistics,
Expand All @@ -17,37 +18,37 @@ type Constructor = {
analyticsApi: typeof analyticsApi;
apiKey: string;
gitService: GITService;
repoPath: string;
repoPaths: string[];
userId: string;
};

class AnalyticsService {
private analyticsApi: typeof analyticsApi;
private apiKey: string;
private gitService: GITService;
private repoPath: string;
private repoPaths: string[];
private userId: string;

public constructor({
analyticsApi,
apiKey,
gitService,
repoPath,
repoPaths,
userId,
}: Constructor) {
this.analyticsApi = analyticsApi;
this.apiKey = apiKey;
this.gitService = gitService;
this.repoPath = repoPath;
this.repoPaths = repoPaths;
this.userId = userId;
}

private async collectStatsByRepository(): Promise<
ActivityLogCreateItemRequestDto[]
> {
private async collectStatsByRepository(
repoPath: string,
): Promise<ActivityLogCreateItemRequestDto[]> {
const stats: ActivityLogCreateItemRequestDto[] = [];
const shortLogResult = await executeCommand(
this.gitService.getShortLogCommand(this.repoPath, "midnight"),
this.gitService.getShortLogCommand(repoPath, "midnight"),
);

const commitItems: CommitStatistics[] = [];
Expand Down Expand Up @@ -77,15 +78,21 @@ class AnalyticsService {
return stats;
}

private async fetchRepository(): Promise<void> {
await executeCommand(this.gitService.getFetchCommand(this.repoPath));
logger.info(`Fetched latest updates for repo at path: ${this.repoPath}`);
private async fetchRepository(repoPath: string): Promise<void> {
await executeCommand(this.gitService.getFetchCommand(repoPath));
logger.info(`Fetched latest updates for repo at path: ${repoPath}`);
}

public async collectAndSendStats(): Promise<void> {
try {
await this.fetchRepository();
const stats = await this.collectStatsByRepository();
const statsAll = [];

for (const repoPath of this.repoPaths) {
await this.fetchRepository(repoPath);
statsAll.push(...(await this.collectStatsByRepository(repoPath)));
}

const stats = mergeStats(statsAll);

if (
stats[FIRST_ARRAY_INDEX] &&
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { mergeStats } from "./merge-stats/merge-stats.helper.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const mergeArrayItems = <T>(
items: T[],
compareFunction: (item1: T, item2: T) => boolean,
mergeFunction: (mergedItem: T, item: T) => void,
): T[] => {
const mergedItems: T[] = [];

for (const item of items) {
const mergedItem = mergedItems.find((mergedItem) =>
compareFunction(mergedItem, item),
);

if (mergedItem) {
mergeFunction(mergedItem, item);
} else {
mergedItems.push(item);
}
}

return mergedItems;
};

export { mergeArrayItems };
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { type ActivityLogCreateItemRequestDto } from "../../types/types.js";
import { mergeArrayItems } from "../merge-array-items/merge-array-items.helper.js";

const mergeStatsItems = (
items: ActivityLogCreateItemRequestDto["items"],
): ActivityLogCreateItemRequestDto["items"] =>
mergeArrayItems(
items,
(item1, item2) =>
item1.authorEmail === item2.authorEmail &&
item1.authorName === item2.authorName,
(mergedItem, item) => (mergedItem.commitsNumber += item.commitsNumber),
);

export { mergeStatsItems };
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type ActivityLogCreateItemRequestDto } from "../../types/types.js";
import { mergeArrayItems } from "../merge-array-items/merge-array-items.helper.js";
import { mergeStatsItems } from "../merge-stats-items/merge-stats-items.helper.js";

const mergeStats = (
statsAll: ActivityLogCreateItemRequestDto[],
): ActivityLogCreateItemRequestDto[] =>
mergeArrayItems(
statsAll,
(item1, item2) => item1.date === item2.date,
(mergedItem, item) =>
(mergedItem.items = mergeStatsItems([
...mergedItem.items,
...item.items,
])),
);

export { mergeStats };

0 comments on commit a7e9082

Please sign in to comment.