Unified some errors details
- Non-critical errors will stop when using -W - More stack traces on error - More centralized exit
This commit is contained in:
parent
6e914b0959
commit
7ec3a1379c
|
|
@ -226,11 +226,9 @@ def solve_config(a_plot_config, quiet=False):
|
|||
logger.warning(W_VARCFG + 'More than one config file found in current directory.\n'
|
||||
' Using '+plot_config+' if you want to use another use -c option.')
|
||||
else:
|
||||
logger.error('No config file found (*.kibot.yaml), use -c to specify one.')
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error('No config file found (*.kibot.yaml), use -c to specify one.', EXIT_BAD_ARGS)
|
||||
if not os.path.isfile(plot_config):
|
||||
logger.error("Plot config file not found: "+plot_config)
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error("Plot config file not found: "+plot_config, EXIT_BAD_ARGS)
|
||||
logger.debug('Using configuration file: `{}`'.format(plot_config))
|
||||
return plot_config
|
||||
|
||||
|
|
@ -254,11 +252,10 @@ def detect_kicad():
|
|||
try:
|
||||
import pcbnew
|
||||
except ImportError:
|
||||
logger.error("Failed to import pcbnew Python module."
|
||||
" Is KiCad installed?"
|
||||
" Do you need to add it to PYTHONPATH?")
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
sys.exit(NO_PCBNEW_MODULE)
|
||||
GS.exit_with_error(["Failed to import pcbnew Python module."
|
||||
" Is KiCad installed?"
|
||||
" Do you need to add it to PYTHONPATH?",
|
||||
TRY_INSTALL_CHECK], NO_PCBNEW_MODULE)
|
||||
try:
|
||||
GS.kicad_version = pcbnew.GetBuildVersion()
|
||||
except AttributeError:
|
||||
|
|
@ -274,8 +271,7 @@ def detect_kicad():
|
|||
|
||||
m = re.search(r'(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?', GS.kicad_version)
|
||||
if m is None:
|
||||
logger.error("Unable to detect KiCad version, got: `{}`".format(GS.kicad_version))
|
||||
sys.exit(NO_PCBNEW_MODULE)
|
||||
GS.exit_with_error(f"Unable to detect KiCad version, got: `{GS.kicad_version}`", NO_PCBNEW_MODULE)
|
||||
GS.kicad_version_major = int(m.group(1))
|
||||
GS.kicad_version_minor = int(m.group(2))
|
||||
GS.kicad_version_patch = int(m.group(3))
|
||||
|
|
@ -346,8 +342,7 @@ def detect_kicad():
|
|||
def parse_defines(args):
|
||||
for define in args.define:
|
||||
if '=' not in define:
|
||||
logger.error('Malformed `define` option, must be VARIABLE=VALUE ({})'.format(define))
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'Malformed `define` option, must be VARIABLE=VALUE ({define})', EXIT_BAD_ARGS)
|
||||
var = define.split('=')[0]
|
||||
GS.cli_defines[var] = define[len(var)+1:]
|
||||
|
||||
|
|
@ -355,8 +350,7 @@ def parse_defines(args):
|
|||
def parse_global_redef(args):
|
||||
for redef in args.global_redef:
|
||||
if '=' not in redef:
|
||||
logger.error('Malformed global-redef option, must be VARIABLE=VALUE ({})'.format(redef))
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'Malformed global-redef option, must be VARIABLE=VALUE ({redef})', EXIT_BAD_ARGS)
|
||||
var = redef.split('=')[0]
|
||||
GS.cli_global_defs[var] = redef[len(var)+1:]
|
||||
|
||||
|
|
@ -373,8 +367,7 @@ def apply_warning_filter(args):
|
|||
try:
|
||||
log.set_filters([SimpleFilter(int(n)) for n in args.no_warn.split(',')])
|
||||
except ValueError:
|
||||
logger.error('-w/--no-warn must specify a comma separated list of numbers ({})'.format(args.no_warn))
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'-w/--no-warn must specify a comma separated list of numbers ({args.no_warn})', EXIT_BAD_ARGS)
|
||||
|
||||
|
||||
def debug_arguments(args):
|
||||
|
|
@ -437,8 +430,7 @@ def main():
|
|||
try:
|
||||
id = int(args.banner)
|
||||
except ValueError:
|
||||
logger.error('The banner option needs an integer ({})'.format(id))
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'The banner option needs an integer ({id})', EXIT_BAD_ARGS)
|
||||
logger.info(get_banner(id))
|
||||
|
||||
if args.help_outputs or args.help_list_outputs:
|
||||
|
|
@ -479,8 +471,7 @@ def main():
|
|||
if args.example:
|
||||
check_board_file(args.board_file)
|
||||
if args.copy_options and not args.board_file:
|
||||
logger.error('Asked to copy options but no PCB specified.')
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error('Asked to copy options but no PCB specified.', EXIT_BAD_ARGS)
|
||||
create_example(args.board_file, GS.out_dir, args.copy_options, args.copy_and_expand)
|
||||
sys.exit(0)
|
||||
if args.quick_start:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from .csv_writer import write_csv
|
|||
from .html_writer import write_html
|
||||
from .xml_writer import write_xml
|
||||
from .. import log
|
||||
from .. import error
|
||||
|
||||
logger = log.get_logger()
|
||||
|
||||
|
|
@ -49,6 +50,6 @@ def write_bom(filename, ext, groups, headings, cfg):
|
|||
if result:
|
||||
logger.debug("{} Output -> {}".format(ext.upper(), filename))
|
||||
else:
|
||||
logger.error("writing {} output".format(ext.upper()))
|
||||
raise error.KiPlotError(f"Fail writing {ext.upper()} output")
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ def get_prefix_simple(prefix):
|
|||
# Unknown, we shouldn't get here because the regex matched
|
||||
# BUT: I found that sometimes unexpected things happen, like mu matching micro and then we reaching this code
|
||||
# Now is fixed, but I can't be sure some bizarre case is overlooked
|
||||
logger.error('Unknown prefix, please report')
|
||||
logger.non_critical_error('Unknown prefix, please report')
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -722,7 +722,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
|
|||
cfg = BoMOptions object with all the configuration
|
||||
"""
|
||||
if not XLSX_SUPPORT:
|
||||
logger.error('Python xlsxwriter module not installed')
|
||||
logger.non_critical_error('Python xlsxwriter module not installed')
|
||||
return False
|
||||
|
||||
link_datasheet = -1
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import io
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
from sys import exit, maxsize
|
||||
from sys import maxsize
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
|
|
@ -58,9 +58,7 @@ try:
|
|||
import yaml
|
||||
except ImportError:
|
||||
log.init()
|
||||
logger.error('No yaml module for Python, install python3-yaml')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(NO_YAML_MODULE)
|
||||
GS.exit_with_error(['No yaml module for Python, install python3-yaml', TRY_INSTALL_CHECK], NO_YAML_MODULE)
|
||||
|
||||
|
||||
def update_dict(d, u):
|
||||
|
|
@ -650,7 +648,7 @@ class CfgYamlReader(object):
|
|||
for k, v in collected_definitions[-1].items():
|
||||
content, replaced = do_replace(k, v, content, replaced)
|
||||
if depth >= 20:
|
||||
logger.error('Maximum depth of definition replacements reached, loop?')
|
||||
logger.non_critical_error('Maximum depth of definition replacements reached, loop?')
|
||||
if GS.debug_level > 3:
|
||||
logger.debug('YAML after expanding definitions:\n'+content)
|
||||
# Create an stream from the string
|
||||
|
|
@ -817,7 +815,7 @@ def print_output_options(name, cl, indent, context=None, skip_keys=False):
|
|||
entry = ind_base_sp+entry
|
||||
if help is None:
|
||||
help = 'Undocumented'
|
||||
logger.error('Undocumented option: `{}`'.format(k))
|
||||
logger.non_critical_error(f'Undocumented option: `{k}`')
|
||||
lines = help.split('\n')
|
||||
preface = ind_str+entry.format(k)
|
||||
if rst_mode and context:
|
||||
|
|
@ -944,8 +942,7 @@ def print_outputs_help(rst, details=False):
|
|||
|
||||
def print_output_help(name):
|
||||
if not RegOutput.is_registered(name):
|
||||
logger.error('Unknown output type `{}`, try --help-list-outputs'.format(name))
|
||||
exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'Unknown output type `{name}`, try --help-list-outputs', EXIT_BAD_ARGS)
|
||||
print_one_out_help(True, name, RegOutput.get_class_for(name))
|
||||
|
||||
|
||||
|
|
@ -1150,8 +1147,7 @@ def create_example(pcb_file, out_dir, copy_options, copy_expand):
|
|||
os.makedirs(out_dir)
|
||||
fname = os.path.join(out_dir, EXAMPLE_CFG)
|
||||
if os.path.isfile(fname):
|
||||
logger.error(fname+" already exists, won't overwrite")
|
||||
exit(WONT_OVERWRITE)
|
||||
GS.exit_with_error(fname+" already exists, won't overwrite", WONT_OVERWRITE)
|
||||
with open(fname, 'w') as f:
|
||||
logger.info('Creating {} example configuration'.format(fname))
|
||||
f.write("# ATTENTION! THIS ISN'T A FULLY FUNCTIONAL EXAMPLE.\n")
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ def python_downloader(dep):
|
|||
# Check if we have pip and wheel
|
||||
pip_command = check_pip()
|
||||
if pip_command is None:
|
||||
logger.error('No pip command available!')
|
||||
logger.non_critical_error('No pip command available!')
|
||||
return False
|
||||
# Try to pip install it
|
||||
if not pip_install(pip_command, name=dep.pypi_name.lower()):
|
||||
|
|
@ -737,7 +737,7 @@ def try_download_tool_binary(dep):
|
|||
if res:
|
||||
using_downloaded(dep)
|
||||
except Exception as e:
|
||||
logger.error('- Failed to download {}: {}'.format(dep.name, e))
|
||||
logger.non_critical_error(f'- Failed to download {dep.name}: {e}')
|
||||
return res, ver
|
||||
|
||||
|
||||
|
|
@ -799,14 +799,13 @@ def check_tool_python(dep, reload=False):
|
|||
importlib.invalidate_caches()
|
||||
mod = importlib.import_module(dep.module_name)
|
||||
if mod.__file__ is None:
|
||||
logger.error(mod)
|
||||
return None, None
|
||||
res, ver = check_tool_python_version(mod, dep)
|
||||
if res is not None and reload:
|
||||
res = importlib.reload(reload)
|
||||
return res, ver
|
||||
except ModuleNotFoundError:
|
||||
logger.error(f'Pip failed for {dep.module_name}')
|
||||
logger.non_critical_error(f'Pip failed for {dep.module_name}')
|
||||
return None, None
|
||||
|
||||
|
||||
|
|
@ -970,7 +969,7 @@ def register_dep(context, dep):
|
|||
if parent:
|
||||
parent_data = base_deps.get(parent.lower(), None)
|
||||
if parent_data is None:
|
||||
logger.error('{} dependency unkwnown parent {}'.format(context, parent))
|
||||
logger.non_critical_error(f'{context} dependency unkwnown parent {parent}')
|
||||
return
|
||||
new_dep = deepcopy(parent_data)
|
||||
new_dep.update(dep)
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class Spec_to_Field(BaseFilter): # noqa: F821
|
|||
v = self.normalize(v, EI_TYPES[n], c)
|
||||
if not self.compare(cur_val, v):
|
||||
desc = "`{}` vs `{}` collision, `{}` != `{}`".format(d, cur_dist, v, cur_val)
|
||||
logger.error(desc)
|
||||
logger.non_critical_error(desc)
|
||||
|
||||
def filter(self, comp):
|
||||
self.solve_from()
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class Subparts(BaseFilter): # noqa: F821
|
|||
return float(vals[0])/float(vals[1])
|
||||
return float(qty)
|
||||
except ValueError:
|
||||
logger.error('Internal error qty_to_float("{}"), please report'.format(qty))
|
||||
logger.non_critical_error(f'Internal error qty_to_float("{qty}"), please report')
|
||||
|
||||
def do_split(self, comp, max_num_subparts, split_fields):
|
||||
""" Split `comp` according to the detected subparts """
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ def parse_len_str(val):
|
|||
c = int(val[:pos])
|
||||
except ValueError:
|
||||
c = None
|
||||
logger.error('Malformed 3D alias entry: '+val)
|
||||
logger.non_critical_error('Malformed 3D alias entry: '+val)
|
||||
value = val[pos+1:]
|
||||
if c is not None and c != len(value):
|
||||
logger.error('3D alias entry error, expected len {}, but found {}'.format(c, len(value)))
|
||||
logger.non_critical_error(f'3D alias entry error, expected len {c}, but found {len(value)}')
|
||||
return value
|
||||
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ def expand_env(val, env, extra_env, used_extra=None):
|
|||
success = False
|
||||
# Note: We can't expand NET_NAME(n)
|
||||
if var not in reported and not var.startswith('NET_NAME('):
|
||||
logger.error('Unable to expand `{}` in `{}`'.format(var, val))
|
||||
logger.non_critical_error(f'Unable to expand `{var}` in `{val}`')
|
||||
reported.add(var)
|
||||
return val
|
||||
|
||||
|
|
@ -585,7 +585,7 @@ class KiConf(object):
|
|||
logger.warning(W_3DRESVER, 'Unsupported 3D resolver version ({})'.format(head))
|
||||
for r in reader:
|
||||
if len(r) != 3:
|
||||
logger.error("3D resolver doesn't contain three values ({})".format(r))
|
||||
logger.non_critical_error(f"3D resolver doesn't contain three values ({r})")
|
||||
continue
|
||||
name = parse_len_str(r[0])
|
||||
value = parse_len_str(r[1])
|
||||
|
|
@ -607,8 +607,7 @@ class KiConf(object):
|
|||
data[key]['page_layout_descr_file'] = key+'.kicad_wks'
|
||||
return dest
|
||||
else:
|
||||
logger.error('Missing page layout file: '+fname)
|
||||
exit(MISSING_WKS)
|
||||
GS.exit_with_error('Missing page layout file: '+fname, MISSING_WKS)
|
||||
return None
|
||||
|
||||
def fix_page_layout_k6(project, dry):
|
||||
|
|
@ -658,8 +657,7 @@ class KiConf(object):
|
|||
dest = str(order)+'.kicad_wks'
|
||||
order = order+1
|
||||
else:
|
||||
logger.error('Missing page layout file: '+fname)
|
||||
exit(MISSING_WKS)
|
||||
GS.exit_with_error('Missing page layout file: '+fname, MISSING_WKS)
|
||||
else:
|
||||
dest = ''
|
||||
lns[c] = f'PageLayoutDescrFile={dest}\n'
|
||||
|
|
|
|||
|
|
@ -73,14 +73,14 @@ class DCMLineReader(LineReader):
|
|||
try:
|
||||
res = res.decode()
|
||||
except UnicodeDecodeError:
|
||||
logger.error('Invalid UTF-8 sequence at line {} of file `{}`'.format(self.line+1, self.file))
|
||||
logger.non_critical_error(f'Invalid UTF-8 sequence at line {self.line+1} of file `{self.file}`')
|
||||
nres = ''
|
||||
for c in res:
|
||||
if c > 127:
|
||||
c = 32
|
||||
nres += chr(c)
|
||||
res = nres
|
||||
logger.error('Using: '+res.rstrip())
|
||||
logger.non_critical_error('Using: '+res.rstrip())
|
||||
return res
|
||||
|
||||
def get_line(self):
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from .misc import (PLOT_ERROR, CORRUPTED_PCB, EXIT_BAD_ARGS, CORRUPTED_SCH, vers
|
|||
MOD_VIRTUAL, W_PCBNOSCH, W_NONEEDSKIP, W_WRONGCHAR, name2make, W_TIMEOUT, W_KIAUTO, W_VARSCH,
|
||||
NO_SCH_FILE, NO_PCB_FILE, W_VARPCB, NO_YAML_MODULE, WRONG_ARGUMENTS, FAILED_EXECUTE, W_VALMISMATCH,
|
||||
MOD_EXCLUDE_FROM_POS_FILES, MOD_EXCLUDE_FROM_BOM, MOD_BOARD_ONLY, hide_stderr, W_MAXDEPTH)
|
||||
from .error import PlotError, KiPlotConfigurationError, config_error
|
||||
from .error import PlotError, KiPlotConfigurationError, config_error, KiPlotError
|
||||
from .config_reader import CfgYamlReader
|
||||
from .pre_base import BasePreFlight
|
||||
from .dep_downloader import register_deps
|
||||
|
|
@ -46,9 +46,7 @@ try:
|
|||
import yaml
|
||||
except ImportError:
|
||||
log.init()
|
||||
logger.error('No yaml module for Python, install python3-yaml')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(NO_YAML_MODULE)
|
||||
GS.exit_with_error(['No yaml module for Python, install python3-yaml', TRY_INSTALL_CHECK], NO_YAML_MODULE)
|
||||
|
||||
|
||||
def cased_path(path):
|
||||
|
|
@ -61,8 +59,7 @@ def try_register_deps(mod, name):
|
|||
try:
|
||||
data = yaml.safe_load(mod.__doc__)
|
||||
except yaml.YAMLError as e:
|
||||
logger.error('While loading plug-in `{}`:'.format(name))
|
||||
config_error("Error loading YAML "+str(e))
|
||||
config_error([f'While loading plug-in `{name}`:', "Error loading YAML "+str(e)])
|
||||
register_deps(name, data)
|
||||
|
||||
|
||||
|
|
@ -195,8 +192,7 @@ def exec_with_retry(cmd, exit_with=None):
|
|||
logger.warning(W_TIMEOUT+'Time out detected, on slow machines or complex projects try:')
|
||||
logger.warning(W_TIMEOUT+'`kiauto_time_out_scale` and/or `kiauto_wait_start` global options')
|
||||
if exit_with is not None and ret:
|
||||
logger.error(cmd[0]+' returned %d', ret)
|
||||
exit(exit_with)
|
||||
GS.exit_with_error(cmd[0]+' returned '+str(ret), exit_with)
|
||||
return ret
|
||||
|
||||
|
||||
|
|
@ -232,9 +228,7 @@ def load_board(pcb_file=None, forced=False):
|
|||
dr.Update()
|
||||
GS.board = board
|
||||
except OSError as e:
|
||||
logger.error('Error loading PCB file. Corrupted?')
|
||||
logger.error(e)
|
||||
exit(CORRUPTED_PCB)
|
||||
GS.exit_with_error(['Error loading PCB file. Corrupted?', str(e)], CORRUPTED_PCB)
|
||||
assert board is not None
|
||||
logger.debug("Board loaded")
|
||||
return board
|
||||
|
|
@ -425,13 +419,11 @@ def preflight_checks(skip_pre, targets):
|
|||
skip_list = skip_pre.split(',')
|
||||
for skip in skip_list:
|
||||
if skip == 'all':
|
||||
logger.error('All can\'t be part of a list of actions '
|
||||
'to skip. Use `--skip all`')
|
||||
exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error('All can\'t be part of a list of actions '
|
||||
'to skip. Use `--skip all`', EXIT_BAD_ARGS)
|
||||
else:
|
||||
if not BasePreFlight.is_registered(skip):
|
||||
logger.error('Unknown preflight `{}`'.format(skip))
|
||||
exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'Unknown preflight `{skip}`', EXIT_BAD_ARGS)
|
||||
o_pre = BasePreFlight.get_preflight(skip)
|
||||
if not o_pre:
|
||||
logger.warning(W_NONEEDSKIP + '`{}` preflight is not in use, no need to skip'.format(skip))
|
||||
|
|
@ -480,8 +472,7 @@ def config_output(out, dry=False, dont_stop=False):
|
|||
def get_output_targets(output, parent):
|
||||
out = RegOutput.get_output(output)
|
||||
if out is None:
|
||||
logger.error('Unknown output `{}` selected in {}'.format(output, parent))
|
||||
exit(WRONG_ARGUMENTS)
|
||||
GS.exit_with_error(f'Unknown output `{output}` selected in {parent}', WRONG_ARGUMENTS)
|
||||
config_output(out)
|
||||
out_dir = get_output_dir(out.dir, out, dry=True)
|
||||
files_list = out.get_targets(out_dir)
|
||||
|
|
@ -501,7 +492,7 @@ def run_output(out, dont_stop=False):
|
|||
try:
|
||||
out.run(get_output_dir(out.dir, out))
|
||||
out._done = True
|
||||
except PlotError as e:
|
||||
except (PlotError, KiPlotError) as e:
|
||||
logger.error("In output `"+str(out)+"`: "+str(e))
|
||||
if not dont_stop:
|
||||
exit(PLOT_ERROR)
|
||||
|
|
@ -551,12 +542,10 @@ def _generate_outputs(outputs, targets, invert, skip_pre, cli_order, no_priority
|
|||
# Check we got a valid list of outputs
|
||||
unknown = next(filter(lambda x: not RegOutput.is_output_or_group(x), targets), None)
|
||||
if unknown:
|
||||
logger.error('Unknown output/group `{}`'.format(unknown))
|
||||
exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error(f'Unknown output/group `{unknown}`', EXIT_BAD_ARGS)
|
||||
# Check for CLI+invert inconsistency
|
||||
if cli_order and invert:
|
||||
logger.error("CLI order and invert options can't be used simultaneously")
|
||||
exit(EXIT_BAD_ARGS)
|
||||
GS.exit_with_error("CLI order and invert options can't be used simultaneously", EXIT_BAD_ARGS)
|
||||
# Expand groups
|
||||
logger.debug('Outputs before groups expansion: {}'.format(targets))
|
||||
try:
|
||||
|
|
@ -777,10 +766,9 @@ def guess_ki6_sch(schematics):
|
|||
|
||||
|
||||
def avoid_mixing_5_and_6(sch, kicad_sch):
|
||||
logger.error('Found KiCad 5 and KiCad 6+ files, make sure the whole project uses one version')
|
||||
logger.error('KiCad 5: '+os.path.basename(sch))
|
||||
logger.error('KiCad 6+: '+os.path.basename(kicad_sch))
|
||||
exit(EXIT_BAD_CONFIG)
|
||||
GS.exit_with_error(['Found KiCad 5 and KiCad 6+ files, make sure the whole project uses one version',
|
||||
'KiCad 5: '+os.path.basename(sch),
|
||||
'KiCad 6+: '+os.path.basename(kicad_sch)], EXIT_BAD_CONFIG)
|
||||
|
||||
|
||||
def solve_schematic(base_dir, a_schematic=None, a_board_file=None, config=None, sug_e=True):
|
||||
|
|
@ -846,8 +834,7 @@ def solve_schematic(base_dir, a_schematic=None, a_board_file=None, config=None,
|
|||
logger.warning(W_VARSCH + 'More than one SCH file found in `'+base_dir+'`.\n'
|
||||
' Using '+schematic+msg+'.')
|
||||
if schematic and not os.path.isfile(schematic):
|
||||
logger.error("Schematic file not found: "+schematic)
|
||||
exit(NO_SCH_FILE)
|
||||
GS.exit_with_error("Schematic file not found: "+schematic, NO_SCH_FILE)
|
||||
if schematic:
|
||||
schematic = os.path.abspath(schematic)
|
||||
logger.debug('Using schematic: `{}`'.format(schematic))
|
||||
|
|
@ -859,8 +846,7 @@ def solve_schematic(base_dir, a_schematic=None, a_board_file=None, config=None,
|
|||
|
||||
def check_board_file(board_file):
|
||||
if board_file and not os.path.isfile(board_file):
|
||||
logger.error("Board file not found: "+board_file)
|
||||
exit(NO_PCB_FILE)
|
||||
GS.exit_with_error("Board file not found: "+board_file, NO_PCB_FILE)
|
||||
|
||||
|
||||
def solve_board_file(base_dir, a_board_file=None, sug_b=True):
|
||||
|
|
@ -1120,8 +1106,7 @@ def generate_examples(start_dir, dry, types):
|
|||
start_dir = '.'
|
||||
else:
|
||||
if not os.path.isdir(start_dir):
|
||||
logger.error('Invalid dir {} to quick start'.format(start_dir))
|
||||
exit(WRONG_ARGUMENTS)
|
||||
GS.exit_with_error(f'Invalid dir {start_dir} to quick start', WRONG_ARGUMENTS)
|
||||
# Set default global options
|
||||
glb = GS.class_for_global_opts()
|
||||
glb.set_tree({})
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ class MyLogger(logging.Logger):
|
|||
super().warning(buf, stacklevel=2, **kwargs) # pragma: no cover (Py38)
|
||||
else:
|
||||
super().warning(buf, **kwargs)
|
||||
self.check_warn_stop()
|
||||
|
||||
def check_warn_stop(self):
|
||||
if stop_on_warnings:
|
||||
self.error('Warnings treated as errors')
|
||||
sys.exit(WARN_AS_ERROR)
|
||||
|
|
@ -148,6 +151,10 @@ class MyLogger(logging.Logger):
|
|||
filt_msg = ', {} filtered'.format(MyLogger.n_filtered)
|
||||
self.info('Found {} unique warning/s ({} total{})'.format(MyLogger.warn_cnt, MyLogger.warn_tcnt, filt_msg))
|
||||
|
||||
def non_critical_error(self, msg):
|
||||
self.error(msg)
|
||||
self.check_warn_stop()
|
||||
|
||||
def findCaller(self, stack_info=False, stacklevel=1):
|
||||
f = sys._getframe(1)
|
||||
# Skip frames from logging module
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ W_VALMISMATCH = '(W135) '
|
|||
W_BADOFFSET = '(W136) '
|
||||
W_BUG16418 = '(W137) '
|
||||
W_NOTHCMP = '(W138) '
|
||||
W_KEEPTMP = '(W139) '
|
||||
# Somehow arbitrary, the colors are real, but can be different
|
||||
PCB_MAT_COLORS = {'fr1': "937042", 'fr2': "949d70", 'fr3': "adacb4", 'fr4': "332B16", 'fr5': "6cc290"}
|
||||
PCB_FINISH_COLORS = {'hal': "8b898c", 'hasl': "8b898c", 'imag': "8b898c", 'enig': "cfb96e", 'enepig': "cfb96e",
|
||||
|
|
|
|||
|
|
@ -151,9 +151,8 @@ class AnyLayerOptions(VariantOptions):
|
|||
def run(self, output_dir, layers):
|
||||
super().run(output_dir)
|
||||
if GS.ki7 and GS.kicad_version_n < KICAD_VERSION_7_0_1 and not self.exclude_edge_layer:
|
||||
logger.error("Plotting the edge layer is not supported by KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer")
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error("Plotting the edge layer is not supported by KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer", MISSING_TOOL)
|
||||
# Memorize the list of visible layers
|
||||
old_visible = GS.board.GetVisibleLayers()
|
||||
# Apply the variants and filters
|
||||
|
|
|
|||
|
|
@ -70,9 +70,8 @@ class Any_PCB_PrintOptions(VariantOptions):
|
|||
def run(self, output, svg=False):
|
||||
super().run(self._layers)
|
||||
if GS.ki7 and GS.kicad_version_n < KICAD_VERSION_7_0_1 and self.scaling != 0 and self.scaling != 1.0:
|
||||
logger.error("Scaled printing is broken in KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer")
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error("Scaled printing is broken in KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer", MISSING_TOOL)
|
||||
command = self.ensure_tool('KiAuto')
|
||||
# Output file name
|
||||
cmd = [command, 'export', '--output_name', output]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from shutil import rmtree
|
|||
from tempfile import NamedTemporaryFile, mkdtemp
|
||||
from .gs import GS
|
||||
from .kiplot import load_sch, get_board_comps_data
|
||||
from .misc import Rect, W_WRONGPASTE, DISABLE_3D_MODEL_TEXT, W_NOCRTYD, MOD_ALLOW_MISSING_COURTYARD, W_MISSDIR
|
||||
from .misc import Rect, W_WRONGPASTE, DISABLE_3D_MODEL_TEXT, W_NOCRTYD, MOD_ALLOW_MISSING_COURTYARD, W_MISSDIR, W_KEEPTMP
|
||||
if not GS.kicad_version_n:
|
||||
# When running the regression tests we need it
|
||||
from kibot.__main__ import detect_kicad
|
||||
|
|
@ -113,7 +113,7 @@ class BaseOutput(RegOutput):
|
|||
def get_targets(self, out_dir):
|
||||
""" Returns a list of targets generated by this output """
|
||||
if not (hasattr(self, "options") and hasattr(self.options, "get_targets")):
|
||||
logger.error("Output {} doesn't implement get_targets(), please report it".format(self))
|
||||
logger.non_critical_error(f"Output {self} doesn't implement get_targets(), please report it")
|
||||
return []
|
||||
return self.options.get_targets(out_dir)
|
||||
|
||||
|
|
@ -1006,7 +1006,7 @@ class VariantOptions(BaseOptions):
|
|||
except SystemExit:
|
||||
if GS.debug_enabled:
|
||||
if self._files_to_remove:
|
||||
logger.error('Keeping temporal files: '+str(self._files_to_remove))
|
||||
logger.warning(W_KEEPTMP+'Keeping temporal files: '+str(self._files_to_remove))
|
||||
else:
|
||||
self.remove_temporals()
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ class Base3DOptions(VariantOptions):
|
|||
try:
|
||||
replace = download_easyeda_3d_model(lcsc_id, self._tmp_dir, fname)
|
||||
except Exception as e:
|
||||
logger.error(f'Error downloading 3D model for LCSC part {lcsc_id} (model: {model} problem: {e})')
|
||||
logger.non_critical_error(f'Error downloading 3D model for LCSC part {lcsc_id} (model: {model} problem: {e})')
|
||||
replace = None
|
||||
if not replace:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ Dependencies:
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
||||
from .error import KiPlotConfigurationError
|
||||
from .kiplot import get_output_targets, run_output, run_command, register_xmp_import, config_output, configure_and_run
|
||||
|
|
@ -551,13 +550,11 @@ class Blender_ExportOptions(BaseOptions):
|
|||
|
||||
def analyze_errors(self, msg):
|
||||
if 'Traceback ' in msg:
|
||||
logger.error('Error from Blender run:\n'+msg[msg.index('Traceback '):])
|
||||
sys.exit(BLENDER_ERROR)
|
||||
GS.exit_with_error('Error from Blender run:\n'+msg[msg.index('Traceback '):], BLENDER_ERROR)
|
||||
|
||||
def run(self, output):
|
||||
if GS.ki5:
|
||||
logger.error("`blender_export` needs KiCad 6+")
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error("`blender_export` needs KiCad 6+", MISSING_TOOL)
|
||||
pcb3d_file = self.solve_pcb3d()
|
||||
# If no outputs specified just finish
|
||||
# Can be used to export the PCB to Blender
|
||||
|
|
|
|||
|
|
@ -172,8 +172,7 @@ class CompressOptions(BaseOptions):
|
|||
run_output(out)
|
||||
if not os.path.exists(file):
|
||||
# Still missing, something is wrong
|
||||
logger.error('Unable to generate `{}` from {}'.format(file, out))
|
||||
exit(INTERNAL_ERROR)
|
||||
GS.exit_with_error(f'Unable to generate `{file}` from {out}', INTERNAL_ERROR)
|
||||
if os.path.isdir(file):
|
||||
# Popultate output adds the image dirs
|
||||
# Computing its content is complex:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import glob
|
|||
import os
|
||||
import re
|
||||
from shutil import copy2
|
||||
from sys import exit
|
||||
from .error import KiPlotConfigurationError
|
||||
from .gs import GS
|
||||
from .kiplot import config_output, get_output_dir, run_output
|
||||
|
|
@ -106,8 +105,7 @@ class Copy_FilesOptions(Base3DOptions):
|
|||
files_list = out.get_targets(out_dir)
|
||||
logger.debugl(2, '- List of files: {}'.format(files_list))
|
||||
else:
|
||||
logger.error('Unknown output `{}` selected in {}'.format(from_output, self._parent))
|
||||
exit(WRONG_ARGUMENTS)
|
||||
GS.exit_with_error(f'Unknown output `{from_output}` selected in {self._parent}', WRONG_ARGUMENTS)
|
||||
# Check if we must run the output to create the files
|
||||
if not no_out_run:
|
||||
for file in files_list:
|
||||
|
|
@ -118,8 +116,7 @@ class Copy_FilesOptions(Base3DOptions):
|
|||
run_output(out)
|
||||
if not os.path.isfile(file):
|
||||
# Still missing, something is wrong
|
||||
logger.error('Unable to generate `{}` from {}'.format(file, out))
|
||||
exit(INTERNAL_ERROR)
|
||||
GS.exit_with_error(f'Unable to generate `{file}` from {out}', INTERNAL_ERROR)
|
||||
return files_list
|
||||
|
||||
def copy_footprints(self, dest, dry):
|
||||
|
|
|
|||
|
|
@ -542,8 +542,7 @@ class DiffOptions(VariantOptions):
|
|||
run_command(cmd, just_raise=True)
|
||||
except CalledProcessError as e:
|
||||
if e.returncode == 10:
|
||||
logger.error('Diff above the threshold')
|
||||
exit(DIFF_TOO_BIG)
|
||||
GS.exit_with_error('Diff above the threshold', DIFF_TOO_BIG)
|
||||
logger.error('Running {} returned {}'.format(e.cmd, e.returncode))
|
||||
if e.stdout:
|
||||
logger.debug('- Output from command: '+e.stdout.decode())
|
||||
|
|
|
|||
|
|
@ -166,9 +166,8 @@ class KiCostOptions(VariantOptions):
|
|||
# Currently we only support the XML mechanism.
|
||||
netlist = GS.sch_no_ext+'.xml'
|
||||
if not isfile(netlist):
|
||||
logger.error('Missing netlist in XML format `{}`'.format(netlist))
|
||||
logger.error('You can generate it using the `update_xml` preflight')
|
||||
exit(BOM_ERROR)
|
||||
GS.exit_with_error([f'Missing netlist in XML format `{netlist}`',
|
||||
'You can generate it using the `update_xml` preflight'], BOM_ERROR)
|
||||
# Check KiCost is available
|
||||
cmd_kicost = abspath(join(dirname(__file__), KICOST_SUBMODULE))
|
||||
if not isfile(cmd_kicost):
|
||||
|
|
|
|||
|
|
@ -147,9 +147,9 @@ def _run_command(cmd):
|
|||
try:
|
||||
cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error('Failed to run %s, error %d', cmd[0], e.returncode)
|
||||
if e.output:
|
||||
logger.debug('Output from command: '+e.output.decode())
|
||||
logger.non_critical_error(f'Failed to run {cmd[0]}, error {e.returncode}')
|
||||
return False
|
||||
if cmd_output.strip():
|
||||
logger.debug('- Output from command:\n'+cmd_output.decode())
|
||||
|
|
@ -173,7 +173,7 @@ class Navigate_ResultsOptions(BaseOptions):
|
|||
self.link_from_root = ''
|
||||
""" *The name of a file to create at the main output directory linking to the home page """
|
||||
self.skip_not_run = False
|
||||
""" Skip outputs with `run_by_default: false` """
|
||||
# """ Skip outputs with `run_by_default: false` """
|
||||
super().__init__()
|
||||
self._expand_id = 'navigate'
|
||||
self._expand_ext = 'html'
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from .error import KiPlotConfigurationError
|
|||
from .gs import GS
|
||||
from .kiplot import run_command, config_output, register_xmp_import
|
||||
from .layer import Layer
|
||||
from .misc import W_PANELEMPTY, KIKIT_UNIT_ALIASES
|
||||
from .misc import W_PANELEMPTY, KIKIT_UNIT_ALIASES, W_KEEPTMP
|
||||
from .optionable import PanelOptions
|
||||
from .out_base import VariantOptions
|
||||
from .registrable import RegOutput
|
||||
|
|
@ -723,7 +723,7 @@ class PanelizeOptions(VariantOptions):
|
|||
finally:
|
||||
if GS.debug_enabled and not remove_tmps:
|
||||
if self._files_to_remove:
|
||||
logger.error('Keeping temporal files: '+str(self._files_to_remove))
|
||||
logger.warning(W_KEEPTMP+'Keeping temporal files: '+str(self._files_to_remove))
|
||||
else:
|
||||
self.remove_temporals()
|
||||
|
||||
|
|
|
|||
|
|
@ -315,8 +315,7 @@ class PCB2Blender_ToolsOptions(VariantOptions):
|
|||
def run(self, output):
|
||||
super().run(output)
|
||||
if GS.ki5:
|
||||
logger.error("`pcb2blender_tools` needs KiCad 6+")
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error("`pcb2blender_tools` needs KiCad 6+", MISSING_TOOL)
|
||||
dir_name = os.path.dirname(output)
|
||||
self.apply_show_components()
|
||||
self.filter_pcb_components(do_3D=True)
|
||||
|
|
|
|||
|
|
@ -879,8 +879,7 @@ class PCB_PrintOptions(VariantOptions):
|
|||
plotter.svg_precision = self.svg_precision
|
||||
image = plotter.plot()
|
||||
except (RuntimeError, SyntaxError, IOError) as e:
|
||||
logger.error('PcbDraw error: '+str(e))
|
||||
exit(PCBDRAW_ERR)
|
||||
GS.exit_with_error('PcbDraw error: '+str(e), PCBDRAW_ERR)
|
||||
|
||||
if GS.debug_level > 1:
|
||||
# Save the SVG only for debug purposes
|
||||
|
|
|
|||
|
|
@ -496,8 +496,7 @@ class PcbDrawOptions(VariantOptions):
|
|||
# When the PCB can't be loaded we get IOError
|
||||
# When the SVG contains errors we get SyntaxError
|
||||
except (RuntimeError, SyntaxError, IOError) as e:
|
||||
logger.error('PcbDraw error: '+str(e))
|
||||
exit(PCBDRAW_ERR)
|
||||
GS.exit_with_error('PcbDraw error: '+str(e), PCBDRAW_ERR)
|
||||
|
||||
# Save the result
|
||||
logger.debug('Saving output to '+svg_save_output_name)
|
||||
|
|
|
|||
|
|
@ -70,8 +70,7 @@ class PDFUniteOptions(BaseOptions):
|
|||
config_output(out)
|
||||
files_list = out.get_targets(get_output_dir(out.dir, out, dry=True))
|
||||
else:
|
||||
logger.error('Unknown output `{}` selected in {}'.format(f.from_output, self._parent))
|
||||
exit(WRONG_ARGUMENTS)
|
||||
GS.exit_with_error(f'Unknown output `{f.from_output}` selected in {self._parent}', WRONG_ARGUMENTS)
|
||||
if not no_out_run:
|
||||
for file in files_list:
|
||||
if not os.path.isfile(file):
|
||||
|
|
@ -81,8 +80,7 @@ class PDFUniteOptions(BaseOptions):
|
|||
run_output(out)
|
||||
if not os.path.isfile(file):
|
||||
# Still missing, something is wrong
|
||||
logger.error('Unable to generate `{}` from {}'.format(file, out))
|
||||
exit(INTERNAL_ERROR)
|
||||
GS.exit_with_error('Unable to generate `{file}` from {out}', INTERNAL_ERROR)
|
||||
else:
|
||||
out_dir = out_dir_cwd if f.from_cwd else out_dir_default
|
||||
source = f.expand_filename_both(f.source, make_safe=False)
|
||||
|
|
@ -113,8 +111,7 @@ class PDFUniteOptions(BaseOptions):
|
|||
try:
|
||||
check_output(cmd, stderr=STDOUT)
|
||||
except FileNotFoundError:
|
||||
logger.error('Missing `pdfunite` command, install it (poppler-utils)')
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error('Missing `pdfunite` command, install it (poppler-utils)', MISSING_TOOL)
|
||||
except CalledProcessError as e:
|
||||
logger.error('Failed to invoke pdfunite command, error {}'.format(e.returncode))
|
||||
if e.output:
|
||||
|
|
@ -132,8 +129,7 @@ class PDFUniteOptions(BaseOptions):
|
|||
if sig != b'%PDF':
|
||||
logger.warning(W_NOTPDF+'Joining a non PDF file `{}`, will most probably fail'.format(fn))
|
||||
if len(files) < 2:
|
||||
logger.error('At least two files must be joined ({})'.format(files))
|
||||
exit(MISSING_FILES)
|
||||
GS.exit_with_error(f'At least two files must be joined ({files})', MISSING_FILES)
|
||||
logger.debug('Generating `{}` PDF'.format(output))
|
||||
if os.path.isfile(output):
|
||||
os.remove(output)
|
||||
|
|
|
|||
|
|
@ -263,9 +263,8 @@ class Render3DOptions(Base3DOptionsWithHL):
|
|||
def run(self, output):
|
||||
super().run(output)
|
||||
if GS.ki6 and GS.kicad_version_n < KICAD_VERSION_6_0_2:
|
||||
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)
|
||||
GS.exit_with_error("3D Viewer not supported for KiCad 6.0.0/1\n"
|
||||
"Please upgrade KiCad to 6.0.2 or newer", MISSING_TOOL)
|
||||
command = self.ensure_tool('KiAuto')
|
||||
if self.transparent_background:
|
||||
# Use the chroma key color
|
||||
|
|
|
|||
|
|
@ -284,10 +284,10 @@ class ReportOptions(BaseOptions):
|
|||
rep = str(val)
|
||||
line = line.replace('${'+var_ori+'}', rep)
|
||||
else:
|
||||
logger.error('Unable to expand `{}`'.format(var))
|
||||
logger.non_critical_error('Unable to expand `{}`'.format(var))
|
||||
if not self._shown_defined:
|
||||
self._shown_defined = True
|
||||
logger.error('Defined values: {}'.format([v for v in defined.keys() if v[0] != '_']))
|
||||
logger.non_critical_error('Defined values: {}'.format([v for v in defined.keys() if v[0] != '_']))
|
||||
return line
|
||||
|
||||
def context_defined_tracks(self, line):
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
# Project: KiBot (formerly KiPlot)
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from subprocess import run, PIPE
|
||||
from .error import KiPlotConfigurationError
|
||||
from .misc import FAILED_EXECUTE, W_EMPTREP, W_BADCHARS
|
||||
|
|
@ -107,8 +106,7 @@ class Base_Replace(BasePreFlight): # noqa: F821
|
|||
logger.debugl(2, 'Running: {}'.format(cmd))
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
if result.returncode:
|
||||
logger.error('Failed to execute:\n{}\nreturn code {}'.format(r.command, result.returncode))
|
||||
sys.exit(FAILED_EXECUTE)
|
||||
GS.exit_with_error('Failed to execute:\n{r.command}\nreturn code {result.returncode}', FAILED_EXECUTE)
|
||||
if not result.stdout:
|
||||
logger.warning(W_EMPTREP+"Empty value from `{}` skipping it".format(r.command))
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from .gs import GS
|
|||
from .registrable import Registrable
|
||||
from .optionable import Optionable
|
||||
from .error import PlotError, KiPlotConfigurationError
|
||||
from .misc import PLOT_ERROR, EXIT_BAD_CONFIG
|
||||
from .misc import PLOT_ERROR, EXIT_BAD_CONFIG, W_KEEPTMP
|
||||
from .log import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
|
@ -88,11 +88,9 @@ class BasePreFlight(Registrable):
|
|||
logger.debug('Preflight run '+k)
|
||||
v.run()
|
||||
except PlotError as e:
|
||||
logger.error("In preflight `"+str(k)+"`: "+str(e))
|
||||
exit(PLOT_ERROR)
|
||||
GS.exit_with_error("In preflight `"+str(k)+"`: "+str(e), PLOT_ERROR)
|
||||
except KiPlotConfigurationError as e:
|
||||
logger.error("In preflight `"+str(k)+"`: "+str(e))
|
||||
exit(EXIT_BAD_CONFIG)
|
||||
GS.exit_with_error("In preflight `"+str(k)+"`: "+str(e), EXIT_BAD_CONFIG)
|
||||
|
||||
def disable(self):
|
||||
self._enabled = False
|
||||
|
|
@ -185,7 +183,7 @@ class BasePreFlight(Registrable):
|
|||
finally:
|
||||
if GS.debug_enabled and not remove_tmps:
|
||||
if self._files_to_remove:
|
||||
logger.error('Keeping temporal files: '+str(self._files_to_remove))
|
||||
logger.warning(W_KEEPTMP+'Keeping temporal files: '+str(self._files_to_remove))
|
||||
else:
|
||||
self.remove_temporals()
|
||||
if self._files_to_remove:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Dependencies:
|
|||
version: 2.0.0
|
||||
"""
|
||||
import os
|
||||
from sys import exit
|
||||
from .macros import macros, pre_class # noqa: F401
|
||||
from .error import KiPlotConfigurationError
|
||||
from .gs import GS
|
||||
|
|
@ -79,7 +78,7 @@ class Run_DRC(BasePreFlight): # noqa: F821
|
|||
if ret > 127:
|
||||
ret = -(256-ret)
|
||||
if ret < 0:
|
||||
logger.error('DRC violations: %d', -ret)
|
||||
msg = f'DRC violations: {-ret}'
|
||||
else:
|
||||
logger.error('DRC returned %d', ret)
|
||||
exit(DRC_ERROR)
|
||||
msg = f'DRC returned {ret}'
|
||||
GS.exit_with_error(msg, DRC_ERROR)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ Dependencies:
|
|||
"""
|
||||
import os
|
||||
from shutil import move
|
||||
from sys import exit
|
||||
from tempfile import NamedTemporaryFile
|
||||
from .macros import macros, pre_class # noqa: F401
|
||||
from .gs import GS
|
||||
|
|
@ -77,9 +76,9 @@ class Run_ERC(BasePreFlight): # noqa: F821
|
|||
if ret > 127:
|
||||
ret = -(256-ret)
|
||||
if ret < 0:
|
||||
logger.error('ERC errors: %d', -ret)
|
||||
msgs = [f'ERC errors: {-ret}']
|
||||
else:
|
||||
logger.error('ERC returned %d', ret)
|
||||
msgs = [f'ERC returned {ret}']
|
||||
if GS.sch.annotation_error:
|
||||
logger.error('Make sure your schematic is fully annotated')
|
||||
exit(ERC_ERROR)
|
||||
msgs.append('Make sure your schematic is fully annotated')
|
||||
GS.exit_with_error(msgs, ERC_ERROR)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import json
|
|||
import os
|
||||
import re
|
||||
from subprocess import run, PIPE
|
||||
import sys
|
||||
from .error import KiPlotConfigurationError
|
||||
from .misc import FAILED_EXECUTE, W_EMPTREP
|
||||
from .optionable import Optionable
|
||||
|
|
@ -135,12 +134,12 @@ class Set_Text_Variables(BasePreFlight): # noqa: F821
|
|||
logger.debug('Executing: '+GS.pasteable_cmd(command))
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
if result.returncode:
|
||||
logger.error('Failed to execute:\n{}\nreturn code {}'.format(r.command, result.returncode))
|
||||
msgs = [f'Failed to execute:\n{r.command}\nreturn code {result.returncode}']
|
||||
if result.stdout:
|
||||
logger.error('stdout:\n{}'.format(result.stdout))
|
||||
msgs.append(f'stdout:\n{result.stdout}')
|
||||
if result.stderr:
|
||||
logger.error('stderr:\n{}'.format(result.stderr))
|
||||
sys.exit(FAILED_EXECUTE)
|
||||
msgs.append(f'stderr:\n{result.stderr}')
|
||||
GS.exit_with_error(msgs, FAILED_EXECUTE)
|
||||
if not result.stdout:
|
||||
logger.warning(W_EMPTREP+"Empty value from `{}`".format(r.command))
|
||||
text = result.stdout.strip()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ Dependencies:
|
|||
"""
|
||||
from collections import namedtuple
|
||||
import os
|
||||
from sys import exit
|
||||
import xml.etree.ElementTree as ET
|
||||
from .macros import macros, document, pre_class # noqa: F401
|
||||
from .error import KiPlotConfigurationError
|
||||
|
|
@ -160,12 +159,10 @@ class Update_XML(BasePreFlight): # noqa: F821
|
|||
|
||||
def check_pcb_parity(self):
|
||||
if GS.ki5:
|
||||
logger.error('PCB vs schematic parity only available for KiCad 6')
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error('PCB vs schematic parity only available for KiCad 6', MISSING_TOOL)
|
||||
if GS.ki7 and GS.kicad_version_n < KICAD_VERSION_7_0_1:
|
||||
logger.error("Connectivity API is broken on KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer")
|
||||
exit(MISSING_TOOL)
|
||||
GS.exit_with_error("Connectivity API is broken on KiCad 7.0.0\n"
|
||||
"Please upgrade KiCad to 7.0.1 or newer", MISSING_TOOL)
|
||||
fname = GS.sch_no_ext+'.xml'
|
||||
logger.debug('Loading XML: '+fname)
|
||||
try:
|
||||
|
|
@ -208,9 +205,7 @@ class Update_XML(BasePreFlight): # noqa: F821
|
|||
for e in errors:
|
||||
logger.warning(W_PARITY+e)
|
||||
else:
|
||||
for e in errors:
|
||||
logger.error(e)
|
||||
exit(NETLIST_DIFF)
|
||||
GS.exit_with_error(errors, NETLIST_DIFF)
|
||||
|
||||
def run(self):
|
||||
command = self.ensure_tool('KiAuto')
|
||||
|
|
|
|||
Loading…
Reference in New Issue