diff --git a/kibot/kiplot.py b/kibot/kiplot.py index 88376695..e1e13f63 100644 --- a/kibot/kiplot.py +++ b/kibot/kiplot.py @@ -148,8 +148,8 @@ def _run_command(command, change_to): return run(command, check=True, stdout=PIPE, stderr=STDOUT, cwd=change_to) -def run_command(command, change_to=None, just_raise=False, use_x11=False): - logger.debug('Executing: '+GS.pasteable_cmd(command)) +def run_command(command, change_to=None, just_raise=False, use_x11=False, err_msg=None, err_lvl=FAILED_EXECUTE): + logger.debug('- Executing: '+GS.pasteable_cmd(command)) if change_to is not None: logger.debug('- CWD: '+change_to) try: @@ -163,7 +163,9 @@ def run_command(command, change_to=None, just_raise=False, use_x11=False): except CalledProcessError as e: if just_raise: raise - GS.exit_with_error(None, FAILED_EXECUTE, e) + if err_msg is not None: + err_msg = err_msg.format(ret=e.returncode) + GS.exit_with_error(err_msg, err_lvl, e) debug_output(res) return res.stdout.decode().rstrip() diff --git a/kibot/out_compress.py b/kibot/out_compress.py index e82850de..bce5d306 100644 --- a/kibot/out_compress.py +++ b/kibot/out_compress.py @@ -18,12 +18,11 @@ import re import os import glob import sys -from subprocess import check_output, STDOUT, CalledProcessError from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA from tarfile import open as tar_open from collections import OrderedDict from .gs import GS -from .kiplot import config_output, run_output, get_output_targets +from .kiplot import config_output, run_output, get_output_targets, run_command from .misc import WRONG_INSTALL, W_EMPTYZIP, INTERNAL_ERROR from .optionable import Optionable, BaseOptions from .registrable import RegOutput @@ -121,11 +120,7 @@ class CompressOptions(BaseOptions): for fname, dest in files.items(): logger.debugl(2, 'Adding '+fname+' as '+dest) cmd = [command, 'a', '-m5', '-ep', '-ap'+os.path.dirname(dest), output, fname] - logger.debugl(2, '- Running {}'.format(cmd)) - try: - check_output(cmd, stderr=STDOUT) - except CalledProcessError as e: - GS.exit_with_error(f'Failed to invoke rar command, error {e.returncode}', WRONG_INSTALL, e) + run_command(cmd, err_msg='Failed to invoke rar command, error {ret}', err_lvl=WRONG_INSTALL) def solve_extension(self): if self.format == 'ZIP': diff --git a/kibot/out_kibom.py b/kibot/out_kibom.py index a669e0e5..c67d4f5d 100644 --- a/kibot/out_kibom.py +++ b/kibot/out_kibom.py @@ -15,9 +15,9 @@ Dependencies: import os from re import search from tempfile import NamedTemporaryFile -from subprocess import (check_output, STDOUT, CalledProcessError) from .misc import BOM_ERROR, W_EXTNAME from .gs import GS +from .kiplot import run_command from .optionable import Optionable, BaseOptions from .error import KiPlotConfigurationError from .bom.columnlist import ColumnList @@ -213,18 +213,14 @@ class KiBoMConfig(Optionable): with NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f: csv = f.name cmd = [command, '--cfg', config, '-d', os.path.dirname(csv), '-s', ',', xml, csv] - logger.debug('Running: '+str(cmd)) - cmd_output = check_output(cmd, stderr=STDOUT) + run_command(cmd, err_msg='Failed to get the column names for `'+xml+'`, error {ret}', err_lvl=BOM_ERROR) with open(csv, 'rt') as f: columns = f.readline().rstrip().split(',') - except CalledProcessError as e: - GS.exit_with_error(f'Failed to get the column names for `{xml}`, error {e.returncode}', BOM_ERROR, e) finally: if config: os.remove(config) if csv: os.remove(csv) - logger.debug('Output from command:\n'+cmd_output.decode()) return GS.sch.get_field_names(columns) def config(self, parent): @@ -426,20 +422,15 @@ class KiBoMOptions(BaseOptions): if self.variant: cmd.extend(['-r', self.variant]) cmd.extend([prj+'.xml', output]) - logger.debug('Running: '+str(cmd)) - try: - cmd_output = check_output(cmd, stderr=STDOUT) - except CalledProcessError as e: - GS.exit_with_error(f'Failed to create BoM, error {e.returncode}', BOM_ERROR, e) + cmd_output = run_command(cmd, err_msg='Failed to create BoM, error {ret}', err_lvl=BOM_ERROR) if force_output: # When we create the .ini we can control the name. # But when the user does it we can trust the settings. - m = search(r'Saving BOM File: (.*)', cmd_output.decode()) + m = search(r'Saving BOM File: (.*)', cmd_output) if m and m.group(1) != output: cur = m.group(1) logger.debug('Renaming output file: {} -> {}'.format(cur, output)) os.replace(cur, output) - logger.debug('Output from command:\n'+cmd_output.decode()) @output_class diff --git a/kibot/out_kicost.py b/kibot/out_kicost.py index c546dad2..a21e28bd 100644 --- a/kibot/out_kicost.py +++ b/kibot/out_kicost.py @@ -11,7 +11,6 @@ Dependencies: """ import os from os.path import isfile, abspath, join, dirname -from subprocess import check_output, STDOUT, CalledProcessError from tempfile import mkdtemp from shutil import rmtree from .misc import (BOM_ERROR, DISTRIBUTORS, W_UNKDIST, ISO_CURRENCIES, W_UNKCUR, KICOST_SUBMODULE, @@ -22,6 +21,7 @@ from .gs import GS from .out_base import VariantOptions from .macros import macros, document, output_class # noqa: F401 from .fil_base import FieldRename +from .kiplot import run_command from . import log logger = log.get_logger() @@ -213,17 +213,12 @@ class KiCostOptions(VariantOptions): cmd.append('--translate_fields') cmd.extend(self.translate_fields) # Run the command - logger.debug('Running: '+str(cmd)) try: - cmd_output = check_output(cmd, stderr=STDOUT) - cmd_output_dec = cmd_output.decode() - except CalledProcessError as e: - GS.exit_with_error(f'Failed to create costs spreadsheet, error {e.returncode}', BOM_ERROR, e) + run_command(cmd, err_msg='Failed to create costs spreadsheet, error {ret}', err_lvl=BOM_ERROR) finally: if net_dir: logger.debug('Removing temporal variant dir `{}`'.format(net_dir)) rmtree(net_dir) - logger.debug('Output from command:\n'+cmd_output_dec+'\n') @output_class diff --git a/kibot/out_pcb_print.py b/kibot/out_pcb_print.py index ca0da136..8e7ec917 100644 --- a/kibot/out_pcb_print.py +++ b/kibot/out_pcb_print.py @@ -32,7 +32,6 @@ from copy import deepcopy import datetime import re import os -import subprocess import importlib from pcbnew import B_Cu, B_Mask, F_Cu, F_Mask, FromMM, IsCopperLayer, LSET, PLOT_CONTROLLER, PLOT_FORMAT_SVG from shutil import rmtree @@ -52,6 +51,7 @@ from .create_pdf import create_pdf_from_pages from .macros import macros, document, output_class # noqa: F401 from .drill_marks import DRILL_MARKS_MAP, add_drill_marks from .layer import Layer, get_priority +from .kiplot import run_command from . import __version__ from . import log @@ -73,13 +73,7 @@ def pcbdraw_warnings(tag, msg): def _run_command(cmd): - logger.debug('- Executing: '+GS.pasteable_cmd(cmd)) - try: - cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - GS.exit_with_error(None, PDF_PCB_PRINT, e) - if cmd_output.strip(): - logger.debug('- Output from command:\n'+cmd_output.decode()) + run_command(cmd, err_lvl=PDF_PCB_PRINT) def hex_to_rgb(value): diff --git a/kibot/out_pcbdraw.py b/kibot/out_pcbdraw.py index 0877b137..7d34826e 100644 --- a/kibot/out_pcbdraw.py +++ b/kibot/out_pcbdraw.py @@ -19,11 +19,10 @@ Dependencies: role: Automatically adjust SVG margin """ import os -import subprocess from tempfile import NamedTemporaryFile # Here we import the whole module to make monkeypatch work from .error import KiPlotConfigurationError -from .kiplot import load_sch, get_board_comps_data +from .kiplot import load_sch, get_board_comps_data, run_command from .misc import (PCBDRAW_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, W_PCBDRAW) from .gs import GS from .layer import Layer @@ -51,14 +50,7 @@ def _get_tmp_name(ext): def _run_command(cmd): - logger.debug('Executing: '+GS.pasteable_cmd(cmd)) - try: - cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - GS.exit_with_error(None, PCBDRAW_ERR, e) - out = cmd_output.decode() - if out.strip(): - logger.debug('Output from command:\n'+out) + run_command(cmd, err_lvl=PCBDRAW_ERR) class PcbDrawStyle(Optionable): diff --git a/kibot/out_pdfunite.py b/kibot/out_pdfunite.py index b31b6f5e..945d11a7 100644 --- a/kibot/out_pdfunite.py +++ b/kibot/out_pdfunite.py @@ -6,10 +6,9 @@ import re import os import glob -from subprocess import check_output, STDOUT, CalledProcessError from .gs import GS from .error import KiPlotConfigurationError -from .kiplot import config_output, get_output_dir, run_output +from .kiplot import config_output, get_output_dir, run_output, run_command from .misc import MISSING_TOOL, WRONG_INSTALL, WRONG_ARGUMENTS, INTERNAL_ERROR, W_NOTPDF, MISSING_FILES, W_NOMATCH from .optionable import Optionable, BaseOptions from .registrable import RegOutput @@ -106,13 +105,10 @@ class PDFUniteOptions(BaseOptions): def run_external(self, files, output): cmd = ['pdfunite']+files+[output] - logger.debug('Running: {}'.format(cmd)) try: - check_output(cmd, stderr=STDOUT) + run_command(cmd, err_msg='Failed to invoke pdfunite command, error {ret}', err_lvl=WRONG_INSTALL) except FileNotFoundError: GS.exit_with_error('Missing `pdfunite` command, install it (poppler-utils)', MISSING_TOOL) - except CalledProcessError as e: - GS.exit_with_error(f'Failed to invoke pdfunite command, error {e.returncode}', WRONG_INSTALL, e) def run(self, output): # Output file name diff --git a/kibot/out_render_3d.py b/kibot/out_render_3d.py index 74ae3588..d9e1f562 100644 --- a/kibot/out_render_3d.py +++ b/kibot/out_render_3d.py @@ -13,11 +13,11 @@ Dependencies: role: Automatically crop images """ import os -import subprocess from .misc import (RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, KICAD_VERSION_6_0_2, MISSING_TOOL) from .gs import GS from .out_base_3d import Base3DOptionsWithHL, Base3D +from .kiplot import run_command from .macros import macros, document, output_class # noqa: F401 from . import log @@ -25,13 +25,7 @@ logger = log.get_logger() def _run_command(cmd): - logger.debug('- Executing: '+GS.pasteable_cmd(cmd)) - try: - cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - GS.exit_with_error(None, RENDER_3D_ERR, e) - if cmd_output.strip(): - logger.debug('- Output from command:\n'+cmd_output.decode()) + run_command(cmd, err_lvl=RENDER_3D_ERR) class Render3DOptions(Base3DOptionsWithHL): diff --git a/kibot/out_report.py b/kibot/out_report.py index 93bfe7b9..cc602496 100644 --- a/kibot/out_report.py +++ b/kibot/out_report.py @@ -18,15 +18,14 @@ Dependencies: import os import re import pcbnew -from subprocess import check_output, STDOUT, CalledProcessError from .gs import GS -from .misc import (UI_SMD, UI_VIRTUAL, MOD_THROUGH_HOLE, MOD_SMD, MOD_EXCLUDE_FROM_POS_FILES, FAILED_EXECUTE, W_WRONGEXT, +from .misc import (UI_SMD, UI_VIRTUAL, MOD_THROUGH_HOLE, MOD_SMD, MOD_EXCLUDE_FROM_POS_FILES, W_WRONGEXT, W_WRONGOAR, W_ECCLASST, VIATYPE_THROUGH, VIATYPE_BLIND_BURIED, VIATYPE_MICROVIA, W_BLINDVIAS, W_MICROVIAS) from .registrable import RegOutput from .out_base import BaseOptions from .error import KiPlotConfigurationError -from .kiplot import config_output +from .kiplot import config_output, run_command from .dep_downloader import get_dep_data from .macros import macros, document, output_class # noqa: F401 from . import log @@ -850,11 +849,7 @@ class ReportOptions(BaseOptions): if not out.endswith('.'+self.convert_to): logger.warning(W_WRONGEXT+'The conversion tool detects the output format using the extension') cmd = [command, '--from', self.convert_from, resources, fname, '-o', out] - logger.debug('Executing: '+GS.pasteable_cmd(cmd)) - try: - check_output(cmd, stderr=STDOUT) - except CalledProcessError as e: - GS.exit_with_error(None, FAILED_EXECUTE, e) + run_command(cmd) def run(self, fname): self.pcb_material = GS.global_pcb_material