Skip to content

Commit 280e283

Browse files
Artem ZahorodniukArtem Zahorodniuk
Artem Zahorodniuk
authored and
Artem Zahorodniuk
committed
change script to support more than 1 git repository
1 parent 33d95b3 commit 280e283

File tree

4 files changed

+55
-20
lines changed

4 files changed

+55
-20
lines changed

apps/frontend/src/pages/project/libs/components/setup-analytics-modal/setup-analytics-modal.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const SetupAnalyticsModal = ({
5757
const apiKey = project.apiKey as string;
5858
const userId = String(authenticatedUser.id);
5959

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

6363
const { control, errors, handleSubmit, handleValueSet } = useAppForm({
@@ -233,8 +233,8 @@ const SetupAnalyticsModal = ({
233233
Prepare the script.
234234
</span>
235235
<p className={styles["list-item-text"]}>
236-
Copy the command below and replace &lt;project-path&gt;
237-
placeholder with your local repository&apos;s path:
236+
Copy the command below and replace &lt;project-path-1&gt;, &lt;project-path-2&gt;, ...
237+
placeholder with your local repositories paths:
238238
</p>
239239
<Input
240240
control={control}

scripts/analytics/src/libs/modules/analytics-cli/base-analytics-cli.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ class BaseAnalyticsCli {
4646

4747
private setupCommands(): void {
4848
this.program
49-
.command("track <apiKey> <userId> <repoPath>")
49+
.command("track <apiKey> <userId> <repoPaths...>")
5050
.description("Start the background job for collecting statistics")
51-
.action(async (apiKey: string, userId: string, repoPath: string) => {
52-
if (!apiKey || !userId || !repoPath) {
51+
.action(async (apiKey: string, userId: string, repoPaths: string[]) => {
52+
if (!apiKey || !userId || !repoPaths) {
5353
this.logger.error("Not all command arguments are provided.");
5454

5555
return;
@@ -80,7 +80,7 @@ class BaseAnalyticsCli {
8080

8181
pm2.start(
8282
{
83-
args: [apiKey, userId, repoPath],
83+
args: [apiKey, userId, ...repoPaths],
8484
autorestart: false,
8585
error: `${project.projectName}-err.log`,
8686
name: project.projectName,

scripts/analytics/src/libs/modules/analytics-cli/init-analytics-cli.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
CRON_SCHEDULE,
1111
} from "./libs/constants/constants.js";
1212

13-
const [apiKey, userId, repoPath] = process.argv.slice(ARGUMENT_START_INDEX) as [
13+
const [apiKey, userId, ...repoPaths] = process.argv.slice(ARGUMENT_START_INDEX) as [
1414
string,
1515
string,
1616
string,
@@ -20,7 +20,7 @@ const analyticsService = new AnalyticsService({
2020
analyticsApi,
2121
apiKey,
2222
gitService,
23-
repoPath,
23+
repoPaths,
2424
userId,
2525
});
2626

scripts/analytics/src/modules/analytics/analytics.service.ts

+46-11
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,37 @@ type Constructor = {
1717
analyticsApi: typeof analyticsApi;
1818
apiKey: string;
1919
gitService: GITService;
20-
repoPath: string;
20+
repoPaths: string[];
2121
userId: string;
2222
};
2323

2424
class AnalyticsService {
2525
private analyticsApi: typeof analyticsApi;
2626
private apiKey: string;
2727
private gitService: GITService;
28-
private repoPath: string;
28+
private repoPaths: string[];
2929
private userId: string;
3030

3131
public constructor({
3232
analyticsApi,
3333
apiKey,
3434
gitService,
35-
repoPath,
35+
repoPaths,
3636
userId,
3737
}: Constructor) {
3838
this.analyticsApi = analyticsApi;
3939
this.apiKey = apiKey;
4040
this.gitService = gitService;
41-
this.repoPath = repoPath;
41+
this.repoPaths = repoPaths;
4242
this.userId = userId;
4343
}
4444

45-
private async collectStatsByRepository(): Promise<
45+
private async collectStatsByRepository(repoPath: string): Promise<
4646
ActivityLogCreateItemRequestDto[]
4747
> {
4848
const stats: ActivityLogCreateItemRequestDto[] = [];
4949
const shortLogResult = await executeCommand(
50-
this.gitService.getShortLogCommand(this.repoPath, "midnight"),
50+
this.gitService.getShortLogCommand(repoPath, "midnight"),
5151
);
5252

5353
const commitItems: CommitStatistics[] = [];
@@ -77,15 +77,20 @@ class AnalyticsService {
7777
return stats;
7878
}
7979

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

8585
public async collectAndSendStats(): Promise<void> {
8686
try {
87-
await this.fetchRepository();
88-
const stats = await this.collectStatsByRepository();
87+
const statsAll = []
88+
for (const repoPath of this.repoPaths) {
89+
await this.fetchRepository(repoPath);
90+
statsAll.push(...await this.collectStatsByRepository(repoPath))
91+
}
92+
93+
const stats = mergeStats(statsAll);
8994

9095
if (
9196
stats[FIRST_ARRAY_INDEX] &&
@@ -116,4 +121,34 @@ class AnalyticsService {
116121
}
117122
}
118123

124+
function mergeStats(statsAll: ActivityLogCreateItemRequestDto[]): ActivityLogCreateItemRequestDto[] {
125+
return mergeByCriteria(statsAll,
126+
(item1, item2) => item1.date === item2.date,
127+
(mergedItem, item) => mergedItem.items = mergeStatsItems([...mergedItem.items, ...item.items])
128+
);
129+
}
130+
131+
function mergeStatsItems(items: CommitStatistics[]): CommitStatistics[] {
132+
return mergeByCriteria(items,
133+
(item1, item2) => item1.authorEmail === item2.authorEmail && item1.authorName === item2.authorName,
134+
(mergedItem, item) => mergedItem.commitsNumber += item.commitsNumber
135+
);
136+
}
137+
138+
function mergeByCriteria<T>(items: T[], compareFn: (item1: T, item2: T) => boolean, mergeFn: (mergedItem: T, item: T) => void): T[] {
139+
const mergedItems: T[] = [];
140+
141+
for (const item of items) {
142+
const mergedItem = mergedItems.find((mergedItem) => compareFn(mergedItem, item));
143+
144+
if (mergedItem) {
145+
mergeFn(mergedItem, item);
146+
} else {
147+
mergedItems.push(item);
148+
}
149+
}
150+
151+
return mergedItems;
152+
}
153+
119154
export { AnalyticsService };

0 commit comments

Comments
 (0)