Unified the "run_command" mechanism

- Now most code calls kiplot.run_command
This commit is contained in:
Salvador E. Tropea 2024-01-08 11:25:48 -03:00
parent 7c7d3aff0b
commit e64b3864b4
9 changed files with 24 additions and 70 deletions

View File

@ -148,8 +148,8 @@ def _run_command(command, change_to):
return run(command, check=True, stdout=PIPE, stderr=STDOUT, cwd=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): 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)) logger.debug('- Executing: '+GS.pasteable_cmd(command))
if change_to is not None: if change_to is not None:
logger.debug('- CWD: '+change_to) logger.debug('- CWD: '+change_to)
try: try:
@ -163,7 +163,9 @@ def run_command(command, change_to=None, just_raise=False, use_x11=False):
except CalledProcessError as e: except CalledProcessError as e:
if just_raise: if just_raise:
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) debug_output(res)
return res.stdout.decode().rstrip() return res.stdout.decode().rstrip()

View File

@ -18,12 +18,11 @@ import re
import os import os
import glob import glob
import sys import sys
from subprocess import check_output, STDOUT, CalledProcessError
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA
from tarfile import open as tar_open from tarfile import open as tar_open
from collections import OrderedDict from collections import OrderedDict
from .gs import GS 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 .misc import WRONG_INSTALL, W_EMPTYZIP, INTERNAL_ERROR
from .optionable import Optionable, BaseOptions from .optionable import Optionable, BaseOptions
from .registrable import RegOutput from .registrable import RegOutput
@ -121,11 +120,7 @@ class CompressOptions(BaseOptions):
for fname, dest in files.items(): for fname, dest in files.items():
logger.debugl(2, 'Adding '+fname+' as '+dest) logger.debugl(2, 'Adding '+fname+' as '+dest)
cmd = [command, 'a', '-m5', '-ep', '-ap'+os.path.dirname(dest), output, fname] cmd = [command, 'a', '-m5', '-ep', '-ap'+os.path.dirname(dest), output, fname]
logger.debugl(2, '- Running {}'.format(cmd)) run_command(cmd, err_msg='Failed to invoke rar command, error {ret}', err_lvl=WRONG_INSTALL)
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)
def solve_extension(self): def solve_extension(self):
if self.format == 'ZIP': if self.format == 'ZIP':

View File

@ -15,9 +15,9 @@ Dependencies:
import os import os
from re import search from re import search
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from subprocess import (check_output, STDOUT, CalledProcessError)
from .misc import BOM_ERROR, W_EXTNAME from .misc import BOM_ERROR, W_EXTNAME
from .gs import GS from .gs import GS
from .kiplot import run_command
from .optionable import Optionable, BaseOptions from .optionable import Optionable, BaseOptions
from .error import KiPlotConfigurationError from .error import KiPlotConfigurationError
from .bom.columnlist import ColumnList from .bom.columnlist import ColumnList
@ -213,18 +213,14 @@ class KiBoMConfig(Optionable):
with NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f: with NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f:
csv = f.name csv = f.name
cmd = [command, '--cfg', config, '-d', os.path.dirname(csv), '-s', ',', xml, csv] cmd = [command, '--cfg', config, '-d', os.path.dirname(csv), '-s', ',', xml, csv]
logger.debug('Running: '+str(cmd)) run_command(cmd, err_msg='Failed to get the column names for `'+xml+'`, error {ret}', err_lvl=BOM_ERROR)
cmd_output = check_output(cmd, stderr=STDOUT)
with open(csv, 'rt') as f: with open(csv, 'rt') as f:
columns = f.readline().rstrip().split(',') 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: finally:
if config: if config:
os.remove(config) os.remove(config)
if csv: if csv:
os.remove(csv) os.remove(csv)
logger.debug('Output from command:\n'+cmd_output.decode())
return GS.sch.get_field_names(columns) return GS.sch.get_field_names(columns)
def config(self, parent): def config(self, parent):
@ -426,20 +422,15 @@ class KiBoMOptions(BaseOptions):
if self.variant: if self.variant:
cmd.extend(['-r', self.variant]) cmd.extend(['-r', self.variant])
cmd.extend([prj+'.xml', output]) cmd.extend([prj+'.xml', output])
logger.debug('Running: '+str(cmd)) cmd_output = run_command(cmd, err_msg='Failed to create BoM, error {ret}', err_lvl=BOM_ERROR)
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)
if force_output: if force_output:
# When we create the .ini we can control the name. # When we create the .ini we can control the name.
# But when the user does it we can trust the settings. # 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: if m and m.group(1) != output:
cur = m.group(1) cur = m.group(1)
logger.debug('Renaming output file: {} -> {}'.format(cur, output)) logger.debug('Renaming output file: {} -> {}'.format(cur, output))
os.replace(cur, output) os.replace(cur, output)
logger.debug('Output from command:\n'+cmd_output.decode())
@output_class @output_class

View File

@ -11,7 +11,6 @@ Dependencies:
""" """
import os import os
from os.path import isfile, abspath, join, dirname from os.path import isfile, abspath, join, dirname
from subprocess import check_output, STDOUT, CalledProcessError
from tempfile import mkdtemp from tempfile import mkdtemp
from shutil import rmtree from shutil import rmtree
from .misc import (BOM_ERROR, DISTRIBUTORS, W_UNKDIST, ISO_CURRENCIES, W_UNKCUR, KICOST_SUBMODULE, 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 .out_base import VariantOptions
from .macros import macros, document, output_class # noqa: F401 from .macros import macros, document, output_class # noqa: F401
from .fil_base import FieldRename from .fil_base import FieldRename
from .kiplot import run_command
from . import log from . import log
logger = log.get_logger() logger = log.get_logger()
@ -213,17 +213,12 @@ class KiCostOptions(VariantOptions):
cmd.append('--translate_fields') cmd.append('--translate_fields')
cmd.extend(self.translate_fields) cmd.extend(self.translate_fields)
# Run the command # Run the command
logger.debug('Running: '+str(cmd))
try: try:
cmd_output = check_output(cmd, stderr=STDOUT) run_command(cmd, err_msg='Failed to create costs spreadsheet, error {ret}', err_lvl=BOM_ERROR)
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)
finally: finally:
if net_dir: if net_dir:
logger.debug('Removing temporal variant dir `{}`'.format(net_dir)) logger.debug('Removing temporal variant dir `{}`'.format(net_dir))
rmtree(net_dir) rmtree(net_dir)
logger.debug('Output from command:\n'+cmd_output_dec+'\n')
@output_class @output_class

View File

@ -32,7 +32,6 @@ from copy import deepcopy
import datetime import datetime
import re import re
import os import os
import subprocess
import importlib import importlib
from pcbnew import B_Cu, B_Mask, F_Cu, F_Mask, FromMM, IsCopperLayer, LSET, PLOT_CONTROLLER, PLOT_FORMAT_SVG from pcbnew import B_Cu, B_Mask, F_Cu, F_Mask, FromMM, IsCopperLayer, LSET, PLOT_CONTROLLER, PLOT_FORMAT_SVG
from shutil import rmtree 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 .macros import macros, document, output_class # noqa: F401
from .drill_marks import DRILL_MARKS_MAP, add_drill_marks from .drill_marks import DRILL_MARKS_MAP, add_drill_marks
from .layer import Layer, get_priority from .layer import Layer, get_priority
from .kiplot import run_command
from . import __version__ from . import __version__
from . import log from . import log
@ -73,13 +73,7 @@ def pcbdraw_warnings(tag, msg):
def _run_command(cmd): def _run_command(cmd):
logger.debug('- Executing: '+GS.pasteable_cmd(cmd)) run_command(cmd, err_lvl=PDF_PCB_PRINT)
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())
def hex_to_rgb(value): def hex_to_rgb(value):

View File

@ -19,11 +19,10 @@ Dependencies:
role: Automatically adjust SVG margin role: Automatically adjust SVG margin
""" """
import os import os
import subprocess
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
# Here we import the whole module to make monkeypatch work # Here we import the whole module to make monkeypatch work
from .error import KiPlotConfigurationError 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 .misc import (PCBDRAW_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, W_PCBDRAW)
from .gs import GS from .gs import GS
from .layer import Layer from .layer import Layer
@ -51,14 +50,7 @@ def _get_tmp_name(ext):
def _run_command(cmd): def _run_command(cmd):
logger.debug('Executing: '+GS.pasteable_cmd(cmd)) run_command(cmd, err_lvl=PCBDRAW_ERR)
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)
class PcbDrawStyle(Optionable): class PcbDrawStyle(Optionable):

View File

@ -6,10 +6,9 @@
import re import re
import os import os
import glob import glob
from subprocess import check_output, STDOUT, CalledProcessError
from .gs import GS from .gs import GS
from .error import KiPlotConfigurationError 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 .misc import MISSING_TOOL, WRONG_INSTALL, WRONG_ARGUMENTS, INTERNAL_ERROR, W_NOTPDF, MISSING_FILES, W_NOMATCH
from .optionable import Optionable, BaseOptions from .optionable import Optionable, BaseOptions
from .registrable import RegOutput from .registrable import RegOutput
@ -106,13 +105,10 @@ class PDFUniteOptions(BaseOptions):
def run_external(self, files, output): def run_external(self, files, output):
cmd = ['pdfunite']+files+[output] cmd = ['pdfunite']+files+[output]
logger.debug('Running: {}'.format(cmd))
try: try:
check_output(cmd, stderr=STDOUT) run_command(cmd, err_msg='Failed to invoke pdfunite command, error {ret}', err_lvl=WRONG_INSTALL)
except FileNotFoundError: except FileNotFoundError:
GS.exit_with_error('Missing `pdfunite` command, install it (poppler-utils)', MISSING_TOOL) 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): def run(self, output):
# Output file name # Output file name

View File

@ -13,11 +13,11 @@ Dependencies:
role: Automatically crop images role: Automatically crop images
""" """
import os import os
import subprocess
from .misc import (RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, from .misc import (RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS,
KICAD_VERSION_6_0_2, MISSING_TOOL) KICAD_VERSION_6_0_2, MISSING_TOOL)
from .gs import GS from .gs import GS
from .out_base_3d import Base3DOptionsWithHL, Base3D from .out_base_3d import Base3DOptionsWithHL, Base3D
from .kiplot import run_command
from .macros import macros, document, output_class # noqa: F401 from .macros import macros, document, output_class # noqa: F401
from . import log from . import log
@ -25,13 +25,7 @@ logger = log.get_logger()
def _run_command(cmd): def _run_command(cmd):
logger.debug('- Executing: '+GS.pasteable_cmd(cmd)) run_command(cmd, err_lvl=RENDER_3D_ERR)
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())
class Render3DOptions(Base3DOptionsWithHL): class Render3DOptions(Base3DOptionsWithHL):

View File

@ -18,15 +18,14 @@ Dependencies:
import os import os
import re import re
import pcbnew import pcbnew
from subprocess import check_output, STDOUT, CalledProcessError
from .gs import GS 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) W_WRONGOAR, W_ECCLASST, VIATYPE_THROUGH, VIATYPE_BLIND_BURIED, VIATYPE_MICROVIA, W_BLINDVIAS, W_MICROVIAS)
from .registrable import RegOutput from .registrable import RegOutput
from .out_base import BaseOptions from .out_base import BaseOptions
from .error import KiPlotConfigurationError from .error import KiPlotConfigurationError
from .kiplot import config_output from .kiplot import config_output, run_command
from .dep_downloader import get_dep_data from .dep_downloader import get_dep_data
from .macros import macros, document, output_class # noqa: F401 from .macros import macros, document, output_class # noqa: F401
from . import log from . import log
@ -850,11 +849,7 @@ class ReportOptions(BaseOptions):
if not out.endswith('.'+self.convert_to): if not out.endswith('.'+self.convert_to):
logger.warning(W_WRONGEXT+'The conversion tool detects the output format using the extension') logger.warning(W_WRONGEXT+'The conversion tool detects the output format using the extension')
cmd = [command, '--from', self.convert_from, resources, fname, '-o', out] cmd = [command, '--from', self.convert_from, resources, fname, '-o', out]
logger.debug('Executing: '+GS.pasteable_cmd(cmd)) run_command(cmd)
try:
check_output(cmd, stderr=STDOUT)
except CalledProcessError as e:
GS.exit_with_error(None, FAILED_EXECUTE, e)
def run(self, fname): def run(self, fname):
self.pcb_material = GS.global_pcb_material self.pcb_material = GS.global_pcb_material