Skip to content

Commit 8c0b70e

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 8c0b70e

File tree

4 files changed

+76
-26
lines changed

4 files changed

+76
-26
lines changed

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

+4-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,9 @@ 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;,
237+
&lt;project-path-2&gt;, ... placeholder with your local
238+
repositories paths:
238239
</p>
239240
<Input
240241
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

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

13-
const [apiKey, userId, repoPath] = process.argv.slice(ARGUMENT_START_INDEX) as [
14-
string,
15-
string,
16-
string,
17-
];
13+
const [apiKey, userId, ...repoPaths] = process.argv.slice(
14+
ARGUMENT_START_INDEX,
15+
) as [string, string, string];
1816

1917
const analyticsService = new AnalyticsService({
2018
analyticsApi,
2119
apiKey,
2220
gitService,
23-
repoPath,
21+
repoPaths,
2422
userId,
2523
});
2624

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

+64-13
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<
46-
ActivityLogCreateItemRequestDto[]
47-
> {
45+
private async collectStatsByRepository(
46+
repoPath: string,
47+
): Promise<ActivityLogCreateItemRequestDto[]> {
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,50 @@ class AnalyticsService {
116121
}
117122
}
118123

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

0 commit comments

Comments
 (0)