@hexlet/cli
Advanced tools
| # Hexlet assignments |
| # Домашние задания | ||
| Работа над домашними заданиями происходит на компьютере студента. | ||
| Для каждого домашнего задания мы подготовили отдельный набор файлов. Обычно в нем содержится: | ||
| * Текст задачи (файл README) | ||
| * Тесты кода | ||
| * Линтер | ||
| * Описание зависимостей | ||
| * Пустой файл, в который студент запишет свое решение | ||
| Все эти файлы хранятся на нашем Gitlab, а утилита *Hexlet CLI* выступает интерфейсом для работы с этой системой. | ||
| ## Команды в утилите Hexlet CLI | ||
| Утилита вызывается по имени *hexlet*, и содержит несколько команд: | ||
| * *assignments init* — создает репозиторий с именем *hexlet-assignments* в профиле студента на Github | ||
| В этот репозиторий будут отправляться все домашние задания, которые вы выполняете на Хекслете, независимо от учебной программы. Для всех учебных программ репозиторий будет один. Имя *hexlet-assignments* для репозитория должно быть свободно. | ||
| Одновременно с созданием репозитория команда *assignments init* совершает еще два действия: | ||
| * Создает конфигурационный файл | ||
| * Создает директорию *Hexlet/hexlet-assignments* в домашней директории на компьютере студента | ||
| * *assignment download* — скачивает домашнее задание | ||
| Эта команда обращается к общей директории *Hexlet/hexlet-assignments* и создает там новые файлы: | ||
| * Поддиректорию с именем курса | ||
| * Поддиректорию с домашним заданием | ||
| Теперь там будет храниться все необходимое для домашнего задания: файлы для решения, текст задачи, тесты, линтер и прочее. | ||
| То же самое можно сделать и без команды: надо зайти на страницу домашней работы, найти ссылку на нужное задание и скачать его. | ||
| * *assignment submit* — отправляет текущее домашнее задание в репозиторий на GitHub | ||
| Выполненное задание нужно отправить на проверку — именно это и делает команда *submit*. | ||
| Она выполняется из локальной директории домашней работы и пушит в ваш удаленный репозиторий все файлы, связанные с текущим заданием. Когда решение студента готово, тесты и линтер локально пройдены, то можно выполнить *submit*. На GitHub также подключены тесты и линтер. | ||
| * *assignment reset* — скачивает новую версию домашнего задания. | ||
| Если уже во время выполнения домашнего задания появляется новая версия упражнения, нужно выполнить *reset*, чтобы повторно скачать ее. | ||
| Команды *assignment download* и *assignment reset* создают резервную копию домашнего задания, над которым идет работа. Если выполнить команду *assignment reset* или *assignment download*, то проделанная работа не потеряется. Старая версия с вашими наработками сохранится в новой директории с текущими датой и временем в названии. | ||
| ### Аргументы | ||
| У команд *assignment download* и *assignment reset* есть аргумент *lesson-url*. Ниже мы покажем, как он используется и где взять нужные значения: | ||
| * *lesson-url* — адрес урока с домашним заданием. Можно взять его из адресной строки урока или скопировать уже готовую команду для скачивания на странице домашнего задания | ||
| ### Опции | ||
| * *--github-token* – *Personal access token* из Gitlab | ||
| * *--hexlet-token* – Ваш персональный токен Хекслета | ||
| ### Использование | ||
| Перед тем, как начать работу с домашним заданием, нужно выполнить инициализацию проекта. Это можно сделать с помощью команды *hexlet assignments init*. У нее есть несколько опций: | ||
| * *--github-token* – Обязательная. *Personal access token* из Gitlab. [Создайте](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) свой Personal access token [здесь](https://github.com/settings/tokens). При создании токена сделайте его бессрочным и проставьте разрешения на *repo* и *workflow* | ||
| * *--hexlet-token* – Обязательная. Ваш персональный токен Хекслета. Этот токен автоматически подставлен в команду на странице домашнего задания | ||
| * *--hexlet-dir* – Необязательная. Директория, в которую будут скачиваться домашние задания. По умолчанию это будет директория Hexlet в вашей домашней директории | ||
| Перейдите на страницу домашней работы, которую нужно скачать. На странице по ссылке «Инициализация утилиты» идентификатор *hexlet-token* уже подставлен в команду для инициализации: | ||
| ```bash | ||
| hexlet assignments init --github-token=<token from github> --hexlet-token=<your hexlet token> | ||
| ``` | ||
| Для инициализации проекта остаётся скопировать команду, вставить свой Personal access token из GitHub и выполнить ее: | ||
| ```bash | ||
| # Можно вызывать из любого каталога | ||
| hexlet assignments init --github-token=<token from github> --hexlet-token=<your hexlet token> | ||
| ``` | ||
| Инициализацию нужно выполнить один раз перед скачиванием первой домашней работы. Если потребуется изменить расположение локальной директории с домашними работами или восстановить настройки и конфиг локального репозитория, инициализацию нужно выполнить повторно. | ||
| Далее можно переходить с выполнению домашней работы. Для команд *assignment download* и *assignment reset* аргументом нужно указать адрес урока с домашним заданием. Адрес урока можно скопировать из адресной строки. Также вы можете взять уже готовую команду на скачивание со страницы домашнего задания: | ||
| ```bash | ||
| # Эта команда скачивает на компьютер домашнее задание с указанным lesson-url | ||
| hexlet assignment download https://ru.hexlet.io/courses/java-collections/lessons/lists/assignment_unit | ||
| ``` | ||
| ```bash | ||
| # Если во время выполнения появилась новая версия | ||
| # Эта команда скачивает новую версию домашнего задания | ||
| # Предыдущую версию и ваши наработки она скопирует в новую директорию | ||
| hexlet assignment reset https://ru.hexlet.io/courses/java-collections/lessons/lists/assignment_unit | ||
| ``` | ||
| Команда *assignment submit* выполняется без аргументов из директории выполненного домашнего задания или любой его поддиректории: | ||
| ```bash | ||
| # Отправляет выполненное домашнее задание на GitHub | ||
| # Выполняются команды git add, commit, push | ||
| hexlet assignment submit | ||
| ``` | ||
| Если вы хотите вспомнить весь список актуальных команд, можно вывести справочную информацию: | ||
| ```bash | ||
| hexlet assignments --help | ||
| ``` | ||
| ```bash | ||
| hexlet assignment --help | ||
| ``` |
+1
-1
@@ -43,3 +43,3 @@ { | ||
| "description": "", | ||
| "version": "2.0.0-6", | ||
| "version": "2.0.0", | ||
| "main": "index.js", | ||
@@ -46,0 +46,0 @@ "scripts": { |
+2
-1
@@ -37,3 +37,3 @@ // @ts-check | ||
| hexletConfigDir, hexletConfigPath, hexletDir, entityName, | ||
| githubToken, hexletToken, projectUrl, | ||
| githubToken, hexletToken, projectUrl, preferredLocale, | ||
| } = options; | ||
@@ -56,2 +56,3 @@ | ||
| hexletDir, | ||
| preferredLocale, | ||
| assignments: { | ||
@@ -58,0 +59,0 @@ githubUrl: projectUrl, |
@@ -28,3 +28,5 @@ // @ts-check | ||
| const { hexletDir, hexletToken } = await readHexletConfig(hexletConfigPath, entityName); | ||
| const { | ||
| hexletDir, hexletToken, preferredLocale, | ||
| } = await readHexletConfig(hexletConfigPath, entityName); | ||
@@ -67,5 +69,5 @@ const repoPath = generateRepoPath(hexletDir); | ||
| await updateTemplates(hexletTemplatesPath, repoPath); | ||
| await updateTemplates(hexletTemplatesPath, repoPath, preferredLocale); | ||
| console.log(chalk.green(`Assignment path: ${assignmentPath}`)); | ||
| }; |
@@ -25,3 +25,3 @@ // @ts-check | ||
| const { | ||
| hexletDir, githubToken, assignments, | ||
| hexletDir, githubToken, assignments, preferredLocale, | ||
| } = await readHexletConfig(hexletConfigPath, entityName); | ||
@@ -45,3 +45,3 @@ | ||
| await updateTemplates(hexletTemplatesPath, repoPath); | ||
| await updateTemplates(hexletTemplatesPath, repoPath, preferredLocale); | ||
| const currentPath = await updateCurrent(repoPath, courseSlugWithLocale, lessonSlug); | ||
@@ -48,0 +48,0 @@ const changesToCommit = await git.hasChangesToCommit({ |
@@ -47,7 +47,15 @@ // @ts-check | ||
| await hexlet.initAssignments({ token: hexletToken, repoUrl: repoData.html_url }); | ||
| const { preferredLocale } = await hexlet.initAssignments({ | ||
| token: hexletToken, | ||
| repoUrl: repoData.html_url, | ||
| }); | ||
| log('prepare and write config'); | ||
| const { hexletDir } = await prepareConfig({ | ||
| ...params, hexletConfigDir, hexletConfigPath, projectUrl: repoData.html_url, entityName, | ||
| ...params, | ||
| hexletConfigDir, | ||
| hexletConfigPath, | ||
| projectUrl: repoData.html_url, | ||
| entityName, | ||
| preferredLocale, | ||
| }); | ||
@@ -83,3 +91,3 @@ | ||
| const templatePaths = await updateTemplates(hexletTemplatesPath, repoPath); | ||
| const templatePaths = await updateTemplates(hexletTemplatesPath, repoPath, preferredLocale); | ||
| const changesToCommit = await git.hasChangesToCommit({ | ||
@@ -86,0 +94,0 @@ dir: repoPath, |
@@ -75,12 +75,2 @@ // @ts-check | ||
| const files = await fsp.readdir(exercisesPath, { withFileTypes: true }); | ||
| const exerciseNames = files | ||
| .filter((file) => file.isDirectory()) | ||
| .map((dir) => dir.name); | ||
| if (_.isEmpty(exerciseNames)) { | ||
| console.log(chalk.gray(`Directory '${exercisesPath}' does not contain exercises. Skip migrating.`)); | ||
| return; | ||
| } | ||
| if (!skipImportGitlab) { | ||
@@ -105,2 +95,3 @@ const api = new Gitlab({ | ||
| const hexletGitlabUrl = new URL(programs[program].gitlabUrl); | ||
| const hexletProjectPath = hexletGitlabUrl.pathname.replace(/^\//, ''); | ||
| hexletGitlabUrl.pathname = `${hexletGitlabUrl.pathname}.git`; | ||
@@ -114,5 +105,23 @@ hexletGitlabUrl.username = 'oauth2'; | ||
| }); | ||
| console.log(chalk.green(`Remote repository exported to: ${project.web_url}`)); | ||
| console.log(chalk.cyan(`Remote repository exported to: ${project.web_url}`)); | ||
| await api.ProtectedBranches.unprotect(hexletProjectPath, programBranch); | ||
| await api.ProtectedBranches.protect(hexletProjectPath, programBranch, { | ||
| push_access_level: 0, | ||
| merge_access_level: 0, | ||
| }); | ||
| console.log(chalk.yellow(`Repository: ${programs[program].gitlabUrl} closed for pushing!`)); | ||
| console.log(); | ||
| } | ||
| const files = await fsp.readdir(exercisesPath, { withFileTypes: true }); | ||
| const exerciseNames = files | ||
| .filter((file) => file.isDirectory()) | ||
| .map((dir) => dir.name); | ||
| if (_.isEmpty(exerciseNames)) { | ||
| console.log(chalk.gray(`Directory '${exercisesPath}' does not contain exercises. Skip migrating.`)); | ||
| return; | ||
| } | ||
| log('copy exercises to assignments', repoPath); | ||
@@ -136,2 +145,3 @@ const copyPromises = exerciseNames | ||
| const assignmentPaths = await Promise.all(copyPromises); | ||
| console.log(chalk.cyan(`Local path to assignments: ${repoPath}`)); | ||
@@ -180,4 +190,3 @@ log('update remote repository', assignments.githubUrl); | ||
| console.log(chalk.green('Changes have been pushed!')); | ||
| console.log(chalk.cyan(`Open ${assignments.githubUrl}`)); | ||
| console.log(chalk.cyan(`Remote repository with assignments ${assignments.githubUrl}`)); | ||
| } else { | ||
@@ -187,5 +196,5 @@ console.log(chalk.grey('Nothing to push. Skip pushing.')); | ||
| console.log(chalk.grey(`Path to assignments: ${repoPath}`)); | ||
| console.log(); | ||
| console.log(chalk.green(`Migration from ${programPath} to ${repoPath} finished!`)); | ||
| console.log(); | ||
| }; |
@@ -56,2 +56,6 @@ // @ts-check | ||
| } | ||
| const { preferred_locale: preferredLocale } = response.data; | ||
| return { preferredLocale }; | ||
| }; | ||
@@ -58,0 +62,0 @@ |
@@ -14,6 +14,6 @@ // @ts-check | ||
| const updateTemplates = async (hexletTemplatesPath, repoPath) => { | ||
| const updateTemplates = async (hexletTemplatesPath, repoPath, preferredLocale) => { | ||
| const templatesPath = path.join(hexletTemplatesPath, 'assignments'); | ||
| const templates = [ | ||
| { fileName: 'README.md', destPath: 'README.md' }, | ||
| { fileName: `README.${preferredLocale}.md`, destPath: 'README.md' }, | ||
| { fileName: 'hexlet-check.yml', destPath: path.join('.github', 'workflows', 'hexlet-check.yml') }, | ||
@@ -20,0 +20,0 @@ ]; |
| # Домашние задания | ||
| Работа над домашними заданиями происходит на компьютере студента. | ||
| Для каждого домашнего задания мы подготовили отдельный набор файлов. Обычно в нем содержится: | ||
| * Текст задачи (файл README) | ||
| * Тесты кода | ||
| * Линтер | ||
| * Описание зависимостей | ||
| * Пустой файл, в который студент запишет свое решение | ||
| Все эти файлы хранятся на нашем Gitlab, а утилита *Hexlet CLI* выступает интерфейсом для работы с этой системой. | ||
| ## Команды в утилите Hexlet CLI | ||
| Утилита вызывается по имени *hexlet*, и содержит несколько команд: | ||
| * *assignments init* — создает репозиторий с именем *hexlet-assignments* в профиле студента на Github | ||
| В этот репозиторий будут отправляться все домашние задания, которые вы выполняете на Хекслете, независимо от учебной программы. Для всех учебных программ репозиторий будет один. Имя *hexlet-assignments* для репозитория должно быть свободно. | ||
| Одновременно с созданием репозитория команда *assignments init* совершает еще два действия: | ||
| * Создает конфигурационный файл | ||
| * Создает директорию *Hexlet/hexlet-assignments* в домашней директории на компьютере студента | ||
| * *assignment download* — скачивает домашнее задание | ||
| Эта команда обращается к общей директории *Hexlet/hexlet-assignments* и создает там новые файлы: | ||
| * Поддиректорию с именем курса | ||
| * Поддиректорию с домашним заданием | ||
| Теперь там будет храниться все необходимое для домашнего задания: файлы для решения, текст задачи, тесты, линтер и прочее. | ||
| То же самое можно сделать и без команды: надо зайти на страницу домашней работы, найти ссылку на нужное задание и скачать его. | ||
| * *assignment submit* — отправляет текущее домашнее задание в репозиторий на GitHub | ||
| Выполненное задание нужно отправить на проверку — именно это и делает команда *submit*. | ||
| Она выполняется из локальной директории домашней работы и пушит в ваш удаленный репозиторий все файлы, связанные с текущим заданием. Когда решение студента готово, тесты и линтер локально пройдены, то можно выполнить *submit*. На GitHub также подключены тесты и линтер. | ||
| * *assignment reset* — скачивает новую версию домашнего задания. | ||
| Если уже во время выполнения домашнего задания появляется новая версия упражнения, нужно выполнить *reset*, чтобы повторно скачать ее. | ||
| Команды *assignment download* и *assignment reset* создают резервную копию домашнего задания, над которым идет работа. Если выполнить команду *assignment reset* или *assignment download*, то проделанная работа не потеряется. Старая версия с вашими наработками сохранится в новой директории с текущими датой и временем в названии. | ||
| ### Аргументы | ||
| У команд *assignment download* и *assignment reset* есть аргумент *lesson-url*. Ниже мы покажем, как он используется и где взять нужные значения: | ||
| * *lesson-url* — адрес урока с домашним заданием. Можно взять его из адресной строки урока или скопировать уже готовую команду для скачивания на странице домашнего задания | ||
| ### Опции | ||
| * *--github-token* – *Personal access token* из Gitlab | ||
| * *--hexlet-token* – Ваш персональный токен Хекслета | ||
| ### Использование | ||
| Перед тем, как начать работу с домашним заданием, нужно выполнить инициализацию проекта. Это можно сделать с помощью команды *hexlet assignments init*. У нее есть несколько опций: | ||
| * *--github-token* – Обязательная. *Personal access token* из Gitlab. [Создайте](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) свой Personal access token [здесь](https://github.com/settings/tokens). При создании токена сделайте его бессрочным и проставьте разрешения на *repo* и *workflow* | ||
| * *--hexlet-token* – Обязательная. Ваш персональный токен Хекслета. Этот токен автоматически подставлен в команду на странице домашнего задания | ||
| * *--hexlet-dir* – Необязательная. Директория, в которую будут скачиваться домашние задания. По умолчанию это будет директория Hexlet в вашей домашней директории | ||
| Перейдите на страницу домашней работы, которую нужно скачать. На странице по ссылке «Инициализация утилиты» идентификатор *hexlet-token* уже подставлен в команду для инициализации: | ||
| ```bash | ||
| hexlet assignments init --github-token=<token from github> --hexlet-token=<your hexlet token> | ||
| ``` | ||
| Для инициализации проекта остаётся скопировать команду, вставить свой Personal access token из GitHub и выполнить ее: | ||
| ```bash | ||
| # Можно вызывать из любого каталога | ||
| hexlet assignments init --github-token=<token from github> --hexlet-token=<your hexlet token> | ||
| ``` | ||
| Инициализацию нужно выполнить один раз перед скачиванием первой домашней работы. Если потребуется изменить расположение локальной директории с домашними работами или восстановить настройки и конфиг локального репозитория, инициализацию нужно выполнить повторно. | ||
| Далее можно переходить с выполнению домашней работы. Для команд *assignment download* и *assignment reset* аргументом нужно указать адрес урока с домашним заданием. Адрес урока можно скопировать из адресной строки. Также вы можете взять уже готовую команду на скачивание со страницы домашнего задания: | ||
| ```bash | ||
| # Эта команда скачивает на компьютер домашнее задание с указанным lesson-url | ||
| hexlet assignment download https://ru.hexlet.io/courses/java-collections/lessons/lists/assignment_unit | ||
| ``` | ||
| ```bash | ||
| # Если во время выполнения появилась новая версия | ||
| # Эта команда скачивает новую версию домашнего задания | ||
| # Предыдущую версию и ваши наработки она скопирует в новую директорию | ||
| hexlet assignment reset https://ru.hexlet.io/courses/java-collections/lessons/lists/assignment_unit | ||
| ``` | ||
| Команда *assignment submit* выполняется без аргументов из директории выполненного домашнего задания или любой его поддиректории: | ||
| ```bash | ||
| # Отправляет выполненное домашнее задание на GitHub | ||
| # Выполняются команды git add, commit, push | ||
| hexlet assignment submit | ||
| ``` | ||
| Если вы хотите вспомнить весь список актуальных команд, можно вывести справочную информацию: | ||
| ```bash | ||
| hexlet assignments --help | ||
| ``` | ||
| ```bash | ||
| hexlet assignment --help | ||
| ``` |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 3 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 3 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
71446
1.07%38
2.7%1569
1.36%0
-100%