[Diff/KiRi] Moved common code to a base class

This commit is contained in:
Salvador E. Tropea 2024-01-09 08:14:05 -03:00
parent 6f3d0c87dc
commit 0af0f93a71
3 changed files with 86 additions and 104 deletions

77
kibot/out_any_diff.py Normal file
View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2022-2024 Salvador E. Tropea
# Copyright (c) 2022-2024 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from tempfile import NamedTemporaryFile
from .gs import GS
from .kiplot import run_command
from .out_base import VariantOptions
from .pre_base import BasePreFlight
from .macros import macros, document, output_class # noqa: F401
from . import log
logger = log.get_logger()
class AnyDiffOptions(VariantOptions):
def __init__(self):
with document:
self.zones = 'global'
""" [global,fill,unfill,none] How to handle PCB zones. The default is *global* and means that we
fill zones if the *check_zone_fills* preflight is enabled. The *fill* option always forces
a refill, *unfill* forces a zone removal and *none* lets the zones unchanged.
Be careful with the *keep_generated* option when changing this setting """
super().__init__()
self._expand_id = 'diff'
self._expand_ext = 'pdf'
self._kiri_mode = False
def add_zones_ops(self, cmd):
if self.zones == 'global':
if BasePreFlight.get_option('check_zone_fills'):
cmd.extend(['--zones', 'fill'])
elif self.zones == 'fill':
cmd.extend(['--zones', 'fill'])
elif self.zones == 'unfill':
cmd.extend(['--zones', 'unfill'])
def add_to_cache(self, name, hash):
cmd = [self.command, '--no_reader', '--only_cache', '--old_file_hash', hash, '--cache_dir', self.cache_dir]
if self._kiri_mode:
cmd.append('--kiri_mode')
self.add_zones_ops(cmd)
if self.incl_file:
cmd.extend(['--layers', self.incl_file])
if not hasattr(self, 'only_first_sch_page') or not self.only_first_sch_page:
cmd.append('--all_pages')
if GS.debug_enabled:
cmd.insert(1, '-'+'v'*GS.debug_level)
cmd.extend([name, name])
self.name_used_for_cache = name
run_command(cmd)
def run_git(self, cmd, cwd=None, just_raise=False):
if cwd is None:
cwd = self.repo_dir
return run_command([self.git_command]+cmd, change_to=cwd, just_raise=just_raise)
def git_dirty(self, file=None):
ops = ['status', '--porcelain', '-uno']
if file is not None:
ops.append(file)
return self.run_git(ops)
def remove_git_worktree(self, name):
logger.debug('Removing temporal checkout at '+name)
self.run_git(['worktree', 'remove', '--force', name])
def save_layers_incl(self, layers):
self._solved_layers = layers
logger.debug('Including layers:')
with NamedTemporaryFile(mode='w', suffix='.lst', delete=False) as f:
self.incl_file = f.name
for la in layers:
logger.debug('- {} ({})'.format(la.layer, la.id))
f.write(str(la.id)+'\n')
return self.incl_file

View File

@ -31,9 +31,8 @@ from .gs import GS
from .kiplot import load_any_sch, run_command, config_output, get_output_dir, run_output
from .layer import Layer
from .misc import DIFF_TOO_BIG, FAILED_EXECUTE
from .out_base import VariantOptions
from .pre_base import BasePreFlight
from .registrable import RegOutput
from .out_any_diff import AnyDiffOptions
from .macros import macros, document, output_class # noqa: F401
from . import log
@ -41,7 +40,7 @@ logger = log.get_logger()
STASH_MSG = 'KiBot_Changes_Entry'
class DiffOptions(VariantOptions):
class DiffOptions(AnyDiffOptions):
def __init__(self):
with document:
self.output = GS.def_global_output
@ -109,14 +108,7 @@ class DiffOptions(VariantOptions):
""" Always fail if the old/new file doesn't exist. Currently we don't fail if they are from a repo.
So if you refer to a repo point where the file wasn't created KiBot will use an empty file.
Enabling this option KiBot will report an error """
self.zones = 'global'
""" [global,fill,unfill,none] How to handle PCB zones. The default is *global* and means that we
fill zones if the *check_zone_fills* preflight is enabled. The *fill* option always forces
a refill, *unfill* forces a zone removal and *none* lets the zones unchanged.
Be careful with the cache when changing this setting"""
super().__init__()
self._expand_id = 'diff'
self._expand_ext = 'pdf'
def config(self, parent):
super().config(parent)
@ -147,28 +139,6 @@ class DiffOptions(VariantOptions):
self.h.update(chunk)
return self.h.hexdigest()
def add_zones_ops(self, cmd):
if self.zones == 'global':
if BasePreFlight.get_option('check_zone_fills'):
cmd.extend(['--zones', 'fill'])
elif self.zones == 'fill':
cmd.extend(['--zones', 'fill'])
elif self.zones == 'unfill':
cmd.extend(['--zones', 'unfill'])
def add_to_cache(self, name, hash):
cmd = [self.command, '--no_reader', '--only_cache', '--old_file_hash', hash, '--cache_dir', self.cache_dir]
self.add_zones_ops(cmd)
if self.incl_file:
cmd.extend(['--layers', self.incl_file])
if not self.only_first_sch_page:
cmd.append('--all_pages')
if GS.debug_enabled:
cmd.insert(1, '-'+'v'*GS.debug_level)
cmd.extend([name, name])
self.name_used_for_cache = name
run_command(cmd)
def cache_pcb(self, name, force_exist):
if name:
if not os.path.isfile(name) and not force_exist:
@ -229,11 +199,6 @@ class DiffOptions(VariantOptions):
self.git_hash = 'Current' if not name else 'FILE'
return self.cache_pcb(name, force_exist) if self.pcb else self.cache_sch(name, force_exist)
def run_git(self, cmd, cwd=None, just_raise=False):
if cwd is None:
cwd = self.repo_dir
return run_command([self.git_command]+cmd, change_to=cwd, just_raise=just_raise)
def stash_pop(self, cwd=None):
# We don't know if we stashed anything (push always returns 0)
# So we check that the last stash contains our message
@ -355,9 +320,6 @@ class DiffOptions(VariantOptions):
name += '-dirty'
return '{}({})'.format(self.run_git(['rev-parse', '--short', 'HEAD'], cwd=cwd), name)
def git_dirty(self):
return self.run_git(['status', '--porcelain', '-uno'])
def cache_git_use_stash(self, name):
self.stashed = False
self.checkedout = False
@ -438,10 +400,6 @@ class DiffOptions(VariantOptions):
self.git_hash = self.get_git_point_desc(name_ori, cwd)
return hash
def remove_git_worktree(self, name):
logger.debug('Removing temporal checkout at '+name)
self.run_git(['worktree', 'remove', '--force', name])
@staticmethod
def check_output_type(out, must_be):
if out.type != must_be:
@ -501,16 +459,7 @@ class DiffOptions(VariantOptions):
return self.cache_output(name)
def create_layers_incl(self, layers):
incl_file = None
if self.pcb and not isinstance(layers, type):
layers = Layer.solve(layers)
logger.debug('Including layers:')
with NamedTemporaryFile(mode='w', suffix='.lst', delete=False) as f:
incl_file = f.name
for la in layers:
logger.debug('- {} ({})'.format(la.layer, la.id))
f.write(str(la.id)+'\n')
return incl_file
return self.save_layers_incl(Layer.solve(layers)) if self.pcb and not isinstance(layers, type) else None
def do_compare(self, old, old_type, new, new_type, name, name_ori):
dir_name = os.path.dirname(name)

View File

@ -25,15 +25,14 @@ import pwd
import os
from shutil import copy2, rmtree
from subprocess import CalledProcessError
from tempfile import mkdtemp, NamedTemporaryFile
from tempfile import mkdtemp
from .error import KiPlotConfigurationError
from .gs import GS
from .kicad.color_theme import load_color_theme
from .kiplot import load_any_sch, run_command
from .layer import Layer
from .misc import W_NOTHCMP
from .out_base import VariantOptions
from .pre_base import BasePreFlight
from .out_any_diff import AnyDiffOptions
from .macros import macros, document, output_class # noqa: F401
from . import log
@ -54,7 +53,7 @@ def get_cur_user():
return 'Local user'
class KiRiOptions(VariantOptions):
class KiRiOptions(AnyDiffOptions):
def __init__(self):
with document:
self.color_theme = '_builtin_classic'
@ -70,14 +69,8 @@ class KiRiOptions(VariantOptions):
Note that this can be a revision-range, consult the gitrevisions manual for more information """
self.keep_generated = False
""" *Avoid PCB and SCH images regeneration. Useful for incremental usage """
self.zones = 'global'
""" [global,fill,unfill,none] How to handle PCB zones. The default is *global* and means that we
fill zones if the *check_zone_fills* preflight is enabled. The *fill* option always forces
a refill, *unfill* forces a zone removal and *none* lets the zones unchanged.
Be careful with the *keep_generated* option when changing this setting """
super().__init__()
self._expand_id = 'diff'
self._expand_ext = 'pdf'
self._kiri_mode = True
def config(self, parent):
super().config(parent)
@ -97,56 +90,19 @@ class KiRiOptions(VariantOptions):
files.append(os.path.join(self.cache_dir, HASH_LOCAL))
return files
def add_to_cache(self, name, hash):
cmd = [self.command, '--no_reader', '--only_cache', '--old_file_hash', hash[:7], '--cache_dir', self.cache_dir,
'--kiri_mode', '--all_pages']
if self.zones == 'global':
if BasePreFlight.get_option('check_zone_fills'):
cmd.extend(['--zones', 'fill'])
elif self.zones == 'fill':
cmd.extend(['--zones', 'fill'])
elif self.zones == 'unfill':
cmd.extend(['--zones', 'unfill'])
if self.incl_file:
cmd.extend(['--layers', self.incl_file])
if GS.debug_enabled:
cmd.insert(1, '-'+'v'*GS.debug_level)
cmd.extend([name, name])
self.name_used_for_cache = name
run_command(cmd)
def run_git(self, cmd, cwd=None, just_raise=False):
if cwd is None:
cwd = self.repo_dir
return run_command([self.git_command]+cmd, change_to=cwd, just_raise=just_raise)
def git_dirty(self, file):
return self.run_git(['status', '--porcelain', '-uno', file])
def remove_git_worktree(self, name):
logger.debug('Removing temporal checkout at '+name)
self.run_git(['worktree', 'remove', '--force', name])
def create_layers_incl(self, layers):
self.incl_file = None
if isinstance(layers, type):
self._solved_layers = None
return False
layers = Layer.solve(layers)
self._solved_layers = layers
logger.debug('Including layers:')
with NamedTemporaryFile(mode='w', suffix='.lst', delete=False) as f:
self.incl_file = f.name
for la in layers:
logger.debug('- {} ({})'.format(la.layer, la.id))
f.write(str(la.id)+'\n')
self.save_layers_incl(Layer.solve(layers))
return True
def do_cache(self, name, tmp_wd, hash):
name_copy = self.run_git(['ls-files', '--full-name', name])
name_copy = os.path.join(tmp_wd, name_copy)
logger.debug('- Using temporal copy: '+name_copy)
self.add_to_cache(name_copy, hash)
self.add_to_cache(name_copy, hash[:7])
return name_copy
def save_pcb_layers(self, hash):