Skip to content

Commit 6c04001

Browse files
p-y-t-h-e-cpflookyjohnhrochpkoper
authored
chore(DEV SETUP): added Bash and PowerShell dev setup scripts (#167)
* doc: added tags into fundamentals def * chore(DEV SETUP): added dev_setup bash file which automates setting up dev environment * chore(DEV SETUP): added dev_setup powershell script plus few updates * chore(DEV SETUP): updated CONTRIBUTING.md with how create a local dev with setup scripts * chore(DEV SETUP): corrected setup scripts indentation --------- Co-authored-by: Flook Peter <pflooky@hotmail.com> Co-authored-by: johnroch <78982434+johnhroch@users.noreply.github.com> Co-authored-by: pkoper <pkoper@jaguarlandrover.com>
1 parent 58d4bc0 commit 6c04001

File tree

4 files changed

+578
-0
lines changed

4 files changed

+578
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,10 @@ docs/contributing.md
1111
docs/home.md
1212
docs/vendors.md
1313
docs/examples/**/*.md
14+
15+
# Development setup exclusions — keeping the repository clean and minimal.
16+
# Except for `.venv/`, these files are typically not included in
17+
# `.gitignore`, but are listed here to maintain simplicity and clarity.
18+
.venv/
19+
.pre-commit-config.yaml
20+
.markdownlint.json

CONTRIBUTING.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,44 @@ image: "https://raw.githubusercontent.com/bitol-io/artwork/main/horizontal/color
77
# Contributing to Open Data Contract Standard
88

99
Thank you for your interest in contributing to Open Data Contract Standard (ODCS). Please refer to the [TSC contributing guidelines](https://github.com/bitol-io/tsc/blob/main/CONTRIBUTING.md).
10+
11+
## Create a Local Development Environment
12+
13+
To set up a local development environment, use the predefined setup scripts:
14+
15+
<details><summary>For Windows Development Environment run:</summary>
16+
17+
```shell
18+
. \scr\script\dev_setup.ps1
19+
```
20+
21+
</details>
22+
23+
<details><summary>For Unix Development Environment run:</summary>
24+
25+
```bash
26+
source src/script/dev_setup.sh
27+
```
28+
29+
</details>
30+
31+
Each of these scripts will:
32+
33+
* Check the virtual environment:
34+
* Create and activate it if missing
35+
* Activate it if not already active
36+
* Check `pip` status:
37+
* Verify the current version
38+
* Compare against the latest version
39+
* Upgrade if necessary
40+
* Check `pre_commit` status:
41+
* Install if missing
42+
* Check `pre-commit` version:
43+
* Verify the current version
44+
* Compare against the latest version
45+
* Upgrade if necessary
46+
* Check `pre-commit` hooks:
47+
* Create `.pre-commit-config.yaml` if missing
48+
* Update and install all hooks
49+
* Check `.markdownlint.json`:
50+
* Create the file if it doesn’t exist

src/script/dev_setup.ps1

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#!/usr/bin/env pwsh
2+
<#
3+
.SYNOPSIS
4+
Developer environment setup (PowerShell 7+)
5+
.DESCRIPTION
6+
Creates/activates venv (where possible), checks/updates pip and pre-commit,
7+
and Asserts config files (.pre-commit-config.yaml, .markdownlint.json, .commitlintrc.json).
8+
#>
9+
10+
# -----------------------------
11+
# 🎨 Color map & helpers
12+
# -----------------------------
13+
$Colors = @{
14+
'Info' = 'Cyan'
15+
'Task' = 'Yellow'
16+
'Pass' = 'Green'
17+
'Warn' = 'Magenta'
18+
'Fail' = 'Red'
19+
}
20+
21+
function Write-Info([string]$m){Write-Host "💡 [INFO] $m" -ForegroundColor $Colors.Info }
22+
function Write-Task([string]$m){ Write-Host "⚡ [TASK] $m" -ForegroundColor $Colors.Task }
23+
function Write-Pass([string]$m){ Write-Host "✅ [PASS] $m" -ForegroundColor $Colors.Pass }
24+
function Write-Warn([string]$m){ Write-Host "⚠️ [WARN] $m" -ForegroundColor $Colors.Warn }
25+
function Write-Fail([string]$m){ Write-Host "❌ [FAIL] $m" -ForegroundColor $Colors.Fail }
26+
27+
# -----------------------------
28+
# 🌱 Virtual environment
29+
# -----------------------------
30+
$VenvDir = ".venv"
31+
32+
function Assert-VirtualEnv {
33+
Write-Info "Checking virtual environment status ..."
34+
35+
# PowerShell activation path (Windows & pwsh)
36+
$ActivatePs1 = Join-Path $VenvDir "Scripts/Activate.ps1"
37+
38+
if (Test-Path $ActivatePs1) {
39+
if ($env:VIRTUAL_ENV) {
40+
Write-Pass "Virtual environment found and active."
41+
} else {
42+
Write-Info "Virtual environment found but not active."
43+
Write-Task "activating ..."
44+
try {
45+
& $ActivatePs1
46+
} catch {
47+
Write-Warn "Activation script ran but returned an error: $($_.Exception.Message)"
48+
}
49+
}
50+
} else {
51+
Write-Warn "No virtual environment found."
52+
Write-Task "creating and activating ..."
53+
try {
54+
& python -m venv $VenvDir 2>&1 | Out-Null
55+
& $ActivatePs1
56+
} catch {
57+
Write-Fail "Failed to create virtual environment: $($_.Exception.Message)"
58+
}
59+
}
60+
}
61+
62+
# -----------------------------
63+
# 🔧 Pip version helpers (robust regex)
64+
# -----------------------------
65+
function Get-PipVersion {
66+
try {
67+
$out = & pip --version 2>&1
68+
} catch {
69+
return $null
70+
}
71+
$match = [regex]::Match($out, 'pip\s+(\d+(?:\.\d+)+)')
72+
if ($match.Success) { return $match.Groups[1].Value }
73+
return $null
74+
}
75+
76+
function Get-LatestPipVersion {
77+
try {
78+
$dry = & python -m pip install --upgrade pip --dry-run 2>&1
79+
} catch {
80+
$dry = $null
81+
}
82+
if ($null -ne $dry) {
83+
# look for "pip-1.2.3" or parenthesized versions like "(1.2.3)"
84+
$m = [regex]::Match($dry, 'pip-?(\d+(?:\.\d+)*)')
85+
if ($m.Success) { return $m.Groups[1].Value }
86+
$m2 = [regex]::Match($dry, '\((\d+(?:\.\d+)*)\)')
87+
if ($m2.Success) { return $m2.Groups[1].Value }
88+
}
89+
return $null
90+
}
91+
92+
function Assert-PipUpToDate {
93+
Write-Info "Checking pip version ..."
94+
$current = Get-PipVersion
95+
$latest = Get-LatestPipVersion
96+
97+
if (-not $current -or -not $latest) {
98+
Write-Warn "Could not determine pip versions (current: $current, latest: $latest). Skipping upgrade check."
99+
return
100+
}
101+
Write-Info "Current: $current | Latest: $latest"
102+
if ($current -eq $latest) {
103+
Write-Pass "pip is up to date."
104+
} else {
105+
Write-Warn "pip is outdated."
106+
Write-Task "upgrading ..."
107+
try { & python -m pip install --upgrade pip } catch { Write-Fail "pip upgrade failed: $($_.Exception.Message)" }
108+
}
109+
}
110+
111+
# -----------------------------
112+
# 🔄 pre-commit helpers (robust regex)
113+
# -----------------------------
114+
function Assert-PreCommitInstalled {
115+
Write-Info "Checking pre-commit installation ..."
116+
if (Get-Command pre-commit -ErrorAction SilentlyContinue) {
117+
Write-Pass "pre-commit is installed."
118+
} else {
119+
Write-Warn "pre-commit is missing."
120+
Write-Task "installing ..."
121+
try { & pip install pre-commit } catch { Write-Fail "Failed to install pre-commit: $($_.Exception.Message)"; return }
122+
}
123+
}
124+
125+
function Get-PreCommitVersion {
126+
try { $out = & pre-commit --version 2>&1 } catch { return $null }
127+
$match = [regex]::Match($out, 'pre-commit\s+(\d+(?:\.\d+)*)')
128+
if ($match.Success) { return $match.Groups[1].Value }
129+
return $null
130+
}
131+
132+
function Get-LatestPreCommitVersion {
133+
try { $dry = & pip install pre-commit --upgrade --dry-run 2>&1 } catch { $dry = $null }
134+
if ($null -ne $dry) {
135+
$m = [regex]::Match($dry, 'commit-?(\d+(?:\.\d+)*)')
136+
if ($m.Success) { return $m.Groups[1].Value }
137+
$m2 = [regex]::Match($dry, '\((\d+(?:\.\d+)*)\)')
138+
if ($m2.Success) { return $m2.Groups[1].Value }
139+
}
140+
return $null
141+
}
142+
143+
function Assert-PreCommitUpToDate {
144+
Write-Info "Checking pre-commit version ..."
145+
$current = Get-PreCommitVersion
146+
$latest = Get-LatestPreCommitVersion
147+
if (-not $current -or -not $latest) {
148+
Write-Warn "Could not determine pre-commit versions (current: $current, latest: $latest). Skipping upgrade check."
149+
return
150+
}
151+
Write-Info "Current: $current | Latest: $latest"
152+
if ($current -eq $latest) {
153+
Write-Pass "pre-commit is up to date."
154+
} else {
155+
Write-Warn "pre-commit is outdated."
156+
Write-Task "upgrading ..."
157+
try { & pip install --upgrade pre-commit } catch { Write-Fail "Failed to upgrade pre-commit: $($_.Exception.Message)" }
158+
}
159+
}
160+
161+
# -----------------------------
162+
# 📄 Config file creators (PowerShell-native)
163+
# -----------------------------
164+
function New-PreCommitConfig { @"
165+
default_stages: [pre-commit, manual]
166+
167+
repos:
168+
- repo: https://github.com/pre-commit/pre-commit-hooks
169+
rev: v6.0.0
170+
hooks:
171+
- id: trailing-whitespace
172+
- id: end-of-file-fixer
173+
- id: check-yaml
174+
args: ["--unsafe"]
175+
- id: check-added-large-files
176+
177+
- repo: https://github.com/tcort/markdown-link-check
178+
rev: v3.13.7
179+
hooks:
180+
- id: markdown-link-check
181+
args: [-q]
182+
183+
- repo: https://github.com/igorshubovych/markdownlint-cli
184+
rev: v0.45.0
185+
hooks:
186+
- id: markdownlint
187+
args: ["--ignore", "CHANGELOG.md", "--fix"]
188+
"@ | Out-File -FilePath ".pre-commit-config.yaml" -Encoding utf8 }
189+
190+
function New-MarkdownLintConfig { @"
191+
{
192+
"comment": "Markdown Lint Rules",
193+
"default": true,
194+
"MD007": {"indent": 4},
195+
"MD013": false,
196+
"MD024": false,
197+
"MD025": {"front_matter_title": ""},
198+
"MD029": {"style": "one_or_ordered"},
199+
"MD033": false
200+
}
201+
"@ | Out-File -FilePath ".markdownlint.json" -Encoding utf8 }
202+
203+
function New-CommitLintConfig { @"
204+
{
205+
"rules": {
206+
"body-leading-blank": [1, "always"],
207+
"footer-leading-blank": [1, "always"],
208+
"header-max-length": [2, "always", 72],
209+
"scope-case": [2, "always", "upper-case"],
210+
"scope-empty": [2, "never"],
211+
"subject-case": [2, "never", ["start-case", "pascal-case", "upper-case"]],
212+
"subject-empty": [2, "never"],
213+
"subject-full-stop": [2, "never", "."],
214+
"type-case": [2, "always", "lower-case"],
215+
"type-empty": [2, "never"],
216+
"type-enum": [2, "always", ["build","chore","ci","docs","feat","fix","perf","refactor","revert","style","test"]]
217+
}
218+
}
219+
"@ | Out-File -FilePath ".commitlintrc.json" -Encoding utf8 }
220+
221+
# -----------------------------
222+
# 🔧 Assert files and hooks
223+
# -----------------------------
224+
function Assert-File([string]$path, [scriptblock]$createBlock) {
225+
if (Test-Path $path) {
226+
Write-Pass "$path already exists, please ensure it has the correct format."
227+
} else {
228+
Write-Warn "$path file is missing."
229+
Write-Task "creating ..."
230+
& $createBlock
231+
}
232+
}
233+
234+
function Assert-PreCommitHooks {
235+
Write-Info "Checking pre-commit config and hooks ..."
236+
Assert-File ".pre-commit-config.yaml" { New-PreCommitConfig }
237+
try {
238+
& pre-commit autoupdate
239+
& pre-commit install
240+
} catch {
241+
Write-Warn "pre-commit command failed to run: $($_.Exception.Message)"
242+
}
243+
244+
# If commit-msg/commitlint present, install commit-msg hook and Assert commitlintrc
245+
$hasCommitMsg = Select-String -Path ".pre-commit-config.yaml" -Pattern "commit-msg|commitlint" -Quiet
246+
if ($hasCommitMsg) {
247+
Write-Task "Installing commit-msg hook ..."
248+
try {
249+
& pre-commit install --hook-type commit-msg
250+
} catch {
251+
Write-Warn "Could not install commit-msg hook: $($_.Exception.Message)"
252+
}
253+
Assert-File ".commitlintrc.json" { New-CommitLintConfig }
254+
}
255+
Assert-File ".markdownlint.json" { New-MarkdownLintConfig }
256+
}
257+
258+
# -----------------------------
259+
# 🚀 Run tasks
260+
# -----------------------------
261+
Assert-VirtualEnv
262+
Assert-PipUpToDate
263+
Assert-PreCommitInstalled
264+
Assert-PreCommitUpToDate
265+
Assert-PreCommitHooks
266+
267+
Write-Pass "🎉 Setup Completed Successfully!"

0 commit comments

Comments
 (0)