breadkit-lint 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +54 -0
  5. data/SECURITY.md +5 -0
  6. data/config/default.yml +36 -0
  7. data/docs/rules/Electrical/DanglingWire.md +9 -0
  8. data/docs/rules/Electrical/FloatingPin.md +9 -0
  9. data/docs/rules/Electrical/MissingSeriesResistor.md +11 -0
  10. data/docs/rules/Electrical/NetLabelConflict.md +10 -0
  11. data/docs/rules/Electrical/NoCommonGround.md +10 -0
  12. data/docs/rules/Electrical/PowerPinUnconnected.md +9 -0
  13. data/docs/rules/Electrical/ReversePolarity.md +10 -0
  14. data/docs/rules/Electrical/ShortCircuit.md +9 -0
  15. data/docs/rules/Electrical/ShortedComponent.md +9 -0
  16. data/docs/rules/Electrical/SplitRail.md +10 -0
  17. data/docs/rules/Electrical/SupplyVoltageRange.md +10 -0
  18. data/docs/rules/Intent/ConnectionMismatch.md +9 -0
  19. data/docs/rules/Intent/UnknownNet.md +9 -0
  20. data/docs/rules/Layout/DuplicateRef.md +10 -0
  21. data/docs/rules/Layout/HoleConflict.md +10 -0
  22. data/docs/rules/Layout/InvalidHole.md +9 -0
  23. data/docs/rules/Layout/InvalidPlacement.md +9 -0
  24. data/docs/rules/Layout/NoFreeHole.md +7 -0
  25. data/docs/rules/Layout/PinsInSameStrip.md +9 -0
  26. data/docs/rules/Layout/SplitNetLabel.md +3 -0
  27. data/docs/rules/Layout/UnknownBoard.md +3 -0
  28. data/docs/rules/Layout/UnknownOption.md +5 -0
  29. data/docs/rules/Layout/UnknownPart.md +9 -0
  30. data/docs/rules/Layout/UnknownPin.md +9 -0
  31. data/docs/rules/Layout/UnknownTransistorModel.md +5 -0
  32. data/docs/rules/Layout/UnplacedPin.md +3 -0
  33. data/docs/rules/Style/WireColor.md +9 -0
  34. data/exe/bklint +5 -0
  35. data/lib/breadkit/lint/rules/electrical.rb +371 -0
  36. data/lib/breadkit/lint/rules/intent.rb +59 -0
  37. data/lib/breadkit/lint/rules/layout.rb +33 -0
  38. data/lib/breadkit/lint/rules/style.rb +43 -0
  39. data/lib/breadkit/lint/rules/support.rb +88 -0
  40. data/lib/breadkit/lint/rules.rb +205 -0
  41. data/lib/breadkit/lint/version.rb +7 -0
  42. data/lib/breadkit/lint.rb +476 -0
  43. data/locales/en.yml +28 -0
  44. data/locales/ja.yml +65 -0
  45. data/package-lock.json +1172 -0
  46. data/package.json +12 -0
  47. data/scripts/check_bad_examples.rb +37 -0
  48. data/sig/breadkit/lint.rbs +68 -0
  49. data/site/favicon.svg +7 -0
  50. data/site/index.html +95 -0
  51. data/site/styles.css +14 -0
  52. metadata +111 -0
data/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "breadkit-lint-site",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "scripts": {
6
+ "build": "mkdir -p _site && cp -R site/. _site/ && tailwindcss -i site/styles.css -o _site/assets/site.css --minify"
7
+ },
8
+ "devDependencies": {
9
+ "@tailwindcss/cli": "4.3.3",
10
+ "tailwindcss": "4.3.3"
11
+ }
12
+ }
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "open3"
6
+
7
+ root = File.expand_path("..", __dir__)
8
+ core = File.expand_path("../breadkit", root)
9
+ files = Dir[File.join(core, "examples", "bad", "*.bk.rb")].sort
10
+ abort "no bad examples found in #{core}/examples/bad" if files.empty?
11
+
12
+ failed = false
13
+ files.each do |path|
14
+ expected = File.foreach(path).filter_map { |line| line[/\A#\s*expect:\s*(\S+)/, 1] }.first
15
+ unless expected
16
+ warn "#{path}: missing '# expect: Rule/Id' header"
17
+ failed = true
18
+ next
19
+ end
20
+
21
+ stdout, stderr, status = Open3.capture3("bklint", "--format", "json", path, chdir: root)
22
+ report = JSON.parse(stdout)
23
+ rules = report.fetch("files").flat_map { |file| file.fetch("offenses").map { |offense| offense.fetch("rule") } }
24
+ unless status.exitstatus == 1 && rules.include?(expected)
25
+ warn "#{path}: expected #{expected}, got exit #{status.exitstatus} and #{rules.inspect}"
26
+ warn stderr unless stderr.empty?
27
+ failed = true
28
+ next
29
+ end
30
+
31
+ puts "#{File.basename(path)}: #{expected} detected"
32
+ rescue JSON::ParserError, KeyError => e
33
+ warn "#{path}: invalid bklint JSON (#{e.message})"
34
+ failed = true
35
+ end
36
+
37
+ exit(failed ? 1 : 0)
@@ -0,0 +1,68 @@
1
+ module Breadkit
2
+ module Lint
3
+ VERSION: String
4
+
5
+ class Error < StandardError
6
+ end
7
+
8
+ class Offense
9
+ attr_reader rule: String
10
+ attr_reader severity: String
11
+ attr_reader message: String
12
+ attr_reader location: Breadkit::SourceLocation?
13
+ attr_reader targets: Hash[Symbol, untyped]
14
+ attr_reader state: String?
15
+ end
16
+
17
+ class Rule
18
+ attr_reader id: String
19
+ attr_reader severity: String
20
+ attr_reader description: String
21
+ attr_reader state_sensitive: bool
22
+ def check: (Context context) -> void
23
+ end
24
+
25
+ class Context
26
+ attr_reader circuit: Breadkit::Circuit
27
+ attr_reader state: Breadkit::State
28
+ attr_reader config: Config
29
+ attr_reader offenses: Array[Offense]
30
+ end
31
+
32
+ class Registry
33
+ def self.all: () -> Array[Rule | singleton(Rule)]
34
+ def self.register: (Rule | singleton(Rule) rule) -> void
35
+ end
36
+
37
+ class Config
38
+ attr_reader data: Hash[String, untyped]
39
+ def initialize: (?String? path) -> void
40
+ def severity: (Rule rule) -> String
41
+ def enabled?: (Rule rule) -> bool
42
+ def switch_states: () -> String
43
+ def fail_level: () -> String
44
+ def excludes: () -> Array[String]
45
+ def extra_parts: () -> Array[String]
46
+ def unknown_rules: () -> Array[String]
47
+ def excluded?: (String path) -> bool
48
+ end
49
+
50
+ class Engine
51
+ def initialize: (?config: Config) -> void
52
+ def run: (String | Array[String] paths, ?only: Array[String]?, ?except: Array[String]?) -> Array[Hash[Symbol, untyped]]
53
+ def fail?: (Array[Hash[Symbol, untyped]] files, ?String threshold) -> bool
54
+ def fatal?: (Array[Hash[Symbol, untyped]] files) -> bool
55
+ end
56
+
57
+ class Formatter
58
+ def text: (Array[Hash[Symbol, untyped]] files, ?locale: String) -> String
59
+ def json: (Array[Hash[Symbol, untyped]] files) -> String
60
+ def github: (Array[Hash[Symbol, untyped]] files) -> String
61
+ def sarif: (Array[Hash[Symbol, untyped]] files) -> String
62
+ end
63
+
64
+ class CLI
65
+ def run: (Array[String] argv) -> Integer
66
+ end
67
+ end
68
+ end
data/site/favicon.svg ADDED
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
2
+ <rect width="48" height="48" rx="12" fill="#1b2423" />
3
+ <path d="M10 15h28M10 33h28M15 10v28M33 10v28" fill="none" stroke="#3d4b47" stroke-width="2" />
4
+ <path d="M15 15h18v18H15z" fill="none" stroke="#d99755" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" />
5
+ <circle cx="15" cy="15" r="2.5" fill="#e8eeeb" />
6
+ <circle cx="33" cy="33" r="2.5" fill="#e8eeeb" />
7
+ </svg>
data/site/index.html ADDED
@@ -0,0 +1,95 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="theme-color" content="#101719">
7
+ <meta name="description" content="Check breadboard placement, shorts, floating pins, and mismatches with your intended connections.">
8
+ <title>breadkit-lint | Check wiring before building</title>
9
+ <link rel="canonical" href="https://breadkit.github.io/breadkit-lint/">
10
+ <link rel="icon" href="./favicon.svg" type="image/svg+xml">
11
+ <link rel="stylesheet" href="./assets/site.css">
12
+ </head>
13
+ <body class="min-h-dvh bg-ink font-sans text-paper antialiased">
14
+ <a class="sr-only rounded-sm bg-copper px-4 py-3 font-semibold text-ink focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:outline-2 focus:outline-offset-4 focus:outline-paper" href="#main">Skip to content</a>
15
+ <header class="border-b border-line">
16
+ <div class="mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-4 px-5 py-5 sm:px-8 lg:px-10">
17
+ <a class="flex items-center gap-3 rounded-sm text-xl font-semibold focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="./" aria-label="breadkit-lint home"><img class="size-8" src="./favicon.svg" alt="" width="32" height="32"><span>breadkit-lint</span></a>
18
+ <nav aria-label="Main navigation" class="flex flex-wrap items-center gap-x-5 gap-y-2 text-sm text-muted">
19
+ <a class="rounded-sm hover:text-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit/">Breadkit</a>
20
+ <a class="rounded-sm hover:text-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit/guide/">Guide</a>
21
+ <a class="rounded-sm hover:text-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit/guide/dsl/">Reference</a>
22
+ <a class="rounded-sm hover:text-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit-render/">Render</a>
23
+ <a class="rounded-sm hover:text-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://github.com/breadkit/breadkit-lint">GitHub</a>
24
+ </nav>
25
+ </div>
26
+ </header>
27
+
28
+ <main id="main">
29
+ <section class="mx-auto grid max-w-7xl items-center gap-12 px-5 py-16 sm:px-8 lg:grid-cols-2 lg:gap-16 lg:px-10 lg:py-24">
30
+ <div class="max-w-xl">
31
+ <p class="mb-5 text-sm font-medium text-copper">The Breadkit circuit checker</p>
32
+ <h1 class="text-balance text-4xl font-semibold leading-tight sm:text-5xl lg:text-6xl">Check wiring before you build.</h1>
33
+ <p class="mt-6 max-w-lg text-pretty text-lg leading-8 text-muted">Analyze breadboard holes and component connections to find placement errors, shorts, floating pins, and mismatches with your design intent.</p>
34
+ <div class="mt-8 flex flex-wrap gap-x-6 gap-y-4">
35
+ <a class="rounded-sm bg-copper px-5 py-3 font-semibold text-ink hover:bg-paper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="#example">See a finding</a>
36
+ <a class="rounded-sm py-3 font-medium text-paper underline decoration-line underline-offset-4 hover:decoration-copper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://github.com/breadkit/breadkit-lint/tree/main/docs/rules">Browse rules</a>
37
+ </div>
38
+ <div class="mt-10 rounded-lg border border-line bg-board p-5">
39
+ <p class="mb-3 text-sm text-muted">Install and run</p>
40
+ <pre class="overflow-x-auto font-mono text-sm leading-7"><code>gem install breadkit-lint
41
+ bklint circuit.bk.rb</code></pre>
42
+ </div>
43
+ </div>
44
+ <figure id="example" class="m-0 overflow-hidden rounded-xl border border-line bg-board">
45
+ <div class="border-b border-line px-5 py-4 text-sm text-muted">Example: a short circuit</div>
46
+ <div class="p-5 sm:p-7">
47
+ <pre class="overflow-x-auto font-mono text-sm leading-7 text-paper"><code>board :half
48
+ supply :USB, voltage: 5.0,
49
+ plus: "B+1", minus: "B-1"
50
+ wire "a10", "B+"
51
+ wire "b10", "B-"</code></pre>
52
+ <div class="my-6 border-t border-line"></div>
53
+ <p class="mb-3 text-sm text-muted">From the bklint report</p>
54
+ <pre class="overflow-x-auto font-mono text-sm leading-7 text-paper"><code>E: [Electrical/ShortCircuit]
55
+ inconsistent voltage constraints near USB.+</code></pre>
56
+ </div>
57
+ <figcaption class="border-t border-line px-5 py-4 text-pretty text-sm leading-6 text-muted">a10 and b10 share a conductive strip, so the positive and negative rails are shorted.</figcaption>
58
+ </figure>
59
+ </section>
60
+
61
+ <section id="checks" class="border-t border-line bg-board/60">
62
+ <div class="mx-auto max-w-7xl px-5 py-16 sm:px-8 lg:px-10">
63
+ <h2 class="text-balance text-3xl font-semibold">What it checks</h2>
64
+ <div class="mt-8 border-y border-line">
65
+ <div class="grid gap-2 py-6 md:grid-cols-3"><h3 class="text-balance text-xl font-semibold">Placement</h3><p class="text-pretty leading-7 text-muted md:col-span-2">Invalid holes, part collisions, leads placed on the same strip, and ICs that miss the center gap.</p></div>
66
+ <div class="grid gap-2 border-t border-line py-6 md:grid-cols-3"><h3 class="text-balance text-xl font-semibold">Electrical connections</h3><p class="text-pretty leading-7 text-muted md:col-span-2">Shorts, unconnected pins, split rails, supply voltages, and LED series resistors.</p></div>
67
+ <div class="grid gap-2 border-t border-line py-6 md:grid-cols-3"><h3 class="text-balance text-xl font-semibold">Design intent</h3><p class="text-pretty leading-7 text-muted md:col-span-2">Differences between <code class="font-mono text-paper">expect</code> declarations and the resolved nets.</p></div>
68
+ </div>
69
+ </div>
70
+ </section>
71
+
72
+ <section id="workflow" class="mx-auto grid max-w-7xl gap-10 px-5 py-16 sm:px-8 lg:grid-cols-2 lg:px-10">
73
+ <div>
74
+ <h2 class="text-balance text-3xl font-semibold">Use it locally or in CI</h2>
75
+ <p class="mt-4 max-w-xl text-pretty leading-7 text-muted">Choose text, JSON, GitHub annotations, or SARIF output. Set the severity that fails the run with <code class="font-mono text-paper">--fail-level</code>.</p>
76
+ <pre class="mt-6 overflow-x-auto rounded-lg border border-line bg-board p-5 font-mono text-sm leading-7"><code>bklint circuit.bk.rb --format github
77
+ bklint circuit.bk.rb --format sarif --out lint.sarif
78
+ bklint circuit.bk.rb --only Electrical/ShortCircuit</code></pre>
79
+ </div>
80
+ <div class="rounded-lg border border-line bg-board p-6">
81
+ <h3 class="text-balance text-xl font-semibold">Review findings on the diagram</h3>
82
+ <p class="mt-4 text-pretty leading-7 text-muted">Pass JSON results to breadkit-render to mark the reported holes and wires on the diagram.</p>
83
+ <pre class="mt-5 overflow-x-auto font-mono text-sm leading-7"><code>bklint circuit.bk.rb --format json --out lint.json
84
+ bkrender circuit.bk.rb --annotations lint.json \
85
+ -o review.svg</code></pre>
86
+ <a class="mt-6 inline-block rounded-sm text-paper underline decoration-copper underline-offset-4 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit-render/">Explore breadkit-render</a>
87
+ </div>
88
+ </section>
89
+
90
+ <section class="border-t border-line"><div class="mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-4 px-5 py-10 sm:px-8 lg:px-10"><p class="max-w-2xl text-pretty text-sm leading-6 text-muted">DSL files and configuration <code class="font-mono text-paper">require</code> statements run as Ruby. Only process inputs you trust. Use IR JSON for data-only exchange.</p><a class="rounded-sm text-paper underline decoration-line underline-offset-4 hover:decoration-copper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://breadkit.github.io/breadkit/guide/">Learn to write a circuit</a></div></section>
91
+ </main>
92
+
93
+ <footer class="border-t border-line"><div class="mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-3 px-5 py-7 text-sm text-muted sm:px-8 lg:px-10"><p>breadkit-lint is published independently from breadkit.</p><a class="rounded-sm text-paper underline decoration-line underline-offset-4 hover:decoration-copper focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-copper" href="https://github.com/breadkit/breadkit-lint">GitHub repository</a></div></footer>
94
+ </body>
95
+ </html>
data/site/styles.css ADDED
@@ -0,0 +1,14 @@
1
+ @import "tailwindcss";
2
+
3
+ @source "./**/*.html";
4
+
5
+ @theme {
6
+ --color-ink: #101719;
7
+ --color-board: #1b2423;
8
+ --color-line: #3d4b47;
9
+ --color-paper: #e8eeeb;
10
+ --color-muted: #a1b0aa;
11
+ --color-copper: #d99755;
12
+ --font-sans: "Avenir Next", Avenir, ui-sans-serif, system-ui, sans-serif;
13
+ --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
14
+ }
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: breadkit-lint
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yudai Takada
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: breadkit
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.1.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.1.0
26
+ description: bklint analyzes Breadkit circuits and reports layout, electrical, and
27
+ intent offenses.
28
+ email:
29
+ - t.yudai92@gmail.com
30
+ executables:
31
+ - bklint
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - CHANGELOG.md
36
+ - LICENSE.txt
37
+ - README.md
38
+ - SECURITY.md
39
+ - config/default.yml
40
+ - docs/rules/Electrical/DanglingWire.md
41
+ - docs/rules/Electrical/FloatingPin.md
42
+ - docs/rules/Electrical/MissingSeriesResistor.md
43
+ - docs/rules/Electrical/NetLabelConflict.md
44
+ - docs/rules/Electrical/NoCommonGround.md
45
+ - docs/rules/Electrical/PowerPinUnconnected.md
46
+ - docs/rules/Electrical/ReversePolarity.md
47
+ - docs/rules/Electrical/ShortCircuit.md
48
+ - docs/rules/Electrical/ShortedComponent.md
49
+ - docs/rules/Electrical/SplitRail.md
50
+ - docs/rules/Electrical/SupplyVoltageRange.md
51
+ - docs/rules/Intent/ConnectionMismatch.md
52
+ - docs/rules/Intent/UnknownNet.md
53
+ - docs/rules/Layout/DuplicateRef.md
54
+ - docs/rules/Layout/HoleConflict.md
55
+ - docs/rules/Layout/InvalidHole.md
56
+ - docs/rules/Layout/InvalidPlacement.md
57
+ - docs/rules/Layout/NoFreeHole.md
58
+ - docs/rules/Layout/PinsInSameStrip.md
59
+ - docs/rules/Layout/SplitNetLabel.md
60
+ - docs/rules/Layout/UnknownBoard.md
61
+ - docs/rules/Layout/UnknownOption.md
62
+ - docs/rules/Layout/UnknownPart.md
63
+ - docs/rules/Layout/UnknownPin.md
64
+ - docs/rules/Layout/UnknownTransistorModel.md
65
+ - docs/rules/Layout/UnplacedPin.md
66
+ - docs/rules/Style/WireColor.md
67
+ - exe/bklint
68
+ - lib/breadkit/lint.rb
69
+ - lib/breadkit/lint/rules.rb
70
+ - lib/breadkit/lint/rules/electrical.rb
71
+ - lib/breadkit/lint/rules/intent.rb
72
+ - lib/breadkit/lint/rules/layout.rb
73
+ - lib/breadkit/lint/rules/style.rb
74
+ - lib/breadkit/lint/rules/support.rb
75
+ - lib/breadkit/lint/version.rb
76
+ - locales/en.yml
77
+ - locales/ja.yml
78
+ - package-lock.json
79
+ - package.json
80
+ - scripts/check_bad_examples.rb
81
+ - sig/breadkit/lint.rbs
82
+ - site/favicon.svg
83
+ - site/index.html
84
+ - site/styles.css
85
+ homepage: https://github.com/breadkit/breadkit-lint
86
+ licenses:
87
+ - MIT
88
+ metadata:
89
+ homepage_uri: https://github.com/breadkit/breadkit-lint
90
+ source_code_uri: https://github.com/breadkit/breadkit-lint/tree/main
91
+ bug_tracker_uri: https://github.com/breadkit/breadkit-lint/issues
92
+ documentation_uri: https://github.com/breadkit/breadkit-lint/tree/main/docs
93
+ rubygems_mfa_required: 'true'
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '3.3'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 4.0.16
109
+ specification_version: 4
110
+ summary: Check breadboard wiring designs for common layout and circuit errors.
111
+ test_files: []