[DRC] Added Workaround for problems with DRC exclusions
- Global option: `drc_exclusions_workaround` - KiCad bug [11562](https://gitlab.com/kicad/code/kicad/-/issues/11562) Fixes INTI-CMNB/KiAuto#26
This commit is contained in:
parent
69269d8560
commit
c5a6d894c9
|
|
@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `--dont-stop` command line option, to try to continue even on errors (#209)
|
||||
- PDF/SVG PCB Print: option to print all pages/single page (#236)
|
||||
- iBoM: Support for variants that change component fields (#242)
|
||||
- Workaround for problems with DRC exclusions (See INTI-CMNB/KiAuto#26)
|
||||
Global option: `drc_exclusions_workaround`
|
||||
KiCad bug [11562](https://gitlab.com/kicad/code/kicad/-/issues/11562)
|
||||
|
||||
### Fixed
|
||||
- OAR computation (Report) (#225)
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ Notes:
|
|||
[**Requests**](https://pypi.org/project/Requests/) [](https://pypi.org/project/Requests/) [](https://pypi.org/project/Requests/) [](https://packages.debian.org/bullseye/python3-requests)
|
||||
- Mandatory
|
||||
|
||||
[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v1.6.13 [](https://github.com/INTI-CMNB/KiAuto) 
|
||||
[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v2.0.0 [](https://github.com/INTI-CMNB/KiAuto) 
|
||||
- Mandatory for: `gencad`, `netlist`, `pdf_pcb_print`, `pdf_sch_print`, `render_3d`, `run_drc`, `run_erc`, `step`, `svg_pcb_print`, `svg_sch_print`, `update_xml`
|
||||
- Optional to print the page frame in GUI mode for `pcb_print`
|
||||
|
||||
|
|
@ -640,6 +640,10 @@ global:
|
|||
Uses the `strftime` format.
|
||||
- `date_time_format`: [string='%Y-%m-%d_%H-%M-%S'] Format used for the PCB and schematic date when using the file timestamp. Uses the `strftime` format.
|
||||
- `dir`: [string=''] Default pattern for the output directories.
|
||||
- `drc_exclusions_workaround`: [boolean=false] KiCad 6 introduced DRC exclusions. They are stored in the project but ignored by the Python API.
|
||||
This is reported as bug number 11562 (https://gitlab.com/kicad/code/kicad/-/issues/11562).
|
||||
If you really need exclusions enable this option, this will use the GUI version of the DRC (slower).
|
||||
Current KiCad version is 6.0.7 and the bug is still there.
|
||||
- `drill_size_increment`: [number=0.05] This is the difference between drill tools in millimeters.
|
||||
A manufacturer with 0.05 of increment has drills for 0.1, 0.15, 0.2, 0.25, etc..
|
||||
- `edge_connector`: [string='no'] [yes,no,bevelled] Has the PCB edge connectors?
|
||||
|
|
|
|||
|
|
@ -110,6 +110,11 @@ class Globals(FiltersOptions):
|
|||
""" Format used for the PCB and schematic date when using the file timestamp. Uses the `strftime` format """
|
||||
self.dir = ''
|
||||
""" Default pattern for the output directories """
|
||||
self.drc_exclusions_workaround = False
|
||||
""" KiCad 6 introduced DRC exclusions. They are stored in the project but ignored by the Python API.
|
||||
This is reported as bug number 11562 (https://gitlab.com/kicad/code/kicad/-/issues/11562).
|
||||
If you really need exclusions enable this option, this will use the GUI version of the DRC (slower).
|
||||
Current KiCad version is 6.0.7 and the bug is still there """
|
||||
self.drill_size_increment = 0.05
|
||||
""" This is the difference between drill tools in millimeters.
|
||||
A manufacturer with 0.05 of increment has drills for 0.1, 0.15, 0.2, 0.25, etc. """
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ class GS(object):
|
|||
global_cross_no_body = None
|
||||
global_date_format = None
|
||||
global_date_time_format = None
|
||||
global_drc_exclusions_workaround = None
|
||||
global_dir = None
|
||||
global_drill_size_increment = None
|
||||
global_edge_connector = None
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
Dependencies:
|
||||
- from: KiAuto
|
||||
role: mandatory
|
||||
version: 1.4.0
|
||||
version: 2.0.0
|
||||
"""
|
||||
import os
|
||||
from sys import exit
|
||||
|
|
@ -49,6 +49,8 @@ class Run_DRC(BasePreFlight): # noqa: F821
|
|||
cmd = [command, 'run_drc', '-o', output]
|
||||
if GS.filter_file:
|
||||
cmd.extend(['-f', GS.filter_file])
|
||||
if GS.global_drc_exclusions_workaround:
|
||||
cmd.append('-F')
|
||||
if BasePreFlight.get_option('ignore_unconnected'): # noqa: F821
|
||||
cmd.append('-i')
|
||||
cmd.extend([GS.pcb_file, self.expand_dirname(GS.out_dir)])
|
||||
|
|
|
|||
|
|
@ -350,8 +350,8 @@ deps = '{\
|
|||
"mandatory": true,\
|
||||
"output": "run_drc",\
|
||||
"version": [\
|
||||
1,\
|
||||
4,\
|
||||
2,\
|
||||
0,\
|
||||
0\
|
||||
]\
|
||||
},\
|
||||
|
|
|
|||
|
|
@ -0,0 +1,177 @@
|
|||
{
|
||||
"board": {
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.049999999999999996,
|
||||
"copper_line_width": 0.19999999999999998,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.049999999999999996,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": false,
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.09999999999999999,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.09999999999999999,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.762,
|
||||
"height": 1.524,
|
||||
"width": 1.524
|
||||
},
|
||||
"silk_line_width": 0.12,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.15,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"45_degree_only": false,
|
||||
"min_clearance": 0.508
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [
|
||||
"clearance|176385001|79614999|7e023245-2c2b-4e2b-bfb9-5d35176e88f2|666713b0-70f4-42df-8761-f65bc212d03b",
|
||||
"invalid_outline|165100000|80645000|e6d8b5bb-6f41-4222-9a89-b8a6280d0752|00000000-0000-0000-0000-000000000000"
|
||||
],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"copper_edge_clearance": "error",
|
||||
"courtyards_overlap": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint_type_mismatch": "error",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"invalid_outline": "error",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "error",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zone_has_empty_net": "error",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"allow_blind_buried_vias": false,
|
||||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_copper_edge_clearance": 0.01,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.19999999999999998,
|
||||
"min_microvia_drill": 0.09999999999999999,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.19999999999999998,
|
||||
"min_via_annular_width": 0.049999999999999996,
|
||||
"min_via_diameter": 0.39999999999999997,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"track_widths": [],
|
||||
"via_dimensions": [],
|
||||
"zones_allow_external_fillets": false,
|
||||
"zones_use_no_outline": true
|
||||
},
|
||||
"layer_presets": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "fail-project.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12.0,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.25,
|
||||
"via_diameter": 0.8,
|
||||
"via_drill": 0.4,
|
||||
"wire_width": 6.0
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"net_colors": null
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": []
|
||||
},
|
||||
"sheets": [],
|
||||
"text_variables": {}
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ def test_miss_sch(test_dir):
|
|||
ctx = context.TestContext(test_dir, prj, 'pre_and_position')
|
||||
ctx.run(EXIT_BAD_ARGS, extra=['pos_ascii'])
|
||||
assert ctx.search_err('No SCH file found')
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_miss_sch_2(test_dir):
|
||||
|
|
@ -141,7 +141,7 @@ def test_miss_sch_2(test_dir):
|
|||
ctx = context.TestContext(test_dir, prj, 'pre_and_position')
|
||||
ctx.run(NO_SCH_FILE, no_board_file=True, extra=['-e', 'bogus', 'pos_ascii'])
|
||||
assert ctx.search_err('Schematic file not found')
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_miss_pcb(test_dir):
|
||||
|
|
|
|||
|
|
@ -89,14 +89,26 @@ def test_drc_1(test_dir):
|
|||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_drc_filter(test_dir):
|
||||
def test_drc_filter_1(test_dir):
|
||||
""" Test using internal filters """
|
||||
prj = 'fail-project'
|
||||
ctx = context.TestContext(test_dir, prj, 'drc_filter', '')
|
||||
ctx.run()
|
||||
# Check all outputs are there
|
||||
ctx.expect_out_file(prj+'-drc.txt')
|
||||
ctx.expect_out_file('kibot_errors.filter')
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_drc_filter_2(test_dir):
|
||||
""" Test using KiCad 6 exclusions """
|
||||
prj = 'fail-project'
|
||||
ctx = context.TestContext(test_dir, prj, 'drc_filter_k6_exc', '')
|
||||
ctx.run(extra_debug=True)
|
||||
# Check all outputs are there
|
||||
ctx.expect_out_file(prj+'-drc.txt')
|
||||
ctx.expect_out_file('kibot_errors.filter')
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_drc_unco(test_dir):
|
||||
|
|
|
|||
|
|
@ -279,49 +279,49 @@ def test_filter_not_list(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_filter_not_list')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Option .?filters.? must be a list\(dict\) not `dict`")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_filter_no_number_1(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_filter_no_number')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Empty option .?number.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_filter_no_number_2(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_filter_no_number_2')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Missing .?error.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_filter_no_regex_1(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_filter_no_regex')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Empty option .?regex.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_filter_wrong_entry(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_filter_wrong_entry')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Unknown option .?numerito.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_pre_list(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_list')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Incorrect .?preflight.? section")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_pre_unk(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_unk')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Unknown preflight: .?run_drcs.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_type_1(test_dir):
|
||||
|
|
@ -329,7 +329,7 @@ def test_error_wrong_type_1(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_wrong_type_1')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("In preflight 'run_drc': must be boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_type_2(test_dir):
|
||||
|
|
@ -337,7 +337,7 @@ def test_error_wrong_type_2(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_wrong_type_2')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("In preflight 'ignore_unconnected': must be boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_type_3(test_dir):
|
||||
|
|
@ -345,7 +345,7 @@ def test_error_wrong_type_3(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_wrong_type_3')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("In preflight 'run_erc': must be boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_type_4(test_dir):
|
||||
|
|
@ -353,7 +353,7 @@ def test_error_wrong_type_4(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_wrong_type_4')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("In preflight 'update_xml': must be boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_type_5(test_dir):
|
||||
|
|
@ -361,56 +361,56 @@ def test_error_wrong_type_5(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_pre_wrong_type_5')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("In preflight 'check_zone_fills': must be boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_yaml(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_yaml')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Error loading YAML")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_out_not_list(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_out_not_list')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(".?outputs.? must be a list")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_unk_section(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_unk_section')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Unknown section .?bogus.? in config")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_hpgl_pen_num(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_hpgl_pen_num')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err("Option .?pen_number.? outside its range")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_bom_wrong_format(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_bom_wrong_format')
|
||||
ctx.run(EXIT_BAD_CONFIG, no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(), 'bom'+context.KICAD_SCH_EXT)])
|
||||
assert ctx.search_err("Option .?format.? must be any of")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_bom_column(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_bom_column')
|
||||
ctx.run(EXIT_BAD_CONFIG, no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(), 'bom'+context.KICAD_SCH_EXT)])
|
||||
assert ctx.search_err("Invalid column name .?Impossible.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_bom_no_columns(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_bom_column')
|
||||
ctx.run(BOM_ERROR, no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(), 'bom_no_xml'+context.KICAD_SCH_EXT)])
|
||||
assert ctx.search_err("Failed to get the column names")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_bom_no_field(test_dir):
|
||||
|
|
@ -418,28 +418,28 @@ def test_error_bom_no_field(test_dir):
|
|||
ctx.run(EXIT_BAD_CONFIG, no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(),
|
||||
'fail-erc'+context.KICAD_SCH_EXT)])
|
||||
assert ctx.search_err("Missing or empty .?field.?")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_boolean(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_wrong_boolean')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(".?exclude_edge_layer.? must be a boolean")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_gerber_precision(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_gerber_precision')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(".?gerber_precision.? must be 4.5 or 4.6")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_wrong_drill_marks_1(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_wrong_drill_marks')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Option `drill_marks` must be any of \['none', 'small', 'full'\] not `bogus`")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_print_pcb_no_layer(test_dir):
|
||||
|
|
@ -653,28 +653,28 @@ def test_error_wrong_import_type(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_wrong_import_type')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Incorrect `import` section \(must be a list\)")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_import_not_str(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_import_not_str')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"`import` items must be strings")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_import_miss_file(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_import_miss_file')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"missing import file")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_error_import_no_outputs(test_dir):
|
||||
ctx = context.TestContext(test_dir, PRJ, 'error_import_no_outputs')
|
||||
ctx.run()
|
||||
assert ctx.search_err(r"No outputs found in `(.*)drc.kibot.yaml`")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_same_name_1(test_dir):
|
||||
|
|
@ -682,7 +682,7 @@ def test_same_name_1(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_same_name_1')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Output name `position` already defined")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_same_name_2(test_dir):
|
||||
|
|
@ -690,7 +690,7 @@ def test_same_name_2(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_same_name_2')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Output name `position` already defined")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_same_name_3(test_dir):
|
||||
|
|
@ -698,7 +698,7 @@ def test_same_name_3(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_same_name_3')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"Output name `position` already defined, while importing from")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
||||
|
||||
def test_extends_1(test_dir):
|
||||
|
|
@ -706,4 +706,4 @@ def test_extends_1(test_dir):
|
|||
ctx = context.TestContext(test_dir, PRJ, 'error_extends_1')
|
||||
ctx.run(EXIT_BAD_CONFIG)
|
||||
assert ctx.search_err(r"In section 'position_mine' \(position\): Unknown output `position2` in `extends`")
|
||||
ctx.clean_up()
|
||||
ctx.clean_up(keep_project=True)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
globals:
|
||||
drc_exclusions_workaround: true
|
||||
|
||||
preflight:
|
||||
run_drc: true
|
||||
filters:
|
||||
- filter_msg: 'Ignore unconnected pad 2 of C4'
|
||||
error: unconnected_items
|
||||
regexp: 'Pad 2 .* of C4'
|
||||
- filter_msg: 'Ignore missing outline'
|
||||
error: invalid_outline
|
||||
regexp: 'no edges found'
|
||||
Loading…
Reference in New Issue