diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2140a37 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index a2bc0aa..a1108f5 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,48 @@ CodeKiller777 ## Автор решения +Журавлев Константин Анатольевич + ## Описание реализации +Этот проект представляет собой Java приложение для анализа активности пользователей по количеству коммитов. + +Он включает следующие компоненты: +- Класс `FileManager` для работы с файлами: чтения данных о коммитах из файла и записи результата в файл. +- Класс `CommitValidator` для проверки данных на валидность. +- Класс `ActivityAnalyzer` для поиска трех пользователей с наибольшим количеством коммитов. + +Статический метод `FileWorker.read` построчно считывает данные о коммитах из текстового файла `commits.txt`. Строка проходит валидацию `CommitValidator.isValidCommitInfo`: если она валидна, то происходит обработка коммита, иначе - строка пропускается, а в консоль выводится сообщение о некорректности строки. Далее, для анализа активности пользователей вызывается метод `ActivityAnalyzer.findTopThreeUsersWithMostCommits`, который анализирует данные о коммитах и определяет три пользователя с наибольшим количеством коммитов. После этого полученные результаты записываются в файл `result.txt` с помощью статического метода `FileWorker.write`. + ## Инструкция по сборке и запуску решения +Это приложение использует систему сборки Maven для управления зависимостями и сборки проекта. + +### Предварительные требования + +Перед запуском проекта убедитесь, что у вас установлены следующие компоненты: + +- Java Development Kit (JDK) +- Maven + +### Как запустить проект + +1. **Клонирование репозитория** + + Клонируйте репозиторий на ваш локальный компьютер: + + ```bash + git clone https://github.com/constZhur/croc-test-task.git + +2. **Сборка** + + Выполните сборку проекта с помощью Maven: + + ```bash + mvn clean package + +3. **Запуск** + + После успешной сборки, запустите приложение: + + ```bash + java -jar target/croc-test-task-1.0-SNAPSHOT.jar diff --git a/commits.txt b/commits.txt new file mode 100644 index 0000000..dbc31d6 --- /dev/null +++ b/commits.txt @@ -0,0 +1,59 @@ +AIvanov 25ec001 2024-04-24T13:56:39.492 +AIvanov 1a3b5c7 2024-04-25T08:12:20.123 +constZhur 9f8e7d6 2024-04-26T17:30:45.678 +MikhailStatsenko 0f0e0d0 2024-04-27T10:45:55.321 +wenos 8765432 2024-04-28T15:20:10.987 +FWilson 2468101 2024-04-29T09:55:30.654 +constZhur abcdef0 2024-04-30T20:40:45.789 +AIvanov 9999999 2024-05-01T11:11:11.111 +constZhur qwertyu 2024-05-02T12:34:56.789 +wenos asdfghj 2024-05-03T18:00:00.000 +MMartin zxcvbnm 2024-05-04T07:30:15.975 +MikhailStatsenko 7777777 2024-05-05T22:45:30.864 +AIvanov abcd123 2024-05-06T14:00:01.234 +PParker 9876543 2024-05-07T19:15:45.321 +MikhailStatsenko 6543210 2024-05-08T08:30:30.654 +RRichardson 8888 2024-05-09T16:45:15.987 +AIvanov 5555555 2024-05-10T05:55:55.555 +wenos 4444444 2024-05-11T11:11:11.111 +constZhur 3333333 2024-05-12T17:17:17.777 +VRobinson 2222222 2024-05-13T22:22:22.222 +WAllen 1111111 2024-05-14T03:33:33.333 +wenos 0000000 2024-05-15T09:45:45.456 +constZhur qazwsx1 2024-05-16T18:18:18.181 +constZhur 1122334 2024-05-17T21:21:21.212 +wenos 3344556 2024-05-18T08:08:08.808 +BBWright 778899011 2024-05-19T19:19:19.199 +CCarter 1122334 2024-05-20T12:12:12.121 +constZhur 5566778 2024-05-21T15:15:15.151 +EEvans 9900112 2024-05-22T06:06:06.060 +constZhur 2244668 2024-05-23T23:23:23.232 +GGonzalez 8800111 2024-05-24T07:07:07.070 +MikhailStatsenko 6677222 2024-05-25T17:17:17.171 +constZhur 4455888 2024-05-26T19:19:19.191 +constZhur 3322110 2024-05-27T10:10:10.101 +MikhailStatsenko 5577889 2024-05-28T12:12:12.121 +LLee 8899553 2024-05-29T23:23:23.232 +MikhailStatsenko 3322665 2024-05-30T14:14:14.141 +NNelson 5511447 2024-05-31T16:16:16.161 +MikhailStatsenko 7766223 2024-06-01T06:06:06.060 +wenos 1144776 2024-06-02T07:07:07.070 +_QPhillips 7788990 2024-06-03T18:18:18.181 +wenos 1122334 2024-06-04T09:09:09.090 +MikhailStatsenko 3344556 2024-06-05T20:20:20.202 +MikhailStatsenko 7788990 2024-06-06T03:03:03.030 +wenos 1122334 2024-06-10T18:18:18.181 +YYoung 3344556 2024-06-11T09:09:09.090 aaaa +wenos 7788990 2024-06-12T20:20:20.202 +AIvanov 25ec001 2024-04-24T13:56:39.492 +MikhailStatsenko 1a3b5c7 2024-04-25T08:12:20.123 +constZhur 9f8e7d6 2024-04-26T17:30:45.678 +MikhailStatsenko 0f0e0d0 2024-04-27T10:45:55.321 +1EJones 8765432 2024-04-28T15:20:10.987 +FWilson 2468101 2024-04-29T09:55:30 +GHernandez abcdef0 2024-04-30T20:40:45.789 +MikhailStatsenko qwertyu 2024-05-02T12:34:56.789 +wenos asdfghj 2024-05-03T18:00:00.000 +constZhur zxcvbnm 2024-05-04T07:30:15.975 +wenos abcd123 2024-05-06T14:00:01.234 +MikhailStatsenko qazwsx1 2024-05-16T18:18:18.181 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e3178db --- /dev/null +++ b/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + ru.croc + croc-test-task + 1.0 + + + 1.8 + 1.8 + UTF-8 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + src/main/resources/manifest.mf + + + + + + + \ No newline at end of file diff --git a/result.txt b/result.txt new file mode 100644 index 0000000..94a1b5d --- /dev/null +++ b/result.txt @@ -0,0 +1,3 @@ +MikhailStatsenko +constZhur +wenos diff --git a/src/main/java/ru/croc/ActivityAnalyzer.java b/src/main/java/ru/croc/ActivityAnalyzer.java new file mode 100644 index 0000000..aa607fa --- /dev/null +++ b/src/main/java/ru/croc/ActivityAnalyzer.java @@ -0,0 +1,35 @@ +package ru.croc; + +import java.util.*; + +/** + * Класс для анализа активности пользователей по количеству коммитов. + */ +public class ActivityAnalyzer { + + /** + * Находит три пользователя с наибольшим количеством коммитов. + * + * @param commitCounts Словарь, ключ: имя пользователя, значение: количество их коммитов. + * @return Список имен трех пользователей с наибольшим количеством коммитов, в порядке убывания. + */ + public static List findTopThreeUsersWithMostCommits(Map commitCounts) { + List users = new ArrayList<>(); + + // Создаем копию Map для сортировки по значению (количеству коммитов) + Map sortedMap = new LinkedHashMap<>(); + commitCounts.entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .forEachOrdered(entry -> sortedMap.put(entry.getKey(), entry.getValue())); + + // Выбираем первые три записи (пользователей с наибольшим количеством коммитов) + int count = 0; + for (String user : sortedMap.keySet()) { + users.add(user); + count++; + if (count == 3) break; + } + + return users; + } +} diff --git a/src/main/java/ru/croc/CommitValidator.java b/src/main/java/ru/croc/CommitValidator.java new file mode 100644 index 0000000..648dd40 --- /dev/null +++ b/src/main/java/ru/croc/CommitValidator.java @@ -0,0 +1,65 @@ +package ru.croc; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Класс для валидации данных о коммитах. + */ +public class CommitValidator { + // Регулярные выражения для проверки формата имени, хэша и даты + private static final String USERNAME_REGEX = "^[a-zA-Z_][a-zA-Z0-9_]*$"; + private static final String COMMIT_HASH_REGEX = "^[a-zA-Z0-9]{7}$"; + private static final String DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?$"; + + // Шаблоны для компиляции регулярных выражений + private static final Pattern USERNAME_PATTERN = Pattern.compile(USERNAME_REGEX); + private static final Pattern COMMIT_HASH_PATTERN = Pattern.compile(COMMIT_HASH_REGEX); + private static final Pattern DATE_PATTERN = Pattern.compile(DATE_REGEX); + + /** + * Проверяет валидность имени пользователя. + * + * @param username Имя пользователя для проверки. + * @return true, если имя пользователя валидно, иначе false. + */ + private static boolean isValidUsername(String username) { + Matcher matcher = USERNAME_PATTERN.matcher(username); + return matcher.matches(); + } + + /** + * Проверяет валидность хэша коммита. + * + * @param commitHash Хэш коммита для проверки. + * @return true, если хэш коммита валиден, иначе false. + */ + private static boolean isValidCommitHash(String commitHash) { + Matcher matcher = COMMIT_HASH_PATTERN.matcher(commitHash); + return matcher.matches(); + } + + /** + * Проверяет валидность формата даты. + * + * @param date Дата для проверки. + * @return true, если формат даты валиден, иначе false. + */ + private static boolean isValidDate(String date) { + Matcher matcher = DATE_PATTERN.matcher(date); + return matcher.matches(); + } + + /** + * Проверяет валидность строки данных о коммите. + * + * @param username Имя пользователя. + * @param commitHash Хэш коммита. + * @param date Дата коммита. + * @return true, если данные о коммите валидны, иначе false. + */ + public static boolean isValidCommitInfo(String username, String commitHash, String date) { + return isValidUsername(username) && isValidCommitHash(commitHash) + && isValidDate(date); + } +} diff --git a/src/main/java/ru/croc/FileManager.java b/src/main/java/ru/croc/FileManager.java new file mode 100644 index 0000000..6aead6e --- /dev/null +++ b/src/main/java/ru/croc/FileManager.java @@ -0,0 +1,59 @@ +package ru.croc; + +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static ru.croc.CommitValidator.*; + +/** + * Класс для работы с файлами + */ +public class FileManager { + + /** + * Считывает данные о коммитах из файла и подсчитывает количество коммитов для каждого пользователя. + * + * @return Словарь, ключ: имя пользователя, значение: количество их коммитов. + */ + public static Map read() { + String path = "commits.txt"; + + Map commitCounts = new HashMap<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(path))) { + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split(" "); + if (parts.length == 3 && isValidCommitInfo(parts[0], parts[1], parts[2])) { + commitCounts.put(parts[0], commitCounts.getOrDefault(parts[0], 0) + 1); + } else { + System.out.println("Некорректный формат строки: " + line); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return commitCounts; + } + + /** + * Записывает список пользователей в файл. + * + * @param users Список пользователей для записи. + */ + public static void write(List users) { + String path = "result.txt"; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) { + // Записываем каждого пользователя на отдельной строке + for (String user : users) { + writer.write(user); + writer.newLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/ru/croc/Main.java b/src/main/java/ru/croc/Main.java new file mode 100644 index 0000000..a6bdd94 --- /dev/null +++ b/src/main/java/ru/croc/Main.java @@ -0,0 +1,12 @@ +package ru.croc; + +import java.util.List; +import java.util.Map; + +public class Main { + public static void main(String[] args) { + Map commitCounts = FileManager.read(); + List topThreeUsers = ActivityAnalyzer.findTopThreeUsersWithMostCommits(commitCounts); + FileManager.write(topThreeUsers); + } +} \ No newline at end of file diff --git a/src/main/resources/manifest.mf b/src/main/resources/manifest.mf new file mode 100644 index 0000000..44ff575 --- /dev/null +++ b/src/main/resources/manifest.mf @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Main-Class: ru.croc.Main