commit 48a4d2f1c8b2bc4733e6e137b82fa3bc48a150fa Author: earnest ma Date: Mon Nov 23 13:55:29 2020 -0500 Initial commit diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..6760537 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,35 @@ +skip_commits: + files: + - '**/*.md' + - '.vscode/**/*' +cache: + - '%USERPROFILE%\Documents\WindowsPowerShell\Modules -> .appveyor.yml' +matrix: + fast_finish: true +build: 'off' +image: Visual Studio 2019 +environment: + SCOOP: C:\projects\scoop + SCOOP_HOME: C:\projects\scoop\apps\scoop\current + matrix: + - PowerShell: 5 + - PowerShell: 7 +init: + - ps: | + (Get-PSProvider 'FileSystem').Home = 'C:\projects\' + if(!(Test-Path "$env:SCOOP_HOME")) { git clone -q --depth=1 "https://github.com/lukesampson/scoop" "$env:SCOOP_HOME" } +for: + - matrix: + only: + - PowerShell: 5 + install: + - ps: . "$env:SCOOP_HOME\test\bin\init.ps1" + test_script: + - ps: . "$env:SCOOP_HOME\test\bin\test.ps1" -TestPath "$env:APPVEYOR_BUILD_FOLDER" + - matrix: + only: + - PowerShell: 7 + install: + - pwsh: . "$env:SCOOP_HOME\test\bin\init.ps1" + test_script: + - pwsh: . "$env:SCOOP_HOME\test\bin\test.ps1" -TestPath "$env:APPVEYOR_BUILD_FOLDER" diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..87b367d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[.git/hooks/*] +end_of_line = lf + +[*.{yml,yaml}] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9627397 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# retain windows line-endings in case checked out on mac or linux +* text eol=crlf +.git/hooks/* text eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..0f2c7cd --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Ash258 diff --git a/.github/ISSUE_TEMPLATE/hash_check_fail.md b/.github/ISSUE_TEMPLATE/hash_check_fail.md new file mode 100644 index 0000000..d4bb4b8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/hash_check_fail.md @@ -0,0 +1,12 @@ +--- +name: Hash check fail +about: Installation failed due to hash check. +title: '%%manifest%%@%%version%%: Hash check failed' +--- + + + + +```powershell + +``` diff --git a/.github/ISSUE_TEMPLATE/manifest_request.md b/.github/ISSUE_TEMPLATE/manifest_request.md new file mode 100644 index 0000000..44d2cd0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/manifest_request.md @@ -0,0 +1,18 @@ +--- +name: New manifest request +about: Request new manifest to be added into this bucket. +title: '[Request] Add %%applicationName%%' +labels: request, help wanted +--- + + + +- **URL to application**: <> +- **Latest version**: +- **Graphical interface**: Yes/No +- **Portable version**: Yes/No + + + + + diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml new file mode 100644 index 0000000..b6a883e --- /dev/null +++ b/.github/workflows/issue.yml @@ -0,0 +1,16 @@ +on: + issues: + types: [ opened, labeled ] +name: Issues +jobs: + issueHandler: + runs-on: ubuntu-latest + name: Issue Verification + steps: + - uses: actions/checkout@main + - name: Verify Issue + uses: Ash258/Scoop-GithubActions@stable + if: github.event.action == 'opened' || (github.event.action == 'labeled' && contains(github.event.issue.labels.*.name, 'verify')) + env: + GITH_EMAIL: youremail@email.com + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/issue_comment.yml b/.github/workflows/issue_comment.yml new file mode 100644 index 0000000..fdb746c --- /dev/null +++ b/.github/workflows/issue_comment.yml @@ -0,0 +1,16 @@ +on: + issue_comment: + types: [ created ] +name: Commented Pull Request +jobs: + pullRequestHandler: + name: Pull Request Validator + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: Pull Request Validation + uses: Ash258/Scoop-GithubActions@stable + if: startsWith(github.event.comment.body, '/verify') + env: + GITH_EMAIL: youremail@email.com + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..265cca2 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,15 @@ +on: + pull_request: + types: [ opened ] +name: Pull Requests +jobs: + pullRequestHandler: + name: Pull Request Validator + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: Pull Request Validation + uses: Ash258/Scoop-GithubActions@stable + env: + GITH_EMAIL: youremail@email.com + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml new file mode 100644 index 0000000..c379875 --- /dev/null +++ b/.github/workflows/schedule.yml @@ -0,0 +1,16 @@ +on: + schedule: + - cron: '0 * * * *' +name: Excavator +jobs: + excavate: + name: Excavator + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: Excavate + uses: Ash258/Scoop-GithubActions@stable + env: + GITH_EMAIL: youremail@email.com + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SKIP_UPDATED: '1' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41a7452 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/checkver* +/.cache/ +/.vagrant/ diff --git a/.vscode/Template.jsonc b/.vscode/Template.jsonc new file mode 100644 index 0000000..ec26d06 --- /dev/null +++ b/.vscode/Template.jsonc @@ -0,0 +1,133 @@ +{ + //#region General Information + "##": "Some general comment for other maintainers", + "version": "1.0", + "description": "Meaningful description.", + "homepage": "https://ash258.com", + "license": { + "identifier": "MIT", + "url": "https://ash258.com" // Whenever possible attach a program specific URL, otherwise do not use + }, + "notes": [ // String or Array Of Strings + "Some notes shown after installation" + ], + //#endregion General Information + //#region Requirements + // "depends": "MANIFEST", + // or Array of string + "depends": [ + "bucket/someManifest", + "manifest" + ], + "suggest": { + "COSI": "COSI" + // "Array": [ + // "bucket/manifest", + // "manifest", + // ] + }, + //#endregion Requirements + //#region Downloading + "cookie": { + "name": "value" + }, + "architecture": { // Or platform specific below (URL, Hash, extract) + "64bit": { + "url": "https://ash258.com", + "hash": "899346f9f283a4fd5aa03015a3f58cde5b9c0b6a5c4d64c2cc74e9b22c1348d7", + "extract_dir": "DIRECTORY INSIDE ARCHIVE" + }, + "32bit": { + "url": [ + "https://ash258.com", + "https://ash258.com#/cosi.zip" + ], + "hash": [ + "899346f9f283a4fd5aa03015a3f58cde5b9c0b6a5c4d64c2cc74e9b22c1348d7", + "md5:899346f9f283a4fd5aa03015a3f58cde" + ], + "extract_dir": [ + "DirectoryInFirstURL", + "DirectoryInSecondtURL" + ] + } + }, + //#endregion Downloading + //#region Extracting + "innosetup": true, + "extract_dir": "FOLDER", + "extract_to": "folder", + //#endregion Extracting + //#region Installing + "pre_install": [ // String or Array Of Strings + "Run some powershell commands executed before running installer", + "other command" + ], + "installer": { + "file": "filename.exe", // Not needed to be specified if installer is downloaded file + "args": "ARGUMENT" // String or Array Of Strings + }, + "post_install": "Some powershell commands executed after running installer", + //#region UnInstalling + "uninstaller": { + "file": "uninstaller.exe", + "args": "ARGUMENT" // String or Array Of Strings + }, + //$endregion UnInstalling + //#endregion Installing + //#region Links + "bin": [ // String or Array Of Array Of Strings + "singlebinary.exe", + [ + "singlebinary.exe", + "withOtherName" + ], + [ + "singlebinary.exe", + "withOtherName", + "andSomeArguments" + ], + [ + "singlebinary.exe", + "withOtherName", + "", // Keep blank if none + "withOtherIcon.ico" + ] + ], + "shortcuts": [ // String or Array Of Array Of Strings (similar to bin) + [ + "", + "" + ] + ], + "psmodule": { + "name": "moduleName" + }, + "env_add_path": "bin", // String or Array Of Strings + "env_set": { + "KEY": "value" + }, + "persist": [ // String or Array Of Strings + "FOLDERTOPERSIST", + "FILETOPERSIST.extension" + ], + //#endregion Links + //#region Updating + // "checkver": "regex", Match regex inside string on homepage + // "checkver": "github", If homepage is set to github repo + "checkver": { + "url": "https://exampleurl.cz", + "jsonpath": "$.cosi", + "regex": "REGEXTOMATCH([\\d.]+)", + "replace": "$1" + }, + "autoupdate": { + "url": "https://ash258.com#/newName.zip", + "hash": { // Some vendors do not ship hashes 😭 + "url": "https://ash258.com", + "regex": "do not write regexes for hash algorithms, use variables ($md5, $sha1, $sha256, $sha512, $checksum)" + }, + "note": "Note after autoupdate" + } + //#endregion Updating +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..76eb8e0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "EditorConfig.EditorConfig", + "ms-vscode.PowerShell", + "fabiospampinato.vscode-terminals", + "usernamehw.errorlens", + "redhat.vscode-yaml", + ], +} diff --git a/.vscode/json.code-snippets b/.vscode/json.code-snippets new file mode 100644 index 0000000..b9a0c9c --- /dev/null +++ b/.vscode/json.code-snippets @@ -0,0 +1,104 @@ +{ + "New app String": { + "prefix": "app", + "scope": "json,jsonc", + "body": [ + "{", + "\t\"version\": \"$1\",", + "\t\"description\": \"$2\",", + "\t\"homepage\": \"$3\",", + "\t\"license\": {\"identifier\": \"$4\"},", + "\t\"notes\": \"$5\",", + "\t\"depends\": \"$6\",", + "\t\"url\": \"$7\",", + "\t\"hash\": \"$8\",", + "\t\"bin\": \"$9\",", + "\t\"shortcuts\": [", + "\t\t[", + "\t\t\t\"$10.exe\",", + "\t\t\t\"$11\"", + "\t\t]", + "\t],", + "\t\"checkver\":\"$12\",", + "\t\"autoupdate\": {", + "\t\t\"url\": \"$13\"", + "\t}", + "}\n", + ], + }, + "New app Arch": { + "prefix": "appArch", + "scope": "json,jsonc", + "body": [ + "{", + "\t\"version\": \"$1\",", + "\t\"description\": \"$2\",", + "\t\"homepage\": \"$3\",", + "\t\"license\": {\"identifier\": \"$4\"},", + "\t\"notes\": \"$5\",", + "\t\"depends\": \"$6\",", + "\t\"architecture\": {", + "\t\t\"64bit\": {", + "\t\t\t\"url\": \"$7\",", + "\t\t\t\"hash\": \"$8\"", + "\t\t},", + "\t\t\"32bit\": {", + "\t\t\t\"url\": \"$9\",", + "\t\t\t\"hash\": \"$10\"", + "\t\t}", + "\t},", + "\t\"bin\": \"$11\",", + "\t\"shortcuts\": [", + "\t\t[", + "\t\t\t\"$12.exe\",", + "\t\t\t\"$13\"", + "\t\t]", + "\t]", + "}\n", + ], + }, + "New Architecture": { + "prefix": "arch", + "scope": "json,jsonc", + "body": [ + "\"architecture\": {", + "\t\"64bit\": {", + "\t\t\"url\": \"$1\",", + "\t\t\"hash\": \"$2\"", + "\t},", + "\t\"32bit\": {", + "\t\t\"url\": \"$3\",", + "\t\t\"hash\": \"$4\"", + "\t}", + "},", + ], + }, + "New Autoupdate with Arch": { + "prefix": "upAr", + "scope": "json,jsonc", + "body": [ + "\"autoupdate\": {", + "\t\"architecture\": {", + "\t\t\"64bit\": {", + "\t\t\t\"url\": \"$1\"", + "\t\t},", + "\t\t\"32bit\": {", + "\t\t\t\"url\": \"$2\"", + "\t\t}", + "\t}", + "}", + ], + }, + "Check for existing persist file": { + "prefix": "persistCheck", + "scope": "json,jsonc", + "body": [ + "\"\\$file = '$1'\",", + "\"if (!(Test-Path \\\"\\$persist_dir\\\\\\\\\\$file\\\")) {\",", + "\"\tWrite-Host 'File' \\$file 'does not exists. Creating.' -f Yellow\",", + "\"\t\\$CONT = @('$2')\",", + "\"\tSet-Content \\\"\\$dir\\\\\\\\\\$file\\\" (\\$CONT -join \\\"`r`n\\\") -Encoding Ascii\",", + "\"}\"", + ], + }, +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bd8584e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,54 @@ +{ + "json.schemas": [ + { + "url": "https://raw.githubusercontent.com/lukesampson/scoop/master/schema.json", + "fileMatch": [ + ".vscode/Template.jsonc", + "bucket/*.json", + ], + }, + ], + "powershell.codeFormatting.preset": "OTBS", + "yaml.format.bracketSpacing": true, + "yaml.format.enable": true, + "yaml.format.singleQuote": true, + "yaml.validate": true, + "yaml.schemas": { + "http://json.schemastore.org/appveyor": "appveyor.yml", + "https://raw.githubusercontent.com/lukesampson/scoop/master/schema.json": [ + "bucket/*.yml", + ], + }, + "terminals.terminals": [ + { + "name": "Powershell", + "shellPath": "powershell.exe", + "shellArgs": [ + "-NoLogo", + "-NoExit", + ], + "focus": true, + "open": true, + }, + { + "name": "Powershell Core", + "shellPath": "pwsh.exe", + "shellArgs": [ + "-NoLogo", + "-NoExit", + ], + "focus": true, + "open": true, + }, + { + "name": "Powershell Core (Preview)", + "shellPath": "pwsh-preview.exe", + "shellArgs": [ + "-NoLogo", + "-NoExit", + ], + "focus": true, + "open": true, + }, + ], +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..9ed4625 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,293 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Check version (Whole repository)", + "detail": "Execute checkver for each manifests ini each folder inside repository.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": ".\\bin\\checkver.ps1", + "args": [ + "-Recurse", + ], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "group": "test", + "problemMatcher": [], + }, + { + // Default (While opened file, Press CTRL+F9 / CTRL+SHIFT+B) + "label": "Check and update (Actual)", + "detail": "Custom version check with auto commit", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": ".\\bin\\checkAndPush.ps1", + "args": [ + "'${file}'", + "${input:pickUpdateType}", + "${input:pickCheckType}", + ], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "reevaluateOnRerun": false, + }, + "group": { + "kind": "build", + "isDefault": true, + }, + }, + { + "label": "Test", + "detail": "Execute Pester tests in repository root directory.", + "type": "shell", + "command": ".\\bin\\test.ps1", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "group": "test", + "problemMatcher": [], + }, + { + "label": "Missing Checkver", + "detail": "Check if manifests have checkver and autoupdate properties.", + "type": "shell", + "command": ".\\bin\\missing-checkver.ps1; .\\bin\\missing-checkver.ps1 -dir \"TODO\"", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "group": "test", + "problemMatcher": [], + }, + { + "label": "Push Auto-PR", + "detail": "Execute checkver and push updated manifests.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": ".\\bin\\auto-pr.ps1", + "args": [ + "-Push", + ], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": true, + "clear": false, + }, + "problemMatcher": [], + }, + { + "label": "Checkver Actual", + "detail": "Check version of currently opened manifest.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": ".\\bin\\checkver.ps1", + "args": [ + "-App", + "'${fileBasenameNoExtension}'", + "-Dir", + "'${relativeFileDirname}'", + "-Force", + ], + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + }, + }, + { + "label": "Checkhashes Actual", + "detail": "Check hashes of currently opened manifest.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": ".\\bin\\checkhashes.ps1", + "args": [ + "-App", + "'${fileBasenameNoExtension}'", + "-Dir", + "'${relativeFileDirname}'", + "-Force", + ], + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + }, + }, + { + "label": "Purge Uninstall Actual", + "detail": "Uninstall currently opened manifest and remove persisted data.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": "scoop", + "args": [ + "uninstall", + "'${fileBasenameNoExtension}'", + "-p", + ], + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + }, + }, + { + "label": "Install Actual", + "detail": "Install currently opened manifest.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": "scoop", + "args": [ + "install", + "'${file}'", + ], + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + }, + }, + { + "label": "ReInstall Actual", + "detail": "Uninstall (--purge) and install currently opened manifest.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "dependsOn": [ + "Purge Uninstall Actual", + "Install Actual", + ], + "dependsOrder": "sequence", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + }, + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + }, + }, + { + "label": "Force Update Actual", + "detail": "Update currently opened manifest.", + "type": "shell", + "options": { + "env": { + "SCOOP_DEBUG": "true", + }, + }, + "command": "scoop", + "args": [ + "update", + "'${fileBasenameNoExtension}'", + "-f", + ], + "problemMatcher": [], + "runOptions": { + "instanceLimit": 99, + "reevaluateOnRerun": false, + }, + }, + ], + "inputs": [ + { + "id": "pickUpdateType", + "description": "Select how manifest should be updated.", + "type": "pickString", + "options": [ + "-Update", + "-ForceUpdate", + ], + "default": "-Update", + }, + { + "id": "pickCheckType", + "description": "Select what binary should be called. (checkver or checkhashes)", + "type": "pickString", + "options": [ + "-Hashes:$false", + "-Hashes", + ], + "default": "-Hashes:$false", + }, + ], +} diff --git a/Bucket.Tests.ps1 b/Bucket.Tests.ps1 new file mode 100644 index 0000000..ef5dd0d --- /dev/null +++ b/Bucket.Tests.ps1 @@ -0,0 +1,3 @@ +if (-not ($env:SCOOP_HOME)) { $env:SCOOP_HOME = scoop prefix scoop | Resolve-Path } + +. "$env:SCOOP_HOME\test\Import-Bucket-Tests.ps1" diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c591e0 --- /dev/null +++ b/README.md @@ -0,0 +1,134 @@ +# Generic scoop bucket + +❗❗🎉 Repository was converted into Template. See [blog](https://github.blog/2019-06-06-generate-new-repositories-with-repository-templates/?utm_campaign=1559837005&utm_medium=social&utm_source=twitter&utm_content=1559837005) for more information. 🎉❗❗ + +In this repository you will find everything you need to know about creating custom bucket with appveyor support. + +- [Files and helpers](#files-and-helpers) + - [`bucket` Folder](#bucket-folder) + - [`bin` Folder](#bin-folder) + - [`Bucket.Tests.ps1` File](#buckettestsps1-file) + - [`.vscode` Folder](#vscode-folder) + - [`.github` Folder](#github-folder) + - [`config files`](#config-files) +- [How to use and adopt this bucket](#how-to-use-and-adopt-this-bucket) + +## Files and helpers + +### `bucket` Folder + +- All manifests belong here +- `.gitkeep` file could be removed after you push your first manifest + +### `bin` Folder + +Scripts which will save you time while debuging and writing manifests. +If you need help how to use them just run `Get-Help .\bin\.ps1`. + +### `Bucket.Tests.ps1` File + +- Test which are executed inside Appveyor pipeline +- Could be configured as `pre_commit` hook + +### `.vscode` Folder + +Contains all syntax highlighting, code formating, manifest creating tools you could use. + +- Extensions + - All extensions which will save your time while writing manifests are in recommended sections + - You will be notified about installing them when you open project +- Settings + - All settings are set to be compatible with Appveyor pipeline and upstream (official) repositories + - No need to worry about formating restrictions between repositories. +- Code snippets + - > Code snippets are templates that make it easier to enter repeating code patterns, such as loops or conditional-statements. + - You could use workspace wide code snippets for speed up manifest creating + - While editing json file write partitial name of snippet and press `tab` + - Available Json snippets: + - `app` + - Create default manifest structure + - `appArch` + - Create default manifest structure with full acrchitecture + - `arch` + - Create only architecture property with 64bit and 32bit + - `upAr` + - Create autoupdate property with architecture + - `persistCheck` + - Installer / pre_install script for checking if file is already persisted or need to be created + +### `.github` Folder + +GitHub repository configuration. + +- `workflows` folder + - Linux (legacy) version [GitHub Actions](https://github.com/features/actions) configuration for automatic issue/PR/updates handling. + - Windows version of actions could be used for better and future proof implementation (see for updated configs) +- `CODEOWNERS` + - Pull requests will request review for users defined in this file +- `PULL REQUEST TEMPLATE` + - Prefilled pull request types with proper titles +- `ISSUE TEMPLATE` + - The most used issue templates for users to select and prefilled with required information and labels + +### `config files` + +- `.appveyor.yml` + - Definition of Appveyor CI pipeline +- `.editorconfig` + - Universal configuration file, compatible with all types of editors + - Defines how files should look +- `.gitattributes` + - Simplifying line endings for git + - No need to configure `auto.clrf` setting on each clone or new workspaces +- `Bucket.Tests.ps1` + - Test which are executed inside Appveyor pipeline + - Could be configured as `pre_commit` hook + +## How to use and adopt this bucket + +1. Click on `Use this template` to create new repository in your account with same files +1. Open project settings and **give your bucket in new name** +1. Add proper description of repository + - Information about what type of manifests could be found here +1. Add `scoop-bucket` tag for repository + - Your manifests will be automatically available at +1. Enable appveyor CI/CD + 1. Register / Login to [Appveyor](https://ci.appveyor.com/login) + 1. Click `New Project` + 1. From Left Panel, choose your source control variant (Github) + 1. From Right Panel, choose repository with bucket and click `+ Add` + 1. 🎉 Project created and ready to build 🎉 + 1. Get Badge URL + 1. Open Appveyor Project settings + 1. Navigate to Badges + 1. Copy `Branch Sample markdown code` snippet for further usage + - Only master branch is better, since you can freely test in other branches and do not mystificate users + - [You could use alternative styles](https://shields.io/category/build#styles) +1. Clone project into some folder + - `git clone git@github.com:USER/REPO.git MyAwesomeBucket` + - or + - `git clone https://github.com/USER/REPO.git MyAwesomeBucket` +1. Open vscode with this clone + - `code MyAwesomeBucket` +1. _[optional]_ Configure remote repository + 1. `git remote add 'upstream' 'https://github.com/Ash258/GenericBucket.git'` + - This step will allow you to synchronize changes with this template repository + - If some changes are pushed into this repository and you want to reflect them into your bucket, you can simply do something like: + - `git fetch --all` + - `git checkout -B upstream-master -t upstream/master` + - Do changes + - `git merge master` or create PR in github +1. Create proper README.md + 1. [Open this README in the browser for reference](https://github.com/Ash258/GenericBucket/tree/master/README.md) + 1. Open `README.template.md` + 1. Replace all `%%templatestring%%` with real and according values + 1. Replace appveyor status badge with yours + - See: + 1. Override this README with completed `README.template.md` + 1. Remove template `README.template.md` +1. Repository tweaks + 1. Open `.github\CODEOWNERS` and change `@Ash258` to desired github username + 1. Actions + 1. Open each file in `.github\workflows` and change `youremail@email.com` with your email + 1. Visit for more information +1. 🎉🎉 Everything set. High quality and automated bucket is ready for new users 🎉🎉 diff --git a/README.template.md b/README.template.md new file mode 100644 index 0000000..2b12514 --- /dev/null +++ b/README.template.md @@ -0,0 +1,3 @@ +# Scoop %%BUCKET_NAME%% Bucket %%SAMPLE_MARKDOWN_BADGE_CODE%% + +`scoop bucket add %%NICE_NAME_TO_BE_SHOWN_TO_USER%% '%%HTTPS_GITHUB_REPOSITORY_URL.git%%'` diff --git a/bin/Helpers.ps1 b/bin/Helpers.ps1 new file mode 100644 index 0000000..d80e25c --- /dev/null +++ b/bin/Helpers.ps1 @@ -0,0 +1,9 @@ +$ROOT_DIRECTORY = Resolve-Path "$PSScriptRoot\.." +$BUCKET_DIRECTORY = Resolve-Path "$ROOT_DIRECTORY\bucket" + +function Get-RecursiveFolder { + $folders = @($ROOT_DIRECTORY) + $folders += Get-ChildItem $ROOT_DIRECTORY -Directory | Where-Object { $_ -inotmatch '.vscode|bin' } + + return Resolve-Path $folders +} diff --git a/bin/auto-pr.ps1 b/bin/auto-pr.ps1 new file mode 100644 index 0000000..b92390a --- /dev/null +++ b/bin/auto-pr.ps1 @@ -0,0 +1,49 @@ +<# +.SYNOPSIS + Updates manifests and pushes them or creates pull-requests. +.DESCRIPTION + Updates manifests and pushes them to directly the master branch or creates pull-requests for upstream. +.PARAMETER Manifest + Specify manifest to be updated. +.PARAMETER Dir + Specify directory with manifests. +.PARAMETER Upstream + Specify upstream repository with target branch. +.PARAMETER Push + Specify if updates should be directly pushed to 'origin master'. +.PARAMETER Request + Specify if pull-requests should be created on 'upstream master' for each manifest. +.PARAMETER SpecialSnowflakes + Specify list of manifests, which should be force updated. +#> +param( + [Alias('App', 'Name')] + [String] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket", + [ValidatePattern('^(.+)\/(.+):(.+)$')] + [String] $Upstream = $((git config --get remote.origin.url) -replace '^.+[:/](?.*)\/(?.*)(\.git)?$', '${user}/${repo}:master'), + [Switch] $Push, + [Switch] $Request, + [string[]] $SpecialSnowflakes +) + +begin { + if (-not $env:SCOOP_HOME) { + if (-not (Get-Command 'scoop' -ErrorAction SilentlyContinue)) { throw 'Scoop installation or SCOOP_HOME environment is required' } + $env:SCOOP_HOME = scoop prefix scoop | Resolve-Path + } + $Params = @{ + App = $Manifest + Dir = Resolve-Path $Dir + Upstream = $Upstream + Push = $Push + Request = $Request + SpecialSnowflakes = $SpecialSnowflakes + SkipUpdated = $true + } +} + +process { & "$env:SCOOP_HOME\bin\auto-pr.ps1" @Params } + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/checkAndPush.ps1 b/bin/checkAndPush.ps1 new file mode 100644 index 0000000..f22c1d4 --- /dev/null +++ b/bin/checkAndPush.ps1 @@ -0,0 +1,77 @@ +<# +.SYNOPSIS + Update manifest, commit and push. +.DESCRIPTION + Use as vscode task: + 1. Open manifest in editor + 1. Press CTRL+SHIFT+B or CTRL+F9 (IntelliJ) + 1. Be surprised +.PARAMETER Manifest + Full Path to manifest. (vscode ${file}) +.PARAMETER Force + Force parameter will be passed to checkver. +.PARAMETER Hashes + checkhashes.ps1 script will be executed instead of checkver.ps1 +#> +param( + [Alias('App')] + [String[]] $Manifest, + [Alias('ForceUpdate')] + [Switch] $Force, + [Switch] $Hashes +) + +begin { + . "$PSScriptRoot\Helpers.ps1" + + if ($Force) { $arg = '-ForceUpdate' } else { $arg = '-Update' } +} + +process { + foreach ($man in $Manifest) { + # TODO: Yaml + # if (-not ($man.EndsWith('.yml'))) { + # $man += '.yml' + # } + if (-not ($man.EndsWith('.json'))) { + $man += '.json' + } + $man = Resolve-Path $man + $folder = Split-Path $man -Parent + $file = Split-Path $man -Leaf + $noExt = ($file -split '\.')[0] + $cmd = 'checkver' + + if ($Force) { scoop cache rm $noExt } + if ($Hashes) { $cmd = 'checkhashes' } + + Invoke-Expression -Command "$PSScriptRoot\$cmd.ps1 '$noExt' '$folder' $arg" + + $updated = @(git status -s) + + if (($updated -match "$noExt").Count -gt 0) { + # TODO: Yaml + # $manifest = Get-Content $man -Raw -Encoding UTF8 | ConvertFrom-Yaml -Ordered + [psobject] $manifest = Get-Content $man -Raw -Encoding UTF8 | ConvertFrom-Json + $message = "$noExt`: Bumped to $($manifest.version)" + + if ($Hashes) { $message = "${noExt}: Fixed hashes" } + + Write-Host 'Commiting' -ForegroundColor Green + git commit --message $message --only "*$file" + $exit = $LASTEXITCODE + + if ($exit -gt 0) { + Write-Host 'Pre-commit hook failed.' -ForegroundColor Red + exit $exit + } + + Write-Host 'Pushing' -ForegroundColor Green + git push + + Write-Host 'DONE' -ForegroundColor Yellow + } else { + Write-Host 'No Changes' -ForegroundColor Yellow + } + } +} diff --git a/bin/checkhashes.ps1 b/bin/checkhashes.ps1 new file mode 100644 index 0000000..27334f4 --- /dev/null +++ b/bin/checkhashes.ps1 @@ -0,0 +1,68 @@ +<# +.SYNOPSIS + Check hashes of all URLs inside manifest. +.DESCRIPTION + Check hashes of all URLs inside manifest. + Script will download every URL and then calculate hash of them. +.PARAMETER Manifest + Specify the name of manifest to be checked. + Placeholders are supported. +.PARAMETER Dir + Specify the directory with manifests. + Default to bucket folder. +.PARAMETER Rest + -u - Update hashes if there are mismatched ones. + -f - Update hashes always (even without mismatch). + -k - Use cache. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 + Check URLs of all manifests. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 MAN + Check URLs of manifests MAN.json inside bucket root. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 MAN TODO + Check URLs of manifests MAN.json inside folder ./BUCKETROOT/TODO. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 MAN -u + Check URLs of manifests MAN and update if there are some mismatches. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 MAN -f + Check URLs of manifests MAN and update even if every hash is correct. +.EXAMPLE + PS BUCKETDIR> .\bin\checkhashes.ps1 MAN -k + Check URLs of manifests MAN and keep it's downloaded files. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App', 'Name')] + [String[]] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket", + [Switch] $Recurse, + [Parameter(ValueFromRemainingArguments)] + [String[]] $Rest +) + + +begin { + . "$PSScriptRoot\Helpers.ps1" + + if (-not $env:SCOOP_HOME) { + if (-not (Get-Command 'scoop' -ErrorAction SilentlyContinue)) { throw 'Scoop installation or SCOOP_HOME environment is required' } + $env:SCOOP_HOME = scoop prefix scoop | Resolve-Path + } + $Dir = Resolve-Path $Dir + $Script = "$env:SCOOP_HOME\bin\checkhashes.ps1" + $Rest = ($Rest | Select-Object -Unique) -join ' ' +} + +process { + if ($Recurse) { + Get-RecursiveFolder | ForEach-Object { Invoke-Expression -Command "$Script -Dir ""$_"" $Rest" } + } else { + foreach ($man in $Manifest) { Invoke-Expression -Command "$Script -App ""$man"" -Dir ""$Dir"" $Rest" } + } +} + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/checkurls.ps1 b/bin/checkurls.ps1 new file mode 100644 index 0000000..6d45a80 --- /dev/null +++ b/bin/checkurls.ps1 @@ -0,0 +1,55 @@ +<# +.SYNOPSIS + Check if all urls inside manifest are valid. +.PARAMETER Manifest + Manifest to check. + Wildcard * is supported. +.PARAMETER Dir + Location where to search manifests. + Default to bucket folder. +.PARAMETER Timeout + How many seconds to wait until mark URL as invalid. +.PARAMETER Rest + -s - Skip manifests will all URLs valid. +.EXAMPLE + PS BUCKETROOT > .\bin\checkurls + Check urls for all manifests in root of bucket. +.EXAMPLE + PS BUCKETROOT > .\bin\checkurls cosi + Check urls for cosi.json manifest in root of bucket. +.EXAMPLE + PS BUCKETROOT > .\bin\checkurls cosi TODO + Check urls for cosi.json manifest in TODO directory. +.EXAMPLE + PS BUCKETROOT > .\bin\checkurls cosi TODO 25 + Check urls for cosi.json manifest in TODO directory with 25 timeout. +.EXAMPLE + PS BUCKETROOT > .\bin\checkurls -dir TODO + Check urls for all manifests in TODO directory. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App')] + [String[]] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket", + [Int] $Timeout = 5, + [Switch] $Recurse, + [Parameter(ValueFromRemainingArguments = $true)] + [String[]] $Rest = @() +) + +begin { + if (-not $env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) } + $Dir = Resolve-Path $Dir + $Script = "$env:SCOOP_HOME\bin\checkurls.ps1" + $Rest = ($Rest | Select-Object -Unique) -join ' ' +} + +process { + if ($Recurse) { + Get-RecursiveFolder | ForEach-Object { Invoke-Expression -Command "$Script -Dir ""$_"" -Timeout $Timeout $Rest" } + } else { + foreach ($man in $Manifest) { Invoke-Expression -Command "$Script -App ""$man"" -Dir ""$Dir"" -Timeout $Timeout $Rest" } + } +} diff --git a/bin/checkver.ps1 b/bin/checkver.ps1 new file mode 100644 index 0000000..97dd85b --- /dev/null +++ b/bin/checkver.ps1 @@ -0,0 +1,82 @@ +<# +.SYNOPSIS + Check version of given manifests. +.DESCRIPTION + Check version of given manifests (If no manifest is present, all manifests in root of repo will be checked). + -s Parameter is set to true by default. (use -ns to show all) + Few control parameters could be used. + -u - Update given manifests + -f - Force update given manifests +.PARAMETER Manifest + Manifest to check. + It could be List of manifests, specific manifest or string with placeholder. +.PARAMETER Dir + Where to search for manifest. + Default to bucket folder. +.PARAMETER Recurse + Manifests in all subdirectories will be checked. (except .vscode and bin) +.PARAMETER Rest + -s - Skip manifest with latest version + -u - Update given manifests + -f - Force update given manifests + Usefull for hash updates +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 + Check all manifests in root. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 MANIFEST + Check manifest with name MANIFEST.json in root. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 -manifest MANIFEST + Check manifest with name MANIFEST.json in root. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 -dir TODO -manifest MANIFEST + Check manifest with name MANIFEST.json in TODO directory. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 MANIFEST TODO + Check manifest with name MANIFEST.json in directory TODO. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 -dir TODO + Check all manifests in directory TODO. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 MAN* + Check all manifests starting with MAN in root. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 Manifest1, Manifest2, Manifest3 + Check all manifests (Manifest 1 to 3) in root. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 MANIFEST -u + Check manifest with name MANIFEST.json in root and update if there is new version. +.EXAMPLE + PS BUCKETROOT > .\bin\checkver.ps1 MANIFEST -f + Check manifest with name MANIFEST.json in root and update even when there is no new version. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App')] + [String[]] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket", + [Switch] $Recurse, + [Parameter(ValueFromRemainingArguments = $true)] + [String[]] $Rest = @() +) + +begin { + . "$PSScriptRoot\Helpers.ps1" + + if (-not $env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) } + $Dir = Resolve-Path $Dir + $Script = "$env:SCOOP_HOME\bin\checkver.ps1" + $Rest = $Rest | Select-Object -Unique # Remove duplicated switches +} + +process { + if ($Recurse) { + Get-RecursiveFolder | ForEach-Object { Invoke-Expression -Command "$Script -Dir ""$_"" $Rest" } + } else { + foreach ($man in $Manifest) { Invoke-Expression -Command "$Script -App ""$man"" -Dir ""$Dir"" $Rest" } + } +} + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/describe.ps1 b/bin/describe.ps1 new file mode 100644 index 0000000..76b1a36 --- /dev/null +++ b/bin/describe.ps1 @@ -0,0 +1,26 @@ +<# +.SYNOPSIS + Find description for given manifest +.PARAMETER Manifest + Manifest to check. + It could be List of manifests, specific manifest or string with placeholder. +.PARAMETER Dir + Where to search for manifest. + Default to bucket folder. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App')] + [String[]] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket" +) + +begin { + if (-not $env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) } + $Dir = Resolve-Path $Dir +} + +process { foreach ($man in $Manifest) { Invoke-Expression -Command "$env:SCOOP_HOME\bin\describe.ps1 -App ""$man"" -Dir ""$Dir""" } } + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/formatjson.ps1 b/bin/formatjson.ps1 new file mode 100644 index 0000000..cdf7f06 --- /dev/null +++ b/bin/formatjson.ps1 @@ -0,0 +1,25 @@ +<# +.SYNOPSIS + Format manifests using scoop's formatter. +.PARAMETER App + Manifest name. +.PARAMETER Dir + Where to search for manifests. + Default to bucket folder. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App')] + [String[]] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket" +) + +begin { + if (-not $env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) } + $Dir = Resolve-Path $Dir +} + +process { foreach ($man in $Manifest) { Invoke-Expression -Command "$env:SCOOP_HOME\bin\formatjson.ps1 -App ""$man"" -Dir ""$Dir""" } } + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/missing-checkver.ps1 b/bin/missing-checkver.ps1 new file mode 100644 index 0000000..a6713c7 --- /dev/null +++ b/bin/missing-checkver.ps1 @@ -0,0 +1,41 @@ +<# +.SYNOPSIS + Check if manifests have checkver and autoupdate property. +.DESCRIPTION + Check if manifests have checkver property. +.PARAMETER App + Manifest name. +.PARAMETER Dir + Directory where to search for manfiest. + Default to bucket folder. +.PARAMETER Rest + -s - Skip supported +.EXAMPLE + PS BUCKETROOT > .\bin\missing-checkver.ps1 + Check all manifests inside root of bucket. +.EXAMPLE + PS BUCKETROOT > .\bin\missing-checkver.ps1 TODO + Check all manifests inside TODO directory. +.EXAMPLE + PS BUCKETROOT > .\bin\missing-checkver.ps1 -dir TODO + Check all manifests inside TODO directory. +#> +param( + [Parameter(ValueFromPipeline = $true)] + [Alias('App')] + [String] $Manifest = '*', + [ValidateScript( { if ( Test-Path $_ -Type Container) { $true } else { $false } })] + [String] $Dir = "$PSScriptRoot\..\bucket", + [Parameter(ValueFromRemainingArguments = $true)] + [String[]] $Rest = '' +) + +begin { + if (-not $env:SCOOP_HOME) { $env:SCOOP_HOME = Resolve-Path (scoop prefix scoop) } + $Dir = Resolve-Path $Dir + $Rest = $Rest -join ' ' +} + +process { Invoke-Expression -Command "$env:SCOOP_HOME\bin\missing-checkver.ps1 -App ""$Manifest"" -Dir ""$Dir"" $Rest" } + +end { Write-Host 'DONE' -ForegroundColor Yellow } diff --git a/bin/test.ps1 b/bin/test.ps1 new file mode 100644 index 0000000..f8616af --- /dev/null +++ b/bin/test.ps1 @@ -0,0 +1,8 @@ +<# +.SYNOPSIS + Execute Pester tests in repository root directory. +#> + +$result = Invoke-Pester "$PSScriptRoot\.." -PassThru + +exit $result.FailedCount diff --git a/bucket/.gitkeep b/bucket/.gitkeep new file mode 100644 index 0000000..df26a2f --- /dev/null +++ b/bucket/.gitkeep @@ -0,0 +1 @@ +Some text to keep CRLF for passing tests without manifest