parent
70a2788df0
commit
9a70f2e141
|
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Added
|
||||
- New outputs:
|
||||
- PCB_Variant: saves a PCB with filters and variants applied.
|
||||
- File_Copy: used to copy files to the output directory. (#279)
|
||||
- Support for Eurocircuits drill adjust to fix small OARs.
|
||||
Option `eurocircuits_reduce_holes`. (#227)
|
||||
- Diff: mechanism to compare using a variant (See #278)
|
||||
|
|
|
|||
35
README.md
35
README.md
|
|
@ -1486,6 +1486,41 @@ Notes:
|
|||
Internally we use 10 for low priority, 90 for high priority and 50 for most outputs.
|
||||
- `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested.
|
||||
|
||||
* Files copier
|
||||
* Type: `copy_files`
|
||||
* Description: Used to copy files to the output directory.
|
||||
Useful when an external tool is used to compress the output directory.
|
||||
Note that you can use the `compress` output to create archives
|
||||
* Valid keys:
|
||||
- **`comment`**: [string=''] A comment for documentation purposes.
|
||||
- **`dir`**: [string='./'] Output directory for the generated files.
|
||||
If it starts with `+` the rest is concatenated to the default dir.
|
||||
- **`name`**: [string=''] Used to identify this particular output definition.
|
||||
- **`options`**: [dict] Options for the `copy_files` output.
|
||||
* Valid keys:
|
||||
- **`files`**: [list(dict)] Which files will be included.
|
||||
* Valid keys:
|
||||
- **`from_output`**: [string=''] Collect files from the selected output.
|
||||
When used the `source` option is ignored.
|
||||
- **`source`**: [string='*'] File names to add, wildcards allowed. Use ** for recursive match.
|
||||
By default this pattern is applied to the current working dir.
|
||||
See the `from_outdir` option.
|
||||
- `dest`: [string=''] Destination directory inside the output dir, empty means the same of the file.
|
||||
- `filter`: [string='.*'] A regular expression that source files must match.
|
||||
- `from_outdir`: [boolean=false] Use the output dir specified with `-d` command line option, not the working dir.
|
||||
- `follow_links`: [boolean=true] Store the file pointed by symlinks, not the symlink.
|
||||
- `link_no_copy`: [boolean=false] Create symlinks instead of copying files.
|
||||
- `category`: [string|list(string)=''] The category for this output. If not specified an internally defined category is used.
|
||||
Categories looks like file system paths, i.e. PCB/fabrication/gerber.
|
||||
- `disable_run_by_default`: [string|boolean] Use it to disable the `run_by_default` status of other output.
|
||||
Useful when this output extends another and you don't want to generate the original.
|
||||
Use the boolean true value to disable the output you are extending.
|
||||
- `extends`: [string=''] Copy the `options` section from the indicated output.
|
||||
- `output_id`: [string=''] Text to use for the %I expansion content. To differentiate variations of this output.
|
||||
- `priority`: [number=11] [0,100] Priority for this output. High priority outputs are created first.
|
||||
Internally we use 10 for low priority, 90 for high priority and 50 for most outputs.
|
||||
- `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested.
|
||||
|
||||
* Diff
|
||||
* Type: `diff`
|
||||
* Description: Generates a PDF with the differences between two PCBs or schematics.
|
||||
|
|
|
|||
|
|
@ -409,6 +409,33 @@ outputs:
|
|||
# [string='%f-%i%I%v.%x'] Name for the generated archive (%i=name of the output %x=according to format). Affected by global options
|
||||
output: '%f-%i%I%v.%x'
|
||||
# `remove_files` is an alias for `move_files`
|
||||
# Files copier:
|
||||
# Useful when an external tool is used to compress the output directory.
|
||||
# Note that you can use the `compress` output to create archives
|
||||
- name: 'copy_files_example'
|
||||
comment: 'Used to copy files to the output directory.'
|
||||
type: 'copy_files'
|
||||
dir: 'Example/copy_files_dir'
|
||||
options:
|
||||
# [list(dict)] Which files will be included
|
||||
files:
|
||||
# [string=''] Destination directory inside the output dir, empty means the same of the file
|
||||
- dest: ''
|
||||
# [string='.*'] A regular expression that source files must match
|
||||
filter: '.*'
|
||||
# [boolean=false] Use the output dir specified with `-d` command line option, not the working dir
|
||||
from_outdir: false
|
||||
# [string=''] Collect files from the selected output.
|
||||
# When used the `source` option is ignored
|
||||
from_output: ''
|
||||
# [string='*'] File names to add, wildcards allowed. Use ** for recursive match.
|
||||
# By default this pattern is applied to the current working dir.
|
||||
# See the `from_outdir` option
|
||||
source: '*'
|
||||
# [boolean=true] Store the file pointed by symlinks, not the symlink
|
||||
follow_links: true
|
||||
# [boolean=false] Create symlinks instead of copying files
|
||||
link_no_copy: false
|
||||
# Diff:
|
||||
# Recursive git submodules aren't supported (submodules inside submodules)
|
||||
- name: 'diff_example'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2022 Salvador E. Tropea
|
||||
# Copyright (c) 2022 Instituto Nacional de Tecnología Industrial
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
from collections import OrderedDict
|
||||
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
|
||||
from .misc import WRONG_ARGUMENTS, INTERNAL_ERROR
|
||||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
|
||||
|
||||
class FilesList(Optionable):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
with document:
|
||||
self.source = '*'
|
||||
""" *File names to add, wildcards allowed. Use ** for recursive match.
|
||||
By default this pattern is applied to the current working dir.
|
||||
See the `from_outdir` option """
|
||||
self.from_outdir = False
|
||||
""" Use the output dir specified with `-d` command line option, not the working dir """
|
||||
self.from_output = ''
|
||||
""" *Collect files from the selected output.
|
||||
When used the `source` option is ignored """
|
||||
self.filter = '.*'
|
||||
""" A regular expression that source files must match """
|
||||
self.dest = ''
|
||||
""" Destination directory inside the output dir, empty means the same of the file """
|
||||
|
||||
|
||||
class Copy_FilesOptions(BaseOptions):
|
||||
def __init__(self):
|
||||
with document:
|
||||
self.files = FilesList
|
||||
""" *[list(dict)] Which files will be included """
|
||||
self.follow_links = True
|
||||
""" Store the file pointed by symlinks, not the symlink """
|
||||
self.link_no_copy = False
|
||||
""" Create symlinks instead of copying files """
|
||||
super().__init__()
|
||||
self._expand_id = 'copy'
|
||||
self._expand_ext = 'files'
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if isinstance(self.files, type):
|
||||
KiPlotConfigurationError('No files provided')
|
||||
|
||||
def get_files(self, no_out_run=False):
|
||||
files = OrderedDict()
|
||||
src_dir_cwd = os.getcwd()
|
||||
src_dir_outdir = self.expand_filename_sch(GS.out_dir)
|
||||
for f in self.files:
|
||||
src_dir = src_dir_outdir if f.from_outdir else src_dir_cwd
|
||||
# Get the list of candidates
|
||||
files_list = None
|
||||
if f.from_output:
|
||||
logger.debugl(2, '- From output `{}`'.format(f.from_output))
|
||||
out = RegOutput.get_output(f.from_output)
|
||||
if out is not None:
|
||||
config_output(out)
|
||||
out_dir = get_output_dir(out.dir, out, dry=True)
|
||||
files_list = out.get_targets(out_dir)
|
||||
logger.debugl(2, '- List of files: {}'.format(files_list))
|
||||
else:
|
||||
logger.error('Unknown output `{}` selected in {}'.format(f.from_output, self._parent))
|
||||
exit(WRONG_ARGUMENTS)
|
||||
# Check if we must run the output to create the files
|
||||
if not no_out_run:
|
||||
for file in files_list:
|
||||
if not os.path.isfile(file):
|
||||
# The target doesn't exist
|
||||
if not out._done:
|
||||
# The output wasn't created in this run, try running it
|
||||
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)
|
||||
else:
|
||||
source = f.expand_filename_both(f.source, make_safe=False)
|
||||
files_list = glob.iglob(os.path.join(src_dir, source), recursive=True)
|
||||
if GS.debug_level > 1:
|
||||
files_list = list(files_list)
|
||||
logger.debug('- Pattern {} list of files: {}'.format(source, files_list))
|
||||
# Filter and adapt them
|
||||
for fname in filter(re.compile(f.filter).match, files_list):
|
||||
fname_real = os.path.realpath(fname) if self.follow_links else os.path.abspath(fname)
|
||||
# Compute the destination directory
|
||||
dest = fname
|
||||
if f.dest:
|
||||
dest = os.path.join(f.dest, os.path.basename(fname))
|
||||
else:
|
||||
dest = os.path.relpath(dest, src_dir)
|
||||
files[fname_real] = dest
|
||||
return files
|
||||
|
||||
def get_targets(self, out_dir):
|
||||
files = self.get_files(no_out_run=True)
|
||||
return sorted([os.path.join(out_dir, v) for v in files.values()])
|
||||
|
||||
def get_dependencies(self):
|
||||
files = self.get_files(no_out_run=True)
|
||||
return files.keys()
|
||||
|
||||
def run(self, output):
|
||||
# Output file name
|
||||
logger.debug('Collecting files')
|
||||
# Collect the files
|
||||
files = self.get_files()
|
||||
logger.debug('Copying files')
|
||||
output += os.path.sep
|
||||
for k, v in files.items():
|
||||
src = k
|
||||
dest = os.path.join(output, v)
|
||||
dest_dir = os.path.dirname(dest)
|
||||
if not os.path.isdir(dest_dir):
|
||||
os.makedirs(dest_dir)
|
||||
logger.debug('- {} -> {}'.format(src, dest))
|
||||
if os.path.isfile(dest) or os.path.islink(dest):
|
||||
os.remove(dest)
|
||||
if self.link_no_copy:
|
||||
os.symlink(os.path.relpath(src, os.path.dirname(dest)), dest)
|
||||
else:
|
||||
copy2(src, dest)
|
||||
|
||||
|
||||
@output_class
|
||||
class Copy_Files(BaseOutput): # noqa: F821
|
||||
""" Files copier
|
||||
Used to copy files to the output directory.
|
||||
Useful when an external tool is used to compress the output directory.
|
||||
Note that you can use the `compress` output to create archives """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Make it low priority so it gets created after all the other outputs
|
||||
self.priority = 11
|
||||
with document:
|
||||
self.options = Copy_FilesOptions
|
||||
""" *[dict] Options for the `copy_files` output """
|
||||
self._none_related = True
|
||||
# The help is inherited and already mentions the default priority
|
||||
self.fix_priority_help()
|
||||
|
||||
def get_dependencies(self):
|
||||
return self.options.get_dependencies()
|
||||
|
||||
def run(self, output_dir):
|
||||
# No output member, just a dir
|
||||
self.options.run(output_dir)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: result
|
||||
comment: Test tarball compress
|
||||
type: copy_files
|
||||
dir: juan
|
||||
options:
|
||||
files:
|
||||
- source: tests/board_samples/kicad_5/%f.*
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
- source: tests/board_samples/kicad_5/deeper.sch
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
- source: tests/board_samples/kicad_5/sub-sheet.sch
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: result
|
||||
type: copy_files
|
||||
dir: 'test.%x'
|
||||
options:
|
||||
# link_no_copy: true
|
||||
files:
|
||||
- source: tests/board_samples/kicad_5/test_v5.*
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
- source: tests/board_samples/kicad_5/deeper.sch
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
- source: tests/board_samples/kicad_5/sub-sheet.sch
|
||||
#from_cwd: true
|
||||
dest: source
|
||||
Loading…
Reference in New Issue