From 48e5323be08108cc7483162fdd5891c8db8b85f6 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Wed, 29 Jun 2022 13:47:50 -0300 Subject: [PATCH] Added auto-download support for KiAuto. --- README.md | 4 ++-- kibot/misc.py | 4 ++-- kibot/out_any_pcb_print.py | 15 +++++++++------ kibot/out_gencad.py | 14 ++++++++------ kibot/out_netlist.py | 16 +++++++--------- kibot/out_pdf_pcb_print.py | 3 ++- kibot/out_render_3d.py | 16 +++++++++------- kibot/out_step.py | 16 +++++++++------- kibot/out_svg_pcb_print.py | 3 ++- kibot/pre_drc.py | 12 +++++++----- kibot/pre_erc.py | 10 ++++++---- kibot/pre_update_xml.py | 10 ++++++---- src/kibot-check | 20 ++++++++++++++++---- 13 files changed, 85 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 151a4529..4e618e78 100644 --- a/README.md +++ b/README.md @@ -113,10 +113,10 @@ Notes: [**Requests**](https://pypi.org/project/Requests/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-requests) - Mandatory -[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v1.6.13 (tool) (PyPi dependency) +[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v1.6.13 (tool) (PyPi dependency) (Auto-download) - 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` -[**KiCost**](https://github.com/INTI-CMNB/KiCost) v1.1.8 (tool) (Auto-download) +[**KiCost**](https://github.com/hildogjr/KiCost) v1.1.8 (tool) (Auto-download) - Mandatory for `kicost` - Optional to find components costs and specs for `bom` diff --git a/kibot/misc.py b/kibot/misc.py index 50bf3512..9fec4e16 100644 --- a/kibot/misc.py +++ b/kibot/misc.py @@ -366,10 +366,10 @@ class ToolDependency(object): self.roles = roles -def kiauto_dependency(output, version=None): +def kiauto_dependency(output, version=None, command='pcbnew_do', downloader=None): role = None if version is None else ToolDependencyRole(version=version) return ToolDependency(output, 'KiCad Automation tools', URL_EESCHEMA_DO, url_down=URL_EESCHEMA_DO+'/releases', - in_debian=False, pypi_name='kiauto', command='pcbnew_do', roles=role) + in_debian=False, pypi_name='kiauto', command=command, roles=role, downloader=downloader) def git_dependency(output, downloader): diff --git a/kibot/out_any_pcb_print.py b/kibot/out_any_pcb_print.py index 5c257659..afbe84a5 100644 --- a/kibot/out_any_pcb_print.py +++ b/kibot/out_any_pcb_print.py @@ -7,9 +7,10 @@ import os from shutil import rmtree from .pre_base import BasePreFlight from .gs import GS -from .kiplot import check_script, exec_with_retry, add_extra_options -from .misc import CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, PDF_PCB_PRINT, kiauto_dependency +from .kiplot import exec_with_retry, add_extra_options +from .misc import CMD_PCBNEW_PRINT_LAYERS, PDF_PCB_PRINT, kiauto_dependency from .out_base import VariantOptions +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .macros import macros, document, output_class # noqa: F401 from .drill_marks import add_drill_marks, DRILL_MARKS_MAP @@ -20,7 +21,9 @@ logger = log.get_logger() def register_deps(pre): - RegDependency.register(kiauto_dependency(pre+'_pcb_print', (1, 6, 7))) + dep = kiauto_dependency(pre+'_pcb_print', (1, 6, 7), CMD_PCBNEW_PRINT_LAYERS, pytool_downloader) + RegDependency.register(dep) + return dep class Any_PCB_PrintOptions(VariantOptions): @@ -79,9 +82,9 @@ class Any_PCB_PrintOptions(VariantOptions): def run(self, output, svg=False): super().run(self._layers) - check_script(CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, '1.6.7') + command = check_tool(self._dependency, fatal=True) # Output file name - cmd = [CMD_PCBNEW_PRINT_LAYERS, 'export', '--output_name', output] + cmd = [command, 'export', '--output_name', output] if BasePreFlight.get_option('check_zone_fills'): cmd.append('-f') cmd.extend(['--scaling', str(self.scaling), '--pads', str(self.drill_marks)]) @@ -113,7 +116,7 @@ class Any_PCB_PrintOptions(VariantOptions): logger.debug('Removing temporal variant dir `{}`'.format(board_dir)) rmtree(board_dir) if ret: - logger.error(CMD_PCBNEW_PRINT_LAYERS+' returned %d', ret) + logger.error(command+' returned %d', ret) exit(PDF_PCB_PRINT) if video_remove: video_name = os.path.join(self.expand_filename_pcb(GS.out_dir), 'pcbnew_export_screencast.ogv') diff --git a/kibot/out_gencad.py b/kibot/out_gencad.py index 18501a6b..8cefa65f 100644 --- a/kibot/out_gencad.py +++ b/kibot/out_gencad.py @@ -6,14 +6,16 @@ import os from .gs import GS from .optionable import BaseOptions -from .misc import CMD_PCBNEW_GENCAD, URL_PCBNEW_GENCAD, FAILED_EXECUTE, kiauto_dependency -from .kiplot import check_script, exec_with_retry, add_extra_options +from .misc import CMD_PCBNEW_GENCAD, FAILED_EXECUTE, kiauto_dependency +from .kiplot import exec_with_retry, add_extra_options from .registrable import RegDependency +from .dep_downloader import check_tool, pytool_downloader from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger() -RegDependency.register(kiauto_dependency('gencad', (1, 6, 5))) +dep = kiauto_dependency('gencad', (1, 6, 5), CMD_PCBNEW_GENCAD, pytool_downloader) +RegDependency.register(dep) class GenCADOptions(BaseOptions): @@ -39,9 +41,9 @@ class GenCADOptions(BaseOptions): return [self._parent.expand_filename(out_dir, self.output)] def run(self, name): - check_script(CMD_PCBNEW_GENCAD, URL_PCBNEW_GENCAD, '1.6.5') + command = check_tool(dep, fatal=True) # Output file name - cmd = [CMD_PCBNEW_GENCAD, 'export_gencad', '--output_name', os.path.basename(name)] + cmd = [command, 'export_gencad', '--output_name', os.path.basename(name)] if self.flip_bottom_padstacks: cmd.append('--flip_bottom_padstacks') if self.unique_pin_names: @@ -57,7 +59,7 @@ class GenCADOptions(BaseOptions): # Execute it ret = exec_with_retry(cmd) if ret: - logger.error(CMD_PCBNEW_GENCAD+' returned %d', ret) + logger.error(command+' returned %d', ret) exit(FAILED_EXECUTE) if video_remove: video_name = os.path.join(self.expand_filename_pcb(GS.out_dir), 'pcbnew_export_gencad_screencast.ogv') diff --git a/kibot/out_netlist.py b/kibot/out_netlist.py index f9bdda83..5e74272e 100644 --- a/kibot/out_netlist.py +++ b/kibot/out_netlist.py @@ -6,15 +6,16 @@ import os from .gs import GS from .optionable import BaseOptions -from .misc import (CMD_PCBNEW_IPC_NETLIST, URL_PCBNEW_IPC_NETLIST, CMD_EESCHEMA_DO, URL_EESCHEMA_DO, FAILED_EXECUTE, - kiauto_dependency) -from .kiplot import check_script, exec_with_retry, add_extra_options +from .misc import CMD_PCBNEW_IPC_NETLIST, CMD_EESCHEMA_DO, FAILED_EXECUTE, kiauto_dependency +from .kiplot import exec_with_retry, add_extra_options +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger() -RegDependency.register(kiauto_dependency('netlist', (1, 6, 11))) +dep = kiauto_dependency('netlist', (1, 6, 11), CMD_EESCHEMA_DO, pytool_downloader) +RegDependency.register(dep) class NetlistOptions(BaseOptions): @@ -40,20 +41,17 @@ class NetlistOptions(BaseOptions): self._category = 'PCB/fabrication/verification' def run(self, name): + command = check_tool(dep, fatal=True) if self.format == 'ipc': - command = CMD_PCBNEW_IPC_NETLIST - url = URL_PCBNEW_IPC_NETLIST + command = command.replace(CMD_EESCHEMA_DO, CMD_PCBNEW_IPC_NETLIST) subcommand = 'ipc_netlist' extra = ['--output_name', name] file = GS.pcb_file else: - command = CMD_EESCHEMA_DO - url = URL_EESCHEMA_DO subcommand = 'netlist' extra = [] file = GS.sch_file output_dir = os.path.dirname(name) - check_script(command, url, '1.6.11') # Output file name cmd = [command, subcommand]+extra+[file, output_dir] cmd, video_remove = add_extra_options(cmd) diff --git a/kibot/out_pdf_pcb_print.py b/kibot/out_pdf_pcb_print.py index da5c6629..4e40ea27 100644 --- a/kibot/out_pdf_pcb_print.py +++ b/kibot/out_pdf_pcb_print.py @@ -11,7 +11,7 @@ from .layer import Layer from . import log logger = log.get_logger() -register_deps('pdf') +dep = register_deps('pdf') class PDF_PCB_PrintOptions(Any_PCB_PrintOptions): @@ -21,6 +21,7 @@ class PDF_PCB_PrintOptions(Any_PCB_PrintOptions): """ Filename for the output PDF (%i=layers, %x=pdf)""" super().__init__() self._expand_ext = 'pdf' + self._dependency = dep @output_class diff --git a/kibot/out_render_3d.py b/kibot/out_render_3d.py index 4bcf7fdd..51ab5fb0 100644 --- a/kibot/out_render_3d.py +++ b/kibot/out_render_3d.py @@ -6,17 +6,19 @@ # KiCad 6 bug: https://gitlab.com/kicad/code/kicad/-/issues/9890 import os from shutil import rmtree -from .misc import (CMD_PCBNEW_3D, URL_PCBNEW_3D, RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, +from .misc import (CMD_PCBNEW_3D, RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, KICAD_VERSION_6_0_2, MISSING_TOOL, kiauto_dependency) -from .gs import (GS) -from .kiplot import check_script, exec_with_retry, add_extra_options +from .gs import GS +from .kiplot import exec_with_retry, add_extra_options from .out_base_3d import Base3DOptions, Base3D +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger() -RegDependency.register(kiauto_dependency('render_3d', (1, 6, 13))) +dep = kiauto_dependency('render_3d', (1, 6, 13), CMD_PCBNEW_3D, pytool_downloader) +RegDependency.register(dep) class Render3DOptions(Base3DOptions): @@ -143,9 +145,9 @@ class Render3DOptions(Base3DOptions): logger.error("3D Viewer not supported for KiCad 6.0.0/1\n" "Please upgrade KiCad to 6.0.2 or newer") exit(MISSING_TOOL) - check_script(CMD_PCBNEW_3D, URL_PCBNEW_3D, '1.6.13') + command = check_tool(dep, fatal=True) # Base command with overwrite - cmd = [CMD_PCBNEW_3D, '--rec_w', str(self.width+2), '--rec_h', str(self.height+85), + cmd = [command, '--rec_w', str(self.width+2), '--rec_h', str(self.height+85), '3d_view', '--output_name', output] # Add user options if not self.no_virtual: @@ -186,7 +188,7 @@ class Render3DOptions(Base3DOptions): if self._tmp_dir: rmtree(self._tmp_dir) if ret: - logger.error(CMD_PCBNEW_3D+' returned %d', ret) + logger.error(command+' returned %d', ret) exit(RENDER_3D_ERR) if video_remove: video_name = os.path.join(self.expand_filename_pcb(GS.out_dir), 'pcbnew_3d_view_screencast.ogv') diff --git a/kibot/out_step.py b/kibot/out_step.py index 902728b4..ea8dca9e 100644 --- a/kibot/out_step.py +++ b/kibot/out_step.py @@ -6,19 +6,21 @@ # KiCad 6 bug: https://gitlab.com/kicad/code/kicad/-/issues/10075 import os import re -from subprocess import (check_output, STDOUT, CalledProcessError) +from subprocess import check_output, STDOUT, CalledProcessError from shutil import rmtree from .error import KiPlotConfigurationError -from .misc import KICAD2STEP, KICAD2STEP_ERR, URL_PCBNEW_RUN_DRC, kiauto_dependency -from .gs import (GS) +from .misc import KICAD2STEP, KICAD2STEP_ERR, kiauto_dependency +from .gs import GS from .out_base_3d import Base3DOptions, Base3D -from .kiplot import check_script, add_extra_options +from .kiplot import add_extra_options +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger() -RegDependency.register(kiauto_dependency('step', (1, 6, 1))) +dep = kiauto_dependency('step', (1, 6, 1), KICAD2STEP, pytool_downloader) +RegDependency.register(dep) class STEPOptions(Base3DOptions): @@ -53,14 +55,14 @@ class STEPOptions(Base3DOptions): def run(self, output): super().run(output) - check_script(KICAD2STEP, URL_PCBNEW_RUN_DRC, '1.6.1') + command = check_tool(dep, fatal=True) # Make units explicit if self.metric_units: units = 'mm' else: units = 'in' # Base command with overwrite - cmd = [KICAD2STEP, '-o', output, '-f', '-d', os.path.dirname(output)] + cmd = [command, '-o', output, '-f', '-d', os.path.dirname(output)] if GS.debug_level > 0: cmd.append('-vv') else: diff --git a/kibot/out_svg_pcb_print.py b/kibot/out_svg_pcb_print.py index 145cd58a..5aa7f7fa 100644 --- a/kibot/out_svg_pcb_print.py +++ b/kibot/out_svg_pcb_print.py @@ -14,7 +14,7 @@ from .layer import Layer from . import log logger = log.get_logger() -register_deps('svg') +dep = register_deps('svg') class SVG_PCB_PrintOptions(Any_PCB_PrintOptions): @@ -28,6 +28,7 @@ class SVG_PCB_PrintOptions(Any_PCB_PrintOptions): """ Enable workaround for KiCad 5 bug """ super().__init__() self._expand_ext = 'svg' + self._dependency = dep def run(self, output): super().run(output, svg=True) diff --git a/kibot/pre_drc.py b/kibot/pre_drc.py index 8e97df99..ff2fc9db 100644 --- a/kibot/pre_drc.py +++ b/kibot/pre_drc.py @@ -9,13 +9,15 @@ from .macros import macros, pre_class # noqa: F401 from .error import (KiPlotConfigurationError) from .gs import GS from .optionable import Optionable -from .kiplot import check_script, exec_with_retry, load_board, add_extra_options -from .misc import CMD_PCBNEW_RUN_DRC, URL_PCBNEW_RUN_DRC, DRC_ERROR, kiauto_dependency +from .kiplot import exec_with_retry, load_board, add_extra_options +from .misc import CMD_PCBNEW_RUN_DRC, DRC_ERROR, kiauto_dependency +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .log import get_logger logger = get_logger(__name__) -RegDependency.register(kiauto_dependency('run_drc')) +dep = kiauto_dependency('run_drc', (1, 4, 0), CMD_PCBNEW_RUN_DRC, pytool_downloader) +RegDependency.register(dep) @pre_class @@ -39,10 +41,10 @@ class Run_DRC(BasePreFlight): # noqa: F821 return [os.path.abspath(os.path.join(self.expand_dirname(GS.out_dir), name))] def run(self): - check_script(CMD_PCBNEW_RUN_DRC, URL_PCBNEW_RUN_DRC, '1.4.0') + command = check_tool(dep, fatal=True) output = self.get_targets()[0] logger.debug('DRC report: '+output) - cmd = [CMD_PCBNEW_RUN_DRC, 'run_drc', '-o', output] + cmd = [command, 'run_drc', '-o', output] if GS.filter_file: cmd.extend(['-f', GS.filter_file]) if BasePreFlight.get_option('ignore_unconnected'): # noqa: F821 diff --git a/kibot/pre_erc.py b/kibot/pre_erc.py index 0bdd66cf..d3b5d38b 100644 --- a/kibot/pre_erc.py +++ b/kibot/pre_erc.py @@ -8,14 +8,16 @@ from sys import exit from .macros import macros, pre_class # noqa: F401 from .gs import GS from .optionable import Optionable -from .kiplot import check_eeschema_do, exec_with_retry, load_sch, add_extra_options +from .kiplot import exec_with_retry, load_sch, add_extra_options from .error import KiPlotConfigurationError from .misc import CMD_EESCHEMA_DO, ERC_ERROR, kiauto_dependency +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .log import get_logger logger = get_logger(__name__) -RegDependency.register(kiauto_dependency('run_erc')) +dep = kiauto_dependency('run_erc', (1, 5, 4), CMD_EESCHEMA_DO, pytool_downloader) +RegDependency.register(dep) @pre_class @@ -39,12 +41,12 @@ class Run_ERC(BasePreFlight): # noqa: F821 return [os.path.abspath(os.path.join(self.expand_dirname(GS.out_dir), name))] def run(self): - check_eeschema_do() + command = check_tool(dep, fatal=True) # The schematic is loaded only before executing an output related to it. # But here we need data from it. output = self.get_targets()[0] logger.debug('ERC report: '+output) - cmd = [CMD_EESCHEMA_DO, 'run_erc', '-o', output] + cmd = [command, 'run_erc', '-o', output] if BasePreFlight.get_option('erc_warnings'): # noqa: F821 cmd.append('-w') if GS.filter_file: diff --git a/kibot/pre_update_xml.py b/kibot/pre_update_xml.py index a9a922e1..9ae5ef6d 100644 --- a/kibot/pre_update_xml.py +++ b/kibot/pre_update_xml.py @@ -8,13 +8,15 @@ from sys import exit from .macros import macros, pre_class # noqa: F401 from .error import KiPlotConfigurationError from .gs import GS -from .kiplot import check_eeschema_do, exec_with_retry, add_extra_options +from .kiplot import exec_with_retry, add_extra_options from .misc import CMD_EESCHEMA_DO, BOM_ERROR, kiauto_dependency +from .dep_downloader import check_tool, pytool_downloader from .registrable import RegDependency from .log import get_logger logger = get_logger(__name__) -RegDependency.register(kiauto_dependency('update_xml')) +dep = kiauto_dependency('update_xml', (1, 5, 4), CMD_EESCHEMA_DO, pytool_downloader) +RegDependency.register(dep) @pre_class @@ -34,9 +36,9 @@ class Update_XML(BasePreFlight): # noqa: F821 return [GS.sch_no_ext+'.xml'] def run(self): - check_eeschema_do() + command = check_tool(dep, fatal=True) out_dir = self.expand_dirname(GS.out_dir) - cmd = [CMD_EESCHEMA_DO, 'bom_xml', GS.sch_file, out_dir] + cmd = [command, 'bom_xml', GS.sch_file, out_dir] # If we are in verbose mode enable debug in the child cmd, video_remove = add_extra_options(cmd) # While creating the XML we run a BoM plug-in that creates a useless BoM diff --git a/src/kibot-check b/src/kibot-check index 63a5b302..9720778a 100755 --- a/src/kibot-check +++ b/src/kibot-check @@ -255,7 +255,7 @@ deps = '{\ "KiCad Automation tools": {\ "command": "pcbnew_do",\ "deb_package": "kicad automation tools",\ - "downloader": null,\ + "downloader": {},\ "extra_deb": null,\ "help_option": "--version",\ "importance": 110000,\ @@ -345,19 +345,31 @@ deps = '{\ "desc": null,\ "mandatory": true,\ "output": "run_drc",\ - "version": null\ + "version": [\ + 1,\ + 4,\ + 0\ + ]\ },\ {\ "desc": null,\ "mandatory": true,\ "output": "run_erc",\ - "version": null\ + "version": [\ + 1,\ + 5,\ + 4\ + ]\ },\ {\ "desc": null,\ "mandatory": true,\ "output": "update_xml",\ - "version": null\ + "version": [\ + 1,\ + 5,\ + 4\ + ]\ }\ ],\ "url": "https://github.com/INTI-CMNB/KiAuto",\