Skip to content
Snippets Groups Projects
Commit dfd43830 authored by michael.minelli's avatar michael.minelli
Browse files

Merge branch 'v4.2.0'

parents 7cd5f733 ba77e5ee
No related branches found
No related tags found
No related merge requests found
Pipeline #33492 canceled
Showing
with 467 additions and 203 deletions
......@@ -350,6 +350,6 @@ Sessionx.vim
.netrwhist
*~
# Auto-generated tag files
tags
# tags
# Persistent undo
[._]*.un~
......@@ -3,7 +3,7 @@
url = ../../shared/jetbrains_configuration.git
[submodule "NodeApp/src/shared"]
path = NodeApp/src/shared
url = ../../shared/nodesharedcode.git
url = https://gitedu.hesge.ch/dojo_project/projects/shared/nodesharedcode
[submodule "NodeApp/src/sharedByClients"]
path = NodeApp/src/sharedByClients
url = ../../shared/nodeclientsharedcode.git
url = https://gitedu.hesge.ch/dojo_project/projects/shared/nodeclientsharedcode
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/dojocli.iml" filepath="$PROJECT_DIR$/.idea/dojocli.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -17,6 +17,11 @@
- No modifications / Keep major and minors versions in sync with all parts of the project
-->
## 4.2.0 (Upcoming)
### ✨ Feature
- Add support for tags on assignments and exercises
## 4.1.1 (2024-05-28)
......@@ -27,7 +32,7 @@
## 4.1.0 (2024-05-28)
### ✨ Feature
- Add features related to corrige (commentary, commit specific link / update, delete link)
- Add features related to corrige (commentary, commit a specific link / update, delete link)
### 🎨 Interface
- Ask for confirmation before creating an exercise that already exists
......
......@@ -92,7 +92,7 @@
sed -i -r "s/,[\ \n]*\}/\}/g" src/init.ts
echo "DOTENV_KEY_PRODUCTION=\"${DOTENV_PROD_KEY}\"" > .env.keys
npx @dotenvx/dotenvx decrypt
npx @dotenvx/dotenvx@0.45.0 decrypt
mv .env.production .env
rm .env.keys
fi
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="104e8585:19002424fea:-7ffe" />
</MTProjectMetadataState>
</option>
</component>
</project>
\ No newline at end of file
This diff is collapsed.
{
"name" : "dojo_cli",
"description" : "CLI of the Dojo project",
"version" : "4.1.1",
"version" : "4.2.0",
"license" : "AGPLv3",
"author" : "Michaël Minelli <dojo@minelli.me>",
"author" : "Michaël Minelli <dojo@mail.minelli.swiss>",
"main" : "dist/app.js",
"bin" : {
"dojo": "./dist/app.js"
......@@ -29,12 +29,12 @@
"lint" : "npx eslint .",
"genversion" : "npx genversion -s -e src/config/Version.ts",
"build" : "npm run genversion; npx tsc",
"start:dev" : "npm run genversion; npm run lint; tsc --noEmit && npx tsx src/app.ts",
"start:dev" : "npm run genversion; npm run lint; tsc --noEmit && npx tsx --no-warnings src/app.ts",
"test" : "echo \"Error: no test specified\" && exit 1"
},
"dependencies" : {
"@dotenvx/dotenvx" : "^0.44.1",
"@eslint/js" : "^9.3.0",
"@dotenvx/dotenvx" : "^0.45.0",
"@eslint/js" : "^9.6.0",
"@gitbeaker/core" : "^40.0.3",
"@gitbeaker/requester-utils": "^40.0.3",
"@gitbeaker/rest" : "^40.0.3",
......@@ -42,6 +42,7 @@
"axios" : "^1.7.2",
"boxen" : "^5.1.2",
"chalk" : "^4.1.2",
"cli-table3" : "^0.6.5",
"commander" : "^12.1.0",
"form-data" : "^4.0.0",
"fs-extra" : "^11.2.0",
......@@ -55,7 +56,7 @@
"tar-stream" : "^3.1.7",
"winston" : "^3.13.0",
"winston-transport" : "^4.7.0",
"yaml" : "^2.4.2",
"yaml" : "^2.4.5",
"zod" : "^3.23.8",
"zod-validation-error" : "^3.3.0"
},
......@@ -63,18 +64,19 @@
"@types/fs-extra" : "^11.0.4",
"@types/inquirer" : "^8.2.10",
"@types/jsonwebtoken" : "^8.5.9",
"@types/node" : "^18.19.33",
"@types/node" : "^18.19.39",
"@types/semver" : "^7.5.8",
"@types/tar-stream" : "^3.1.3",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser" : "^7.11.0",
"dotenv-vault" : "^1.26.1",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser" : "^7.15.0",
"dotenv-cli" : "^7.4.2",
"dotenv-vault" : "^1.26.2",
"eslint" : "^8.57.0",
"genversion" : "^3.2.0",
"pkg" : "^5.8.1",
"tiny-typed-emitter" : "^2.1.0",
"tsx" : "^4.11.0",
"typescript" : "^5.4.5",
"typescript-eslint" : "^7.11.0"
"tsx" : "^4.16.2",
"typescript" : "^5.5.3",
"typescript-eslint" : "^7.15.0"
}
}
......@@ -13,6 +13,7 @@ import AuthCommand from './auth/AuthCommand.js';
import SessionCommand from './auth/SessionCommand.js';
import UpgradeCommand from './UpgradeCommand.js';
import TextStyle from '../types/TextStyle.js';
import TagCommand from './tag/TagCommand';
class CommanderApp {
......@@ -118,6 +119,7 @@ ${ TextStyle.CODE(' dojo upgrade ') }`, {
SessionCommand.registerOnCommand(this.program);
AssignmentCommand.registerOnCommand(this.program);
ExerciseCommand.registerOnCommand(this.program);
TagCommand.registerOnCommand(this.program);
CompletionCommand.registerOnCommand(this.program);
UpgradeCommand.registerOnCommand(this.program);
}
......
......@@ -33,9 +33,7 @@ class AssignmentCreateCommand extends CommanderCommand {
private async dataRetrieval(options: CommandOptions) {
console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...'));
if ( !await AccessesHelper.checkTeachingStaff() ) {
throw new Error();
}
await AccessesHelper.checkTeachingStaff();
this.members = await GitlabManager.fetchMembers(options);
if ( !this.members ) {
......
......@@ -2,6 +2,7 @@ import CommanderCommand from '../CommanderCommand.js';
import ExerciseCreateCommand from './subcommands/ExerciseCreateCommand.js';
import ExerciseRunCommand from './subcommands/ExerciseRunCommand.js';
import ExerciseCorrectionCommand from './subcommands/ExerciseCorrectionCommand.js';
import ExerciseDeleteCommand from './subcommands/ExerciseDeleteCommand';
class ExerciseCommand extends CommanderCommand {
......@@ -15,6 +16,7 @@ class ExerciseCommand extends CommanderCommand {
protected defineSubCommands() {
ExerciseCreateCommand.registerOnCommand(this.command);
ExerciseRunCommand.registerOnCommand(this.command);
ExerciseDeleteCommand.registerOnCommand(this.command);
ExerciseCorrectionCommand.registerOnCommand(this.command);
}
......
......@@ -17,8 +17,8 @@ class ExerciseCorrectionCommand extends CommanderCommand {
protected defineCommand() {
this.command
.description('link an exercise repo as a correction for an assignment')
.requiredOption('-a, --assignment <string>', 'id or url of the assignment of the correction')
.description('list corrections of an assignment')
.requiredOption('-a, --assignment <string>', 'id or url of the assignment')
.action(this.commandAction.bind(this));
}
......
......@@ -33,9 +33,7 @@ class ExerciseCreateCommand extends CommanderCommand {
private async dataRetrieval(options: CommandOptions) {
console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...'));
if ( !await AccessesHelper.checkStudent() ) {
throw new Error();
}
await AccessesHelper.checkStudent();
this.members = await GitlabManager.fetchMembers(options);
if ( !this.members ) {
......
import CommanderCommand from '../../CommanderCommand';
import DojoBackendManager from '../../../managers/DojoBackendManager';
import AccessesHelper from '../../../helpers/AccessesHelper';
import TextStyle from '../../../types/TextStyle';
class ExerciseDeleteCommand extends CommanderCommand {
protected commandName: string = 'delete';
protected defineCommand(): void {
this.command
.description('delete an exercise')
.argument('id or url', 'id or url of the exercise')
.action(this.commandAction.bind(this));
}
private async dataRetrieval() {
console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...'));
await AccessesHelper.checkStudent();
}
private async deleteExercise(exerciseIdOrUrl: string) {
console.log(TextStyle.BLOCK('Please wait while we are deleting the exercise...'));
await DojoBackendManager.deleteExercise(exerciseIdOrUrl);
}
protected async commandAction(exerciseIdOrUrl: string): Promise<void> {
try {
await this.dataRetrieval();
await this.deleteExercise(exerciseIdOrUrl);
} catch ( e ) { /* Do nothing */ }
}
}
export default new ExerciseDeleteCommand();
import CommanderCommand from '../CommanderCommand';
import TagCreateCommand from './subcommands/TagCreateCommand';
import TagDelete from './subcommands/TagDeleteCommand';
import TagProposalCommand from './subcommands/proposal/TagProposalCommand';
class TagCommand extends CommanderCommand {
protected commandName: string = 'tag';
protected defineCommand() {
this.command
.description('manage tags');
}
protected defineSubCommands() {
TagCreateCommand.registerOnCommand(this.command);
TagDelete.registerOnCommand(this.command);
TagProposalCommand.registerOnCommand(this.command);
}
protected async commandAction(): Promise<void> {
// No action
}
}
export default new TagCommand();
\ No newline at end of file
import CommanderCommand from '../../CommanderCommand';
import DojoBackendManager from '../../../managers/DojoBackendManager';
import { Option } from 'commander';
import TextStyle from '../../../types/TextStyle';
import SessionManager from '../../../managers/SessionManager';
import ora from 'ora';
type CommandOptions = { name: string, type: 'Language' | 'Framework' | 'Theme' | 'UserDefined' }
class TagCreateCommand extends CommanderCommand {
protected commandName: string = 'create';
protected defineCommand() {
this.command
.description('create a new tag')
.requiredOption('-n, --name <name>', 'name of the tag')
.addOption(new Option('-t, --type <type>', 'type of the tag').choices([ 'Language', 'Framework', 'Theme', 'UserDefined' ]).makeOptionMandatory(true))
.action(this.commandAction.bind(this));
}
private async dataRetrieval(options: CommandOptions) {
console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...'));
const sessionResult = await SessionManager.testSession(true, [ 'admin' ]);
if ( !sessionResult ) {
throw new Error();
}
if ( options.type !== 'UserDefined' && !sessionResult.admin ) {
ora({
text : `Only admins can create non UserDefined tags`,
indent: 4
}).start().fail();
throw new Error();
}
}
private async createTag(options: CommandOptions) {
console.log(TextStyle.BLOCK('Please wait while we are creating the tag...'));
const tag = await DojoBackendManager.createTag(options.name, options.type);
if ( !tag ) {
throw new Error();
}
}
protected async commandAction(options: CommandOptions): Promise<void> {
try {
await this.dataRetrieval(options);
await this.createTag(options);
} catch ( e ) { /* Do nothing */ }
}
}
export default new TagCreateCommand();
\ No newline at end of file
import CommanderCommand from '../../CommanderCommand';
import DojoBackendManager from '../../../managers/DojoBackendManager';
import TextStyle from '../../../types/TextStyle';
import AccessesHelper from '../../../helpers/AccessesHelper';
class TagDeleteCommand extends CommanderCommand {
protected commandName: string = 'delete';
protected defineCommand() {
this.command
.description('Delete a tag')
.argument('<name>', 'name of the tag')
.action(this.commandAction.bind(this));
}
private async dataRetrieval() {
console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...'));
await AccessesHelper.checkAdmin();
}
private async deleteTag(name: string) {
console.log(TextStyle.BLOCK('Please wait while we are deleting the tag...'));
if ( !await DojoBackendManager.deleteTag(name) ) {
throw new Error();
}
}
protected async commandAction(name: string): Promise<void> {
try {
await this.dataRetrieval();
await this.deleteTag(name);
} catch ( e ) { /* Do nothing */ }
}
}
export default new TagDeleteCommand();
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment