From 7eea30534e08b1fd1b75e6de9f2bb79644f77a60 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 27 Sep 2023 12:11:30 +0200 Subject: [PATCH] Bootstrap Odin track --- .appends/.github/labels.yml | 32 +++++ .gitattributes | 69 ++++++++++ .github/CODEOWNERS | 6 + .github/dependabot.yml | 10 ++ .github/labels.yml | 201 ++++++++++++++++++++++++++++++ .github/workflows/configlet.yml | 15 +++ .github/workflows/sync-labels.yml | 19 +++ .github/workflows/test.yml | 39 ++++++ .gitignore | 4 + CODE_OF_CONDUCT.md | 93 ++++++++++++++ LICENSE | 21 ++++ README.md | 41 ++++++ bin/fetch-configlet | 90 +++++++++++++ bin/fetch-configlet.ps1 | 31 +++++ bin/verify-exercises | 35 ++++++ concepts/.keep | 0 config.json | 30 +++++ docs/ABOUT.md | 14 +++ docs/INSTALLATION.md | 15 +++ docs/LEARNING.md | 13 ++ docs/RESOURCES.md | 13 ++ docs/SNIPPET.txt | 1 + docs/TESTS.md | 15 +++ docs/config.json | 32 +++++ exercises/concept/.keep | 0 exercises/practice/.keep | 0 exercises/shared/.docs/help.md | 21 ++++ exercises/shared/.docs/tests.md | 15 +++ 28 files changed, 875 insertions(+) create mode 100644 .appends/.github/labels.yml create mode 100644 .gitattributes create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/labels.yml create mode 100644 .github/workflows/configlet.yml create mode 100644 .github/workflows/sync-labels.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE create mode 100644 README.md create mode 100755 bin/fetch-configlet create mode 100644 bin/fetch-configlet.ps1 create mode 100755 bin/verify-exercises create mode 100644 concepts/.keep create mode 100644 config.json create mode 100644 docs/ABOUT.md create mode 100644 docs/INSTALLATION.md create mode 100644 docs/LEARNING.md create mode 100644 docs/RESOURCES.md create mode 100644 docs/SNIPPET.txt create mode 100644 docs/TESTS.md create mode 100644 docs/config.json create mode 100644 exercises/concept/.keep create mode 100644 exercises/practice/.keep create mode 100644 exercises/shared/.docs/help.md create mode 100644 exercises/shared/.docs/tests.md diff --git a/.appends/.github/labels.yml b/.appends/.github/labels.yml new file mode 100644 index 0000000..bb722a1 --- /dev/null +++ b/.appends/.github/labels.yml @@ -0,0 +1,32 @@ +# ----------------------------------------------------------------------------------------- # +# These are the repository-specific labels that augment the Exercise-wide labels defined in # +# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # +# ----------------------------------------------------------------------------------------- # + +- name: "duplicate" + description: "" + color: "cccccc" + +- name: "enhancement" + description: "" + color: "84b6eb" + +- name: "invalid" + description: "" + color: "e6e6e6" + +- name: "needs maintainer" + description: "" + color: "fc2929" + +- name: "new track" + description: "" + color: "159818" + +- name: "question" + description: "" + color: "cc317c" + +- name: "wontfix" + description: "" + color: "ffffff" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dc43d72 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,69 @@ +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto + +# Force the following filetypes to have unix eols, so Windows does not break them +*.* text eol=lf + +# Windows forced line-endings +/.idea/* text eol=crlf + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +# +## These files are binary and should be left untouched +# + +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.eot binary +*.woff binary +*.pyc binary +*.pdf binary +*.ez binary +*.bz2 binary +*.swp binary + +*.tgz filter=lfs diff=lfs merge=lfs -text +*.psd filter=lfs diff=lfs merge=lfs -text + +# Force bash scripts to always use lf line endings so that if a repo is accessed +# in Unix via a file share from Windows, the scripts will work. +*.sh text eol=lf + +# Force batch scripts to always use CRLF line endings so that if a repo is accessed +# in Windows via a file share from Linux, the scripts will work. +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..9386b8d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# Code owners +.github/CODEOWNERS @exercism/maintainers-admin + +# Changes to `fetch-configlet` should be made in the `exercism/configlet` repo +bin/fetch-configlet @exercism/maintainers-admin +bin/fetch-configlet.ps1 @exercism/maintainers-admin diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..eb2ead7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 + +updates: + # Keep dependencies for GitHub Actions up-to-date + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' + labels: + - 'x:size/small' diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..a1c6c0e --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,201 @@ +# --------------------------------------------------------------- # +# This is an auto-generated file - Do not manually edit this file # +# --------------------------------------------------------------- # + +# This file is automatically generated by concatenating two files: +# +# 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml +# 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository. +# +# If any of these two files change, a pull request is automatically created containing a re-generated version of this file. +# Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file. +# +# When the pull request has been merged, the GitHub labels will be automatically updated by the "Sync labels" workflow. +# This typically takes 5-10 minutes. + +# --------------------------------------------------------------------- # +# These are the Exercism-wide labels which are shared across all repos. # +# --------------------------------------------------------------------- # + +# The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can contribute to. + +# The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue +- name: "x:action/create" + description: "Work on something from scratch" + color: "ffffff" + +- name: "x:action/fix" + description: "Fix an issue" + color: "ffffff" + +- name: "x:action/improve" + description: "Improve existing functionality/content" + color: "ffffff" + +- name: "x:action/proofread" + description: "Proofread text" + color: "ffffff" + +- name: "x:action/sync" + description: "Sync content with its latest version" + color: "ffffff" + +# The `x:knowledge/` labels describe how much Exercism knowledge is required by the contributor +- name: "x:knowledge/none" + description: "No existing Exercism knowledge required" + color: "ffffff" + +- name: "x:knowledge/elementary" + description: "Little Exercism knowledge required" + color: "ffffff" + +- name: "x:knowledge/intermediate" + description: "Quite a bit of Exercism knowledge required" + color: "ffffff" + +- name: "x:knowledge/advanced" + description: "Comprehensive Exercism knowledge required" + color: "ffffff" + +# The `x:module/` labels indicate what part of Exercism the contributor will be working on +- name: "x:module/analyzer" + description: "Work on Analyzers" + color: "ffffff" + +- name: "x:module/concept" + description: "Work on Concepts" + color: "ffffff" + +- name: "x:module/concept-exercise" + description: "Work on Concept Exercises" + color: "ffffff" + +- name: "x:module/generator" + description: "Work on Exercise generators" + color: "ffffff" + +- name: "x:module/practice-exercise" + description: "Work on Practice Exercises" + color: "ffffff" + +- name: "x:module/representer" + description: "Work on Representers" + color: "ffffff" + +- name: "x:module/test-runner" + description: "Work on Test Runners" + color: "ffffff" + +# The `x:rep/` labels describe the amount of reputation to award +# +# For more information on reputation and how these labels should be used, +# check out https://exercism.org/docs/using/product/reputation +- name: "x:rep/tiny" + description: "Tiny amount of reputation" + color: "ffffff" + +- name: "x:rep/small" + description: "Small amount of reputation" + color: "ffffff" + +- name: "x:rep/medium" + description: "Medium amount of reputation" + color: "ffffff" + +- name: "x:rep/large" + description: "Large amount of reputation" + color: "ffffff" + +- name: "x:rep/massive" + description: "Massive amount of reputation" + color: "ffffff" + +# The `x:size/` labels describe the expected amount of work for a contributor +- name: "x:size/tiny" + description: "Tiny amount of work" + color: "ffffff" + +- name: "x:size/small" + description: "Small amount of work" + color: "ffffff" + +- name: "x:size/medium" + description: "Medium amount of work" + color: "ffffff" + +- name: "x:size/large" + description: "Large amount of work" + color: "ffffff" + +- name: "x:size/massive" + description: "Massive amount of work" + color: "ffffff" + +# The `x:status/` label indicates if there is already someone working on the issue +- name: "x:status/claimed" + description: "Someone is working on this issue" + color: "ffffff" + +# The `x:type/` labels describe what type of work the contributor will be engaged in +- name: "x:type/ci" + description: "Work on Continuous Integration (e.g. GitHub Actions workflows)" + color: "ffffff" + +- name: "x:type/coding" + description: "Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)" + color: "ffffff" + +- name: "x:type/content" + description: "Work on content (e.g. exercises, concepts)" + color: "ffffff" + +- name: "x:type/docker" + description: "Work on Dockerfiles" + color: "ffffff" + +- name: "x:type/docs" + description: "Work on Documentation" + color: "ffffff" + +# This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 +- name: "v3-migration 🤖" + description: "Preparing for Exercism v3" + color: "e99695" + +# This Exercism-wide label can be used to bulk-close issues in preparation for pausing community contributions +- name: "paused" + description: "Work paused until further notice" + color: "e4e669" + +# ----------------------------------------------------------------------------------------- # +# These are the repository-specific labels that augment the Exercise-wide labels defined in # +# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # +# ----------------------------------------------------------------------------------------- # + +- name: "duplicate" + description: "" + color: "cccccc" + +- name: "enhancement" + description: "" + color: "84b6eb" + +- name: "invalid" + description: "" + color: "e6e6e6" + +- name: "needs maintainer" + description: "" + color: "fc2929" + +- name: "new track" + description: "" + color: "159818" + +- name: "question" + description: "" + color: "cc317c" + +- name: "wontfix" + description: "" + color: "ffffff" diff --git a/.github/workflows/configlet.yml b/.github/workflows/configlet.yml new file mode 100644 index 0000000..47eb875 --- /dev/null +++ b/.github/workflows/configlet.yml @@ -0,0 +1,15 @@ +name: Configlet + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + configlet: + uses: exercism/github-actions/.github/workflows/configlet.yml@main diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml new file mode 100644 index 0000000..e7b99e5 --- /dev/null +++ b/.github/workflows/sync-labels.yml @@ -0,0 +1,19 @@ +name: Tools + +on: + push: + branches: + - main + paths: + - .github/labels.yml + - .github/workflows/sync-labels.yml + workflow_dispatch: + schedule: + - cron: 0 0 1 * * # First day of each month + +permissions: + issues: write + +jobs: + sync-labels: + uses: exercism/github-actions/.github/workflows/labels.yml@main diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..67a8ba0 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,39 @@ +# This workflow will do a clean install of the dependencies and run tests across different versions +# +# Replace with the track name +# Replace with an image to run the jobs on +# Replace with a github action to setup tooling on the image +# Replace with a cli command to install the dependencies +# +# Find Github Actions to setup tooling here: +# - https://github.com/actions/?q=setup&type=&language= +# - https://github.com/actions/starter-workflows/tree/main/ci +# - https://github.com/marketplace?type=actions&query=setup +# +# Requires scripts: +# - bin/test + +name: / Test + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + ci: + runs-on: + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Use + uses: + + - name: Install project dependencies + run: + + - name: Verify all exercises + run: bin/verify-exercises diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a513a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.swp +.DS_Store +bin/configlet +bin/configlet.exe diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..df8e367 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,93 @@ +# Code of Conduct + +## Introduction + +Exercism is a platform centered around empathetic conversation. +We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. + +## Seen or experienced something uncomfortable? + +If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. +We will follow up with you as a priority. + +## Enforcement + +We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. +We have banned contributors, mentors and users due to violations. + +After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. +We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. +Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. +We strive to be fair, but will err on the side of protecting the culture of our community. + +Exercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations. + +## The simple version + +- Be empathetic +- Be welcoming +- Be kind +- Be honest +- Be supportive +- Be polite + +## The details + +Exercism should be a safe place for everybody regardless of + +- Gender, gender identity or gender expression +- Sexual orientation +- Disability +- Physical appearance (including but not limited to body size) +- Race +- Age +- Religion +- Anything else you can think of + +As someone who is part of this community, you agree that: + +- We are collectively and individually committed to safety and inclusivity +- We have zero tolerance for abuse, harassment, or discrimination +- We respect people’s boundaries and identities +- We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. + - this includes (but is not limited to) various slurs. +- We avoid using offensive topics as a form of humor + +We actively work towards: + +- Being a safe community +- Cultivating a network of support & encouragement for each other +- Encouraging responsible and varied forms of expression + +We condemn: + +- Stalking, doxxing, or publishing private information +- Violence, threats of violence or violent language +- Anything that compromises people’s safety +- Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature +- The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms +- Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion +- Intimidation or harassment (online or in-person). + Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment +- Inappropriate attention or contact +- Not understanding the differences between constructive criticism and disparagement + +These things are NOT OK. + +Be aware of how your actions affect others. +If it makes someone uncomfortable, stop. + +If you say something that is found offensive, and you are called out on it, try to: + +- Listen without interruption +- Believe what the person is saying & do not attempt to disqualify what they have to say +- Ask for tips / help with avoiding making the offense in the future +- Apologize and ask forgiveness + +## History + +This policy was initially adopted from the Front-end London Slack community and has been modified since. +A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). + +_This policy is a "living" document, and subject to refinement and expansion in the future. +This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ef5d211 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Exercism + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..610446b --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# Exercism Odin Track + +[![configlet](https://github.com/exercism/odin/workflows/configlet/badge.svg)](https://github.com/exercism/odin/actions?query=workflow%3Aconfiglet) [![tests](https://github.com/exercism/odin/workflows/test/badge.svg)](https://github.com/exercism/odin/actions?query=workflow%3Atest) + +Exercism exercises in Odin. + +## Testing + +To test the exercises, run `./bin/test`. +This command will iterate over all exercises and check to see if their exemplar/example implementation passes all the tests. + +### Track linting + +[`configlet`](https://exercism.org/docs/building/configlet) is an Exercism-wide tool for working with tracks. You can download it by running: + +```shell +$ ./bin/fetch-configlet +``` + +Run its [`lint` command](https://exercism.org/docs/building/configlet/lint) to verify if all exercises have all the necessary files and if config files are correct: + +```shell +$ ./bin/configlet lint + +The lint command is under development. +Please re-run this command regularly to see if your track passes the latest linting rules. + +Basic linting finished successfully: +- config.json exists and is valid JSON +- config.json has these valid fields: + language, slug, active, blurb, version, status, online_editor, key_features, tags +- Every concept has the required .md files +- Every concept has a valid links.json file +- Every concept has a valid .meta/config.json file +- Every concept exercise has the required .md files +- Every concept exercise has a valid .meta/config.json file +- Every practice exercise has the required .md files +- Every practice exercise has a valid .meta/config.json file +- Required track docs are present +- Required shared exercise docs are present +``` diff --git a/bin/fetch-configlet b/bin/fetch-configlet new file mode 100755 index 0000000..4800e15 --- /dev/null +++ b/bin/fetch-configlet @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# This file is a copy of the +# https://github.com/exercism/configlet/blob/main/scripts/fetch-configlet file. +# Please submit bugfixes/improvements to the above file to ensure that all tracks benefit from the changes. + +set -eo pipefail + +curlopts=( + --silent + --show-error + --fail + --location + --retry 3 +) + +if [[ -n "${GITHUB_TOKEN}" ]]; then + curlopts+=(--header "authorization: Bearer ${GITHUB_TOKEN}") +fi + +get_download_url() { + local os="$1" + local ext="$2" + local latest='https://api.github.com/repos/exercism/configlet/releases/latest' + local arch + case "$(uname -m)" in + x86_64) arch='x86-64' ;; + *686*) arch='i386' ;; + *386*) arch='i386' ;; + *) arch='x86-64' ;; + esac + local suffix="${os}_${arch}.${ext}" + curl "${curlopts[@]}" --header 'Accept: application/vnd.github.v3+json' "${latest}" | + grep "\"browser_download_url\": \".*/download/.*/configlet.*${suffix}\"$" | + cut -d'"' -f4 +} + +main() { + local output_dir + if [[ -d ./bin ]]; then + output_dir="./bin" + elif [[ $PWD == */bin ]]; then + output_dir="$PWD" + else + echo "Error: no ./bin directory found. This script should be ran from a repo root." >&2 + return 1 + fi + + local os + case "$(uname)" in + Darwin*) os='macos' ;; + Linux*) os='linux' ;; + Windows*) os='windows' ;; + MINGW*) os='windows' ;; + MSYS_NT-*) os='windows' ;; + *) os='linux' ;; + esac + + local ext + case "${os}" in + windows*) ext='zip' ;; + *) ext='tar.gz' ;; + esac + + echo "Fetching configlet..." >&2 + local download_url + download_url="$(get_download_url "${os}" "${ext}")" + local output_path="${output_dir}/latest-configlet.${ext}" + curl "${curlopts[@]}" --output "${output_path}" "${download_url}" + + case "${ext}" in + *zip) unzip "${output_path}" -d "${output_dir}" ;; + *) tar xzf "${output_path}" -C "${output_dir}" ;; + esac + + rm -f "${output_path}" + + local executable_ext + case "${os}" in + windows*) executable_ext='.exe' ;; + *) executable_ext='' ;; + esac + + local configlet_path="${output_dir}/configlet${executable_ext}" + local configlet_version + configlet_version="$(${configlet_path} --version)" + echo "Downloaded configlet ${configlet_version} to ${configlet_path}" +} + +main diff --git a/bin/fetch-configlet.ps1 b/bin/fetch-configlet.ps1 new file mode 100644 index 0000000..ab8f103 --- /dev/null +++ b/bin/fetch-configlet.ps1 @@ -0,0 +1,31 @@ +# This file is a copy of the +# https://github.com/exercism/configlet/blob/main/scripts/fetch-configlet.ps1 file. +# Please submit bugfixes/improvements to the above file to ensure that all tracks +# benefit from the changes. + +$ErrorActionPreference = "Stop" +$ProgressPreference = "SilentlyContinue" + +$requestOpts = @{ + Headers = If ($env:GITHUB_TOKEN) { @{ Authorization = "Bearer ${env:GITHUB_TOKEN}" } } Else { @{ } } + MaximumRetryCount = 3 + RetryIntervalSec = 1 +} + +$arch = If ([Environment]::Is64BitOperatingSystem) { "x86-64" } Else { "i386" } +$fileName = "configlet_.+_windows_$arch.zip" + +Function Get-DownloadUrl { + $latestUrl = "https://api.github.com/repos/exercism/configlet/releases/latest" + Invoke-RestMethod -Uri $latestUrl -PreserveAuthorizationOnRedirect @requestOpts + | Select-Object -ExpandProperty assets + | Where-Object { $_.browser_download_url -match $FileName } + | Select-Object -ExpandProperty browser_download_url +} + +$downloadUrl = Get-DownloadUrl +$outputDirectory = "bin" +$outputFile = Join-Path -Path $outputDirectory -ChildPath $fileName +Invoke-WebRequest -Uri $downloadUrl -OutFile $outputFile @requestOpts +Expand-Archive $outputFile -DestinationPath $outputDirectory -Force +Remove-Item -Path $outputFile diff --git a/bin/verify-exercises b/bin/verify-exercises new file mode 100755 index 0000000..8d31328 --- /dev/null +++ b/bin/verify-exercises @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Synopsis: +# Test the track's exercises. +# +# At a minimum, this file must check if the example/exemplar solution of each +# Practice/Concept Exercise passes the exercise's tests. +# +# To check this, you usually have to (temporarily) replace the exercise's solution files +# with its exemplar/example files. +# +# If your track uses skipped tests, make sure to (temporarily) enable these tests +# before running the tests. +# +# The path to the solution/example/exemplar files can be found in the exercise's +# .meta/config.json file, or possibly inferred from the exercise's directory name. + +# Example: +# ./bin/test + +# Verify the Concept Exercises +for concept_exercise_dir in ./exercises/concept/*/; do + if [ -d $concept_exercise_dir ]; then + echo "Checking $(basename "${concept_exercise_dir}") exercise..." + # TODO: run command to verify that the exemplar solution passes the tests + fi +done + +# Verify the Practice Exercises +for practice_exercise_dir in ./exercises/practice/*/; do + if [ -d $practice_exercise_dir ]; then + echo "Checking $(basename "${practice_exercise_dir}") exercise..." + # TODO: run command to verify that the example solution passes the tests + fi +done diff --git a/concepts/.keep b/concepts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/config.json b/config.json new file mode 100644 index 0000000..8907fff --- /dev/null +++ b/config.json @@ -0,0 +1,30 @@ +{ + "language": "Odin", + "slug": "odin", + "active": false, + "status": { + "concept_exercises": false, + "test_runner": false, + "representer": false, + "analyzer": false + }, + "blurb": "TODO: add blurb", + "version": 3, + "online_editor": { + "indent_style": "space", + "indent_size": 4 + }, + "files": { + "solution": [], + "test": [], + "example": [], + "exemplar": [] + }, + "exercises": { + "concept": [], + "practice": [] + }, + "concepts": [], + "key_features": [], + "tags": [] +} diff --git a/docs/ABOUT.md b/docs/ABOUT.md new file mode 100644 index 0000000..9864ed0 --- /dev/null +++ b/docs/ABOUT.md @@ -0,0 +1,14 @@ +# About + + diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md new file mode 100644 index 0000000..cd6ce85 --- /dev/null +++ b/docs/INSTALLATION.md @@ -0,0 +1,15 @@ +# Installation + + diff --git a/docs/LEARNING.md b/docs/LEARNING.md new file mode 100644 index 0000000..b14434d --- /dev/null +++ b/docs/LEARNING.md @@ -0,0 +1,13 @@ +# Learning + + diff --git a/docs/RESOURCES.md b/docs/RESOURCES.md new file mode 100644 index 0000000..9811f04 --- /dev/null +++ b/docs/RESOURCES.md @@ -0,0 +1,13 @@ +# Resources + + diff --git a/docs/SNIPPET.txt b/docs/SNIPPET.txt new file mode 100644 index 0000000..4b4a4f0 --- /dev/null +++ b/docs/SNIPPET.txt @@ -0,0 +1 @@ +TODO: add snippet diff --git a/docs/TESTS.md b/docs/TESTS.md new file mode 100644 index 0000000..bec9502 --- /dev/null +++ b/docs/TESTS.md @@ -0,0 +1,15 @@ +# Tests + + diff --git a/docs/config.json b/docs/config.json new file mode 100644 index 0000000..964e68b --- /dev/null +++ b/docs/config.json @@ -0,0 +1,32 @@ +{ + "docs": [ + { + "uuid": "ed917837-b09a-429c-836a-69f63e8f0abb", + "slug": "installation", + "path": "docs/INSTALLATION.md", + "title": "Installing Odin locally", + "blurb": "Learn how to install Odin locally to solve Exercism's exercises on your own machine" + }, + { + "uuid": "cf13d739-4769-4e10-adf3-a231a9469efb", + "slug": "learning", + "path": "docs/LEARNING.md", + "title": "How to learn Odin", + "blurb": "An overview of how to get started from scratch with Odin" + }, + { + "uuid": "089f2b69-4056-4ad2-bcb0-97ab9b4444c4", + "slug": "tests", + "path": "docs/TESTS.md", + "title": "Testing on the Odin track", + "blurb": "Learn how to test your Odin exercises on Exercism" + }, + { + "uuid": "a9698853-af57-4498-a56a-739266ef9dc2", + "slug": "resources", + "path": "docs/RESOURCES.md", + "title": "Useful Odin resources", + "blurb": "A collection of useful resources to help you master Odin" + } + ] +} diff --git a/exercises/concept/.keep b/exercises/concept/.keep new file mode 100644 index 0000000..e69de29 diff --git a/exercises/practice/.keep b/exercises/practice/.keep new file mode 100644 index 0000000..e69de29 diff --git a/exercises/shared/.docs/help.md b/exercises/shared/.docs/help.md new file mode 100644 index 0000000..45aa2d6 --- /dev/null +++ b/exercises/shared/.docs/help.md @@ -0,0 +1,21 @@ +# Help + + diff --git a/exercises/shared/.docs/tests.md b/exercises/shared/.docs/tests.md new file mode 100644 index 0000000..1f197bf --- /dev/null +++ b/exercises/shared/.docs/tests.md @@ -0,0 +1,15 @@ +# Tests + +