From d3169837b748ec58dc377b5220ccdf72661bc071 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 20 Oct 2024 10:52:45 +0200 Subject: [PATCH] Simplify add practice exercise (#2312) (#2313) --- .github/ISSUE_TEMPLATE/new_exercise.md | 2 +- README.md | 10 ++-- bin/add-new-exercise.ps1 | 62 --------------------- bin/add-practice-exercise.ps1 | 77 ++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 69 deletions(-) delete mode 100644 bin/add-new-exercise.ps1 create mode 100644 bin/add-practice-exercise.ps1 diff --git a/.github/ISSUE_TEMPLATE/new_exercise.md b/.github/ISSUE_TEMPLATE/new_exercise.md index a67e4b7f90..8b26a39791 100644 --- a/.github/ISSUE_TEMPLATE/new_exercise.md +++ b/.github/ISSUE_TEMPLATE/new_exercise.md @@ -1,6 +1,6 @@ There is a new exercise, [EXERCISE-NAME](https://github.com/exercism/problem-specifications/blob/master/exercises/EXERCISE-NAME/description.md), which data can be found here: https://github.com/exercism/problem-specifications/tree/master/exercises/EXERCISE-NAME -To implement the `EXERCISE-NAME` exercise, first run the `./add-new-exercise EXERCISE-NAME` script that will create and update the files required for the new exercise. After this script has run, it will have done the following: +To implement the `EXERCISE-NAME` exercise, first run the `./add-practice-exercise EXERCISE-NAME` script that will create and update the files required for the new exercise. After this script has run, it will have done the following: - Added a new entry for the exercise to the [config.json](https://github.com/exercism/csharp/blob/master/config.json) file. - Created a default generator in the [generator/Generators/Exercise] directory, which is used to automatically convert the [canonical data](https://github.com/exercism/problem-specifications/blob/master/exercises/EXERCISE-NAME/canonical-data.json) to a test file. For more information on how this works, check the [generators docs](https://github.com/exercism/csharp/blob/master/docs/GENERATORS.md). diff --git a/README.md b/README.md index 5818b6afc0..81e5632829 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,15 @@ Exercism exercises in C# Please see the [contributing guide](https://exercism.org/docs/building) -### Adding a new exercise +### Adding a new practice exercise -To add a new exercise, run the `bin/add-new-exercise.ps1` PowerShell script: +To add a new exercise, run the `bin/add-practice-exercise.ps1` PowerShell script: ```shell -pwsh bin/add-new-exercise.ps1 bob +pwsh bin/add-practice-exercise.ps1 bob ``` -This will create all the necessary files and tests for you. -Then you just need to implement the `Example.cs` file and to check if the generated tests make sense. -Parameters and examples for running the script can be found in the script file. +This will add the exercise's files and output what remains to be done. ## Support diff --git a/bin/add-new-exercise.ps1 b/bin/add-new-exercise.ps1 deleted file mode 100644 index f6a77c248e..0000000000 --- a/bin/add-new-exercise.ps1 +++ /dev/null @@ -1,62 +0,0 @@ -<# -.SYNOPSIS - Add a new exercise. -.DESCRIPTION - Add the files need to add a new exercise. -.PARAMETER Exercise - The slug of the exercise to add. -.PARAMETER Author - The author of the exercise. -.PARAMETER Difficulty - The difficulty of the exercise on a scale from 1 to 10 (optional, default: 1). -.EXAMPLE - The example below will add the "acronym" exercise - PS C:\> ./add-new-exercise.ps1 acronym -#> - -[CmdletBinding(SupportsShouldProcess)] -param ( - [Parameter(Position = 0, Mandatory = $true)][string]$Exercise, - [Parameter(Mandatory = $true)][string]$Author, - [Parameter()][int]$Difficulty = 1 -) - -$PSNativeCommandUseErrorActionPreference = $true - -# Use fetch-configlet and configlet to create the exercise -$extension = if ($IsWindows) { ".exe" } else { "" } -$fetchConfiglet = Join-Path "bin" -ChildPath "fetch-configlet${extension}" -$configlet = Join-Path "bin" -ChildPath "configlet${extension}" -& $fetchConfiglet -& $configlet create --practice-exercise "${Exercise}" --difficulty "${Difficulty}" --author "${Author}" - -# Create project -$exerciseName = (Get-Culture).TextInfo.ToTitleCase($Exercise).Replace("-", "") -$exerciseDir = Join-Path -Path "exercises" -ChildPath "practice" | Join-Path -ChildPath "${Exercise}" -$project = Join-Path -Path "${exerciseDir}" -ChildPath "${ExerciseName}.csproj" -& dotnet new xunit --force -lang "C#" --target-framework-override net8.0 -o "${exerciseDir}" -n "${ExerciseName}" -& dotnet sln (Join-Path "exercises" -ChildPath "Exercises.sln") add "${project}" -& dotnet remove "${project}" package "coverlet.collector" -& dotnet add "${project}" package "Exercism.Tests" --version "0.1.0-beta1" -& dotnet add "${project}" package "xunit.runner.visualstudio" --version "2.4.3" -& dotnet add "${project}" package "xunit" --version "2.4.1" -& dotnet add "${project}" package "Microsoft.NET.Test.Sdk" --version "16.8.3" - -Remove-Item -Path (Join-Path "${exerciseDir}" -ChildPath "UnitTest1.cs") -Remove-Item -Path (Join-Path "${exerciseDir}" -ChildPath "GlobalUsings.cs") -(Get-Content -Path ".editorconfig") -Replace "\[\*\.cs\]", "[${exerciseName}.cs]" | Set-Content -Path (Join-Path "${exerciseDir}" -ChildPath ".editorconfig") - -$generator = Join-Path "generators" -ChildPath "Exercises" | Join-Path -ChildPath "Generators" | Join-Path -ChildPath "${ExerciseName}.cs" -Set-Content -Path "${generator}" -Value @" -using System; - -using Exercism.CSharp.Output; - -namespace Exercism.CSharp.Exercises.Generators; - -internal class ${ExerciseName} : ExerciseGenerator -{ -} -"@ - -& dotnet run --project "generators" --exercise "${Exercise}" diff --git a/bin/add-practice-exercise.ps1 b/bin/add-practice-exercise.ps1 new file mode 100644 index 0000000000..fcfc607cb5 --- /dev/null +++ b/bin/add-practice-exercise.ps1 @@ -0,0 +1,77 @@ +<# +.SYNOPSIS + Add a new exercise. +.DESCRIPTION + Add the files need to add a new exercise. +.PARAMETER Exercise + The slug of the exercise to add. +.PARAMETER Author + The author of the exercise. +.PARAMETER Difficulty + The difficulty of the exercise on a scale from 1 to 10 (optional, default: 1). +.EXAMPLE + The example below will add the "acronym" exercise + PS C:\> ./bin/add-practice-exercise.ps1 acronym +#> + +[CmdletBinding(SupportsShouldProcess)] +param ( + [Parameter(Position = 0, Mandatory = $true)][string]$Exercise, + [Parameter(Mandatory = $true)][string]$Author, + [Parameter()][int]$Difficulty = 1 +) + +$ErrorActionPreference = "Stop" +$PSNativeCommandUseErrorActionPreference = $true + +# Use configlet to create the exercise +& bin/fetch-configlet +& bin/configlet create --practice-exercise $Exercise --difficulty $Difficulty --author $Author + +# Create project +$exerciseName = (Get-Culture).TextInfo.ToTitleCase($Exercise).Replace("-", "") +$exerciseDir = "exercises/practice/${Exercise}" +$project = "${exerciseDir}/${ExerciseName}.csproj" +& dotnet new xunit --force -lang "C#" --target-framework-override net8.0 -o $exerciseDir -n $ExerciseName +& dotnet sln exercises/Exercises.sln add $project + +# Update project packages +& dotnet remove $project package coverlet.collector +& dotnet add $project package Exercism.Tests --version 0.1.0-beta1 +& dotnet add $project package xunit.runner.visualstudio --version 2.4.3 +& dotnet add $project package xunit --version 2.4.1 +& dotnet add $project package Microsoft.NET.Test.Sdk --version 16.8.3 + +# Remove and update files +Remove-Item -Path "${exerciseDir}/UnitTest1.cs" +(Get-Content -Path ".editorconfig") -Replace "\[\*\.cs\]", "[${exerciseName}.cs]" | Set-Content -Path "${exerciseDir}/.editorconfig" + +# Add and run generator (this will update the tests file) +$generator = "generators/Exercises/Generators/${ExerciseName}.cs" +Add-Content -Path $generator -Value @" +using System; + +using Exercism.CSharp.Output; + +namespace Exercism.CSharp.Exercises.Generators; + +internal class ${exerciseName} : ExerciseGenerator +{ +} +"@ +& dotnet run --project generators --exercise $Exercise + +# Output the next steps +$files = Get-Content "exercises/practice/${Exercise}/.meta/config.json" | ConvertFrom-Json | Select-Object -ExpandProperty files +Write-Output @" +Your next steps are: +- Check the test suite in $($files.test | Join-String -Separator ",") + - If the tests need changes, update the '${exerciseName}' class in the '${generator}' file + and then run: 'dotnet run --project generators --exercise ${Exercise}' +- Any test cases you don't implement, mark them in 'exercises/practice/${slug}/.meta/tests.toml' with "include = false" +- Create the example solution in $($files.example | Join-String -Separator ",") +- Verify the example solution passes the tests by running 'bin/verify-exercises ${slug}' +- Create the stub solution in $($files.solution | Join-String -Separator ",") +- Update the 'difficulty' value for the exercise's entry in the 'config.json' file in the repo's root +- Validate CI using 'bin/configlet lint' and 'bin/configlet fmt' +"@