diff --git a/.github/problem-matchers/check-directory-tree.json b/.github/problem-matchers/check-directory-tree.json new file mode 100644 index 0000000000..2944b5f7e6 --- /dev/null +++ b/.github/problem-matchers/check-directory-tree.json @@ -0,0 +1,15 @@ +{ + "problemMatcher": [ + { + "owner": "check-directory-tree", + "pattern": [ + { + "regexp": "^(.+?) (.+?) (.*)", + "file": 1, + "code": 2, + "message": 3 + } + ] + } + ] +} diff --git a/.github/problem-matchers/editor-config.json b/.github/problem-matchers/editor-config.json new file mode 100644 index 0000000000..4e717d9783 --- /dev/null +++ b/.github/problem-matchers/editor-config.json @@ -0,0 +1,20 @@ +{ + "problemMatcher": [ + { + "owner": "editor-config", + "pattern": [ + { + "regexp": "^([^\\\\s].*)$", + "file": 1 + }, + { + "regexp": "^\\s+(\\d+):(\\d+)\\s(.+)$", + "line": 1, + "column": 2, + "message": 3, + "loop": true + } + ] + } + ] +} diff --git a/.github/problem-matchers/yaspeller.json b/.github/problem-matchers/yaspeller.json new file mode 100644 index 0000000000..d12f4078c6 --- /dev/null +++ b/.github/problem-matchers/yaspeller.json @@ -0,0 +1,20 @@ +{ + "problemMatcher": [ + { + "owner": "yaspeller", + "pattern": [ + { + "regexp": "^✗\\s(.*)\\s\\d+\\sms$", + "file": 1 + }, + { + "regexp": "^\\d+\\. (.+) \\((\\d+):(\\d+).*$", + "message": 1, + "line": 2, + "column": 3, + "loop": true + } + ] + } + ] +} diff --git a/.github/workflows/book-check-text.yml b/.github/workflows/book-check-text.yml new file mode 100644 index 0000000000..2556379598 --- /dev/null +++ b/.github/workflows/book-check-text.yml @@ -0,0 +1,43 @@ +name: book-check-text + +# Only run this when the master branch changes +on: + workflow_dispatch: + pull_request: + +# This job installs dependencies, build the book, and pushes it to `gh-pages` +jobs: + yaspeller: + name: Spell check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Spell check + # problem matching breaks loop when it finds unrelated data, so we use reverse grep to clear output + run: | + echo "::add-matcher::.github/problem-matchers/yaspeller.json" + set -o pipefail; npx yaspeller -c .yaspellerrc.json . 2>&1 >/dev/null | grep -v "\-\-\-\-\-" | grep -v "Typos" + echo "::remove-matcher owner=yaspeller::" + + editor-config: + name: Editor Config check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Editor Config Check + # problem matching breaks loop when it finds unrelated data, so we use reverse grep to clear output + run: | + echo "::add-matcher::.github/problem-matchers/editor-config.json" + set -o pipefail; npx eclint check "**/*.md" 2>&1 >/dev/null | grep -v "EditorConfig" + echo "::remove-matcher owner=editor-config::" + + direcyory-tree: + name: Directory tree check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Directory tree check + run: | + echo "::add-matcher::.github/problem-matchers/check-directory-tree.json" + bash ./tools/check_directory_tree.sh qmlcourseRU + echo "::remove-matcher owner=check-directory-tree::" diff --git a/.yaspellerrc.json b/.yaspellerrc.json new file mode 100644 index 0000000000..05e357476f --- /dev/null +++ b/.yaspellerrc.json @@ -0,0 +1,195 @@ +{ + "lang": "ru", + "fileExtensions": [ + ".md" + ], + "excludeFiles": [ + ".git", + "node_modules" + ], + "ignoreUppercase": true, + "ignoreUrls": true, + "ignoreCapitalization": true, + "checkYo": true, + "ignoreText": [ + ["– .*\\]", "g"], + ["следующие люди:.*", "g"] + ], + "dictionary": [ + ".*логин.*", + "bootcamp", + "HR.*", + "Jira", + "onboarding", + "playbook", + "Podlodka", + "Rx", + "Spotify", + "teamlead.*", + "vs", + "Авито", + "автотест.*", + "айти", + "айтишник.*", + "Ана", + "антипаттерн.*", + "апдейт.*", + "апрув.*", + "ассессмент", + "аутичн.*", + "аутсорса.*", + "баг.*", + "билд.*", + "бланшар", + "Бреслав.*", + "брейншторм.*", + "Булдаков.*", + "буллет.*", + "буллшит.*", + "бытовух.*", + "бэкграунд.*", + "бэкенд.*", + "бэклог.*", + "валидирова.*", + "версионируется", + "Версионность", + "виральн.*", + "воркшоп.*", + "волонтерств.*", + "гайд.*", + "Гандапас", + "геймификаци.*", + "главред.*", + "груминг.*", + "Далио", + "дейли.*", + "Дельгядо", + "ДеМарко", + "Деминг.*", + "демотиваци.*", + "демотивирует.*", + "демотивирующ.*", + "джедайские.*", + "джефф", + "дэшборд.*", + "заассайнь.*", + "замылен.*", + "Ильяхов.*", + "инбокс.*", + "инновационн.*", + "интранет.*", + "Кейнер", + "Кови", + "коммит.*", + "коммитим.*", + "коммуницирова.*", + "конфиг.*", + "корпоративщин.*", + "корутин.*", + "кроссфункциональн.*", + "Ласло", + "легаси", + "лендинг.*", + "Ленсиони", + "логир.*", + "лонгрид.*", + "майндмеп.*", + "Мавричева", + "Макафи", + "МакГрегор.*", + "МакКлелланда", + "мейнтейнер.*", + "мелкофикс.*", + "мем.*", + "мерж.*", + "мидл.*", + "микросервис.*", + "митап.*", + "монитор.*", + "мыслетопливо.*", + "найм.*", + "напоминалк.*", + "незадокументированн.*", + "неповторени.*", + "неоптимально", + "несистемно", + "нетворкинг.*", + "онбординг.*", + "опенсорс.*", + "операционк.*", + "отрефактори.*", + "оффер", + "переговорк.*", + "переиспользуем.*", + "перформит.*", + "премиальн.*", + "присваем.*", + "провалидируй.*", + "продакт.*", + "промо.*", + "профстандарт", + "ревью.*", + "рекрутер.*", + "репутационные.*", + "ретроспектив.*", + "рефакторинг.*", + "референс.*", + "рефлекси.*", + "роадмап.*", + "Рэй", + "рэнди", + "скилл.*", + "скрайбинг.*", + "скоммуницир.*", + "скоммуницируй", + "скоуп.*", + "скринкаст.*", + "смарт", + "собеседуем.*", + "созвон.*", + "стейкхолд.*", + "стендап.*", + "стиралк.*", + "сторипойнт.*", + "стрессует", + "стриминг.*", + "тайминг.*", + "телеграм.*", + "техбренд.*", + "техлид.*", + "технобренд.*", + "техпиар.*", + "техрук.*", + "тикет.*", + "тимлид.*", + "токен.*", + "туториал.*", + "шторминг.*", + "фасилитатор.*", + "фасилитац.*", + "фейсбук.*", + "феррацци", + "фидбек", + "фич.*", + "флипчарт.*", + "фреймворк.*", + "фронтенд.*", + "Феншуй.*", + "хакатон.*", + "Хофф", + "Херси", + "холакрат.*", + "хотелок", + "чартрайтинг.*", + "чиксентмихайи", + "шорткаты", + "Шухарт.*", + "Ферацци", + "кликабельн.*", + "человекочитаем.+", + "локал.", + "запуш.{1,3}", + "мультиязычност.", + "контрибьютор.{0,2}" + ] + } diff --git a/tools/check_directory_tree.sh b/tools/check_directory_tree.sh new file mode 100644 index 0000000000..85670d5234 --- /dev/null +++ b/tools/check_directory_tree.sh @@ -0,0 +1,55 @@ +HAS_ERROR=0 + +check_file() { + local filepath=$1 + local has_frontmatter_title=0 + local has_ending=0 + local has_beginning=0 + + # [[ ! $filepath =~ ^(\.?[A-Za-z0-9-]+\/)+(ru|index|en)\.md$ ]] \ + # && echo "$filepath bad_branch_name Check a directory tree, branch should be named only with lowercase letters (a-z), numbers (0-9) and hyphens (-), file should be named as %locale%.md (ru.md, e.g.)" \ + # && HAS_ERROR=1 + + if grep -q -E '^# .+$' "$filepath"; then + # has a markdown first level header in file + return + fi + + # iterate line by line + + while IFS="" read -r line || [ -n "$line" ] + do + if [ "$line" = '---' ] && [ "$has_beginning" = 0 ]; then + has_beginning=1 + continue + fi + if [ "$line" = '---' ] && [ "$has_beginning" = 1 ]; then + has_ending=1 + break + fi + # check that line has title frontmatter param + if [[ $line =~ ^title:.+$ ]]; then + has_frontmatter_title=1 + fi + done < "$filepath" + + + if [ "$has_ending" = 0 ]; then + echo "$filepath open_frontmatter_block Check the .md file, you have open frontmatter block (end it with '---')" + HAS_ERROR=1 + return + fi + + if [ "$has_frontmatter_title" = 0 ]; then + echo "$filepath without_title Check the .md file, it should have frontmatter block with title param or markdown first level header" + HAS_ERROR=1 + fi +} + +IFS=$'\n'; set -f +for filepath in $(find "$1" -iname '*.md'); do + check_file "$filepath" +done +unset IFS; set +f + +exit $HAS_ERROR