Added `kibot-check` tool to check the installation
This commit is contained in:
parent
5bcedf4c7a
commit
fb082fcbb3
|
|
@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- `kibot-check` tool to check the installation
|
||||
- New outputs:
|
||||
- KiCad netlist generation
|
||||
- IPC-D-356 netlist generation (#197)
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -93,14 +93,15 @@ You can also run KiBot using docker images in a CI/CD environment like GitHub or
|
|||
Notes:
|
||||
- When installing from the Debian repo you don't need to worry about dependencies, just pay attention to *recommended* and *suggested* packages.
|
||||
- When installing using `pip` the dependencies marked as **PyPi dependency** will be automatically installed.
|
||||
- The `kibot-check` tool can help you to know which dependencies are missing.
|
||||
|
||||
[**distutils**](https://pypi.org/project/distutils/) (python module) [Debian](https://packages.debian.org/bullseye/python3-distutils)
|
||||
[**Distutils**](https://pypi.org/project/Distutils/) (python module) [Debian](https://packages.debian.org/bullseye/python3-distutils)
|
||||
- Mandatory
|
||||
|
||||
[**PyYAML**](https://pypi.org/project/PyYAML/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-yaml)
|
||||
- Mandatory
|
||||
|
||||
[**requests**](https://pypi.org/project/requests/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-requests)
|
||||
[**Requests**](https://pypi.org/project/Requests/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-requests)
|
||||
- Mandatory
|
||||
|
||||
[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v1.6.11 (tool) (PyPi dependency)
|
||||
|
|
@ -110,24 +111,35 @@ Notes:
|
|||
- Mandatory for `kicost`
|
||||
- Optional to find components costs and specs for `bom`
|
||||
|
||||
[**Interactive HTML BoM**](https://github.com/INTI-CMNB/InteractiveHtmlBom) v2.4.1.3 (tool)
|
||||
[**Interactive HTML BoM**](https://github.com/INTI-CMNB/InteractiveHtmlBom) v2.4.1.4 (tool)
|
||||
- Mandatory for `ibom`
|
||||
|
||||
[**KiBoM**](https://github.com/INTI-CMNB/KiBoM) v1.8.0 (tool)
|
||||
- Mandatory for `kibom`
|
||||
|
||||
[**lxml**](https://pypi.org/project/lxml/) (python module) [Debian](https://packages.debian.org/bullseye/python3-lxml)
|
||||
[**LXML**](https://pypi.org/project/LXML/) (python module) [Debian](https://packages.debian.org/bullseye/python3-lxml)
|
||||
- Mandatory for `pcb_print`
|
||||
|
||||
[**PcbDraw**](https://github.com/INTI-CMNB/pcbdraw) v0.9.0 (tool)
|
||||
- Mandatory for `pcbdraw`
|
||||
|
||||
[**qrcodegen**](https://pypi.org/project/qrcodegen/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-qrcodegen)
|
||||
[**QRCodeGen**](https://pypi.org/project/QRCodeGen/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-qrcodegen)
|
||||
- Mandatory for `qr_lib`
|
||||
|
||||
[**colorama**](https://pypi.org/project/colorama/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-colorama)
|
||||
[**Colorama**](https://pypi.org/project/Colorama/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-colorama)
|
||||
- Optional to get color messages in a portable way for general use
|
||||
|
||||
[**Git**](https://git-scm.com/) (tool) [Debian](https://packages.debian.org/bullseye/git)
|
||||
- Optional to:
|
||||
- Find commit hash and/or date for `pcb_replace`
|
||||
- Find commit hash and/or date for `sch_replace`
|
||||
- Find commit hash and/or date for `set_text_variables`
|
||||
|
||||
[**ImageMagick**](https://imagemagick.org/) (tool) [Debian](https://packages.debian.org/bullseye/imagemagick)
|
||||
- Optional to:
|
||||
- Create monochrome prints for `pcb_print`
|
||||
- Create JPG images for `pcbdraw`
|
||||
|
||||
[**RSVG tools**](https://cran.r-project.org/web/packages/rsvg/index.html) (tool) [Debian](https://packages.debian.org/bullseye/librsvg2-bin)
|
||||
- Optional to:
|
||||
- Create PDF, PNG, EPS and PS formats for `pcb_print`
|
||||
|
|
@ -136,16 +148,13 @@ Notes:
|
|||
[**Ghostscript**](https://www.ghostscript.com/) (tool) [Debian](https://packages.debian.org/bullseye/ghostscript)
|
||||
- Optional to create PS files for `pcb_print`
|
||||
|
||||
[**ImageMagick**](https://imagemagick.org/) (tool) [Debian](https://packages.debian.org/bullseye/imagemagick)
|
||||
- Optional to create JPG images for `pcbdraw`
|
||||
|
||||
[**Pandoc**](https://pandoc.org/) (tool) [Debian](https://packages.debian.org/bullseye/pandoc)
|
||||
- Optional to create PDF/ODF/DOCX files for `report`
|
||||
|
||||
[**RAR**](https://www.rarlab.com/) (tool) [Debian](https://packages.debian.org/bullseye/rar)
|
||||
- Optional to compress in RAR format for `compress`
|
||||
|
||||
[**xlsxwriter**](https://pypi.org/project/xlsxwriter/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-xlsxwriter)
|
||||
[**XLSXWriter**](https://pypi.org/project/XLSXWriter/) (python module) (PyPi dependency) [Debian](https://packages.debian.org/bullseye/python3-xlsxwriter)
|
||||
- Optional to create XLSX files for `bom`
|
||||
|
||||
|
||||
|
|
@ -3026,7 +3035,7 @@ Usage:
|
|||
kibot [-v...] [--start PATH] [-d OUT_DIR] [--dry] [-t, --type TYPE]...
|
||||
--quick-start
|
||||
kibot [-v...] --help-filters
|
||||
kibot [-v...] [--markdown] --help-dependencies
|
||||
kibot [-v...] [--markdown|--json] --help-dependencies
|
||||
kibot [-v...] --help-global-options
|
||||
kibot [-v...] --help-list-outputs
|
||||
kibot [-v...] --help-output=HELP_OUTPUT
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
all: ../README.md samples/generic_plot.kibot.yaml ../kibot/report_templates/report_full_svg.txt ../kibot/config_templates/bom/MacroFab_XYRS.kibot.yaml \
|
||||
../kibot/config_templates/gerber/Elecrow.kibot.yaml ../kibot/config_templates/gerber/FusionPCB.kibot.yaml \
|
||||
../kibot/config_templates/gerber/JLCPCB.kibot.yaml ../kibot/config_templates/gerber/PCBWay.kibot.yaml
|
||||
../kibot/config_templates/gerber/JLCPCB.kibot.yaml ../kibot/config_templates/gerber/PCBWay.kibot.yaml ../src/kibot-check
|
||||
|
||||
../kibot/config_templates/gerber/%.kibot.yaml: samples/%.kibot.yaml
|
||||
cp $< $@
|
||||
|
|
@ -13,6 +13,9 @@ all: ../README.md samples/generic_plot.kibot.yaml ../kibot/report_templates/rep
|
|||
../README.md: README.in replace_tags.pl ../kibot/out_*.py ../kibot/pre_*.py ../kibot/fil_*.py ../kibot/__main__.py ../kibot/config_reader.py
|
||||
cat README.in | perl replace_tags.pl > ../README.md
|
||||
|
||||
../src/kibot-check: ../src/kibot-check.in replace_tags.pl ../kibot/out_*.py ../kibot/pre_*.py ../kibot/registrable.py ../kibot/misc.py ../kibot/config_reader.py
|
||||
cat ../src/kibot-check.in | perl replace_tags.pl > ../src/kibot-check
|
||||
|
||||
samples/generic_plot.kibot.yaml: ../kibot/out_*.py ../kibot/pre_*.py ../kibot/config_reader.py
|
||||
rm -f example_template.kibot.yaml
|
||||
../src/kibot -v --example
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ You can also run KiBot using docker images in a CI/CD environment like GitHub or
|
|||
Notes:
|
||||
- When installing from the Debian repo you don't need to worry about dependencies, just pay attention to *recommended* and *suggested* packages.
|
||||
- When installing using `pip` the dependencies marked as **PyPi dependency** will be automatically installed.
|
||||
- The `kibot-check` tool can help you to know which dependencies are missing.
|
||||
|
||||
@dependencies@
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ $preflight=`../src/kibot --help-preflights`;
|
|||
$filters=`../src/kibot --help-filters`;
|
||||
$global_options=`../src/kibot --help-global-options`;
|
||||
$dependencies=`../src/kibot --help-dependencies --markdown`;
|
||||
$json_dep=`../src/kibot --help-dependencies --json`;
|
||||
$json_dep=~s/\n/\\\n/g;
|
||||
|
||||
while (<>)
|
||||
{
|
||||
|
|
@ -15,6 +17,7 @@ while (<>)
|
|||
$_ =~ s/\@filters\@/$filters/;
|
||||
$_ =~ s/\@global_options\@/$global_options/;
|
||||
$_ =~ s/\@dependencies\@/$dependencies/;
|
||||
$_ =~ s/\@json_dep\@/$json_dep/;
|
||||
print $_;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Usage:
|
|||
kibot [-v...] [--start PATH] [-d OUT_DIR] [--dry] [-t, --type TYPE]...
|
||||
--quick-start
|
||||
kibot [-v...] --help-filters
|
||||
kibot [-v...] [--markdown] --help-dependencies
|
||||
kibot [-v...] [--markdown|--json] --help-dependencies
|
||||
kibot [-v...] --help-global-options
|
||||
kibot [-v...] --help-list-outputs
|
||||
kibot [-v...] --help-output=HELP_OUTPUT
|
||||
|
|
@ -88,9 +88,9 @@ if os.environ.get('KIAUS_USE_NIGHTLY'): # pragma: no cover (nightly)
|
|||
else:
|
||||
os.environ['PYTHONPATH'] = pcbnew_path
|
||||
nightly = True
|
||||
from .gs import (GS)
|
||||
from .misc import (EXIT_BAD_ARGS, W_VARCFG, NO_PCBNEW_MODULE, W_NOKIVER, hide_stderr)
|
||||
from .pre_base import (BasePreFlight)
|
||||
from .gs import GS
|
||||
from .misc import EXIT_BAD_ARGS, W_VARCFG, NO_PCBNEW_MODULE, W_NOKIVER, hide_stderr, TRY_INSTALL_CHECK
|
||||
from .pre_base import BasePreFlight
|
||||
from .config_reader import (CfgYamlReader, print_outputs_help, print_output_help, print_preflights_help, create_example,
|
||||
print_filters_help, print_global_options_help, print_dependencies)
|
||||
from .kiplot import (generate_outputs, load_actions, config_output, generate_makefile, generate_examples, solve_schematic,
|
||||
|
|
@ -157,6 +157,7 @@ def detect_kicad():
|
|||
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)
|
||||
try:
|
||||
GS.kicad_version = pcbnew.GetBuildVersion()
|
||||
|
|
@ -267,7 +268,7 @@ def main():
|
|||
print_global_options_help()
|
||||
sys.exit(0)
|
||||
if args.help_dependencies:
|
||||
print_dependencies(args.markdown)
|
||||
print_dependencies(args.markdown, args.json)
|
||||
sys.exit(0)
|
||||
if args.example:
|
||||
check_board_file(args.board_file)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from base64 import b64decode
|
|||
from .columnlist import ColumnList
|
||||
from .kibot_logo import KIBOT_LOGO
|
||||
from .. import log
|
||||
from ..misc import W_NOKICOST, W_UNKDIST, KICOST_ERROR, W_BADFIELD
|
||||
from ..misc import W_NOKICOST, W_UNKDIST, KICOST_ERROR, W_BADFIELD, TRY_INSTALL_CHECK
|
||||
from ..error import trace_dump
|
||||
from ..gs import GS
|
||||
from .. import __version__
|
||||
|
|
@ -51,6 +51,7 @@ except ModuleNotFoundError:
|
|||
except ImportError:
|
||||
logger.error("Installed KiCost is older than the version we support.")
|
||||
logger.error("Try installing the last release or the current GIT code.")
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
KICOST_SUPPORT = False
|
||||
ProgressConsole = object
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ Class to read KiBot config files
|
|||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from sys import (exit, maxsize)
|
||||
from collections import OrderedDict
|
||||
|
||||
from .error import (KiPlotConfigurationError, config_error)
|
||||
from .misc import (NO_YAML_MODULE, EXIT_BAD_ARGS, EXAMPLE_CFG, WONT_OVERWRITE, W_NOOUTPUTS, W_UNKOUT, W_NOFILTERS,
|
||||
W_NOVARIANTS, W_NOGLOBALS)
|
||||
W_NOVARIANTS, W_NOGLOBALS, TRY_INSTALL_CHECK)
|
||||
from .gs import GS
|
||||
from .registrable import RegOutput, RegVariant, RegFilter, RegDependency
|
||||
from .pre_base import BasePreFlight
|
||||
|
|
@ -35,6 +36,7 @@ try:
|
|||
except ImportError:
|
||||
log.init()
|
||||
logger.error('No yaml module for Python, install python3-yaml')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(NO_YAML_MODULE)
|
||||
|
||||
|
||||
|
|
@ -694,7 +696,13 @@ def global2human(name):
|
|||
return '`'+name+'`' if name != 'global' else 'general use'
|
||||
|
||||
|
||||
def print_dependencies(markdown=True):
|
||||
class MyEncoder(json.JSONEncoder):
|
||||
""" Simple JSON encoder for objects """
|
||||
def default(self, o):
|
||||
return o.__dict__
|
||||
|
||||
|
||||
def print_dependencies(markdown=True, jsn=False):
|
||||
# Compute the importance of each dependency
|
||||
for dep in RegDependency.get_registered().values():
|
||||
importance = 0
|
||||
|
|
@ -705,6 +713,10 @@ def print_dependencies(markdown=True):
|
|||
else:
|
||||
importance += LOCAL_OPTIONAL if local else GLOBAL_OPTIONAL
|
||||
dep.importance = importance
|
||||
# The JSON output is just a dump
|
||||
if jsn:
|
||||
print(json.dumps(RegDependency.get_registered(), cls=MyEncoder, indent=4, sort_keys=True))
|
||||
return
|
||||
# Now print them sorted by importance (and by name as a second criteria)
|
||||
for name, dep in sorted(sorted(RegDependency.get_registered().items(), key=lambda x: x[0].lower()), # noqa C414
|
||||
key=lambda x: x[1].importance, reverse=True):
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from collections import OrderedDict
|
|||
from .gs import GS
|
||||
from .registrable import RegOutput
|
||||
from .misc import (PLOT_ERROR, MISSING_TOOL, CMD_EESCHEMA_DO, URL_EESCHEMA_DO, CORRUPTED_PCB,
|
||||
EXIT_BAD_ARGS, CORRUPTED_SCH, EXIT_BAD_CONFIG, WRONG_INSTALL, UI_SMD, UI_VIRTUAL,
|
||||
EXIT_BAD_ARGS, CORRUPTED_SCH, EXIT_BAD_CONFIG, WRONG_INSTALL, UI_SMD, UI_VIRTUAL, TRY_INSTALL_CHECK,
|
||||
MOD_SMD, MOD_THROUGH_HOLE, 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)
|
||||
from .error import PlotError, KiPlotConfigurationError, config_error, trace_dump
|
||||
|
|
@ -44,6 +44,7 @@ try:
|
|||
except ImportError:
|
||||
log.init()
|
||||
logger.error('No yaml module for Python, install python3-yaml')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(NO_YAML_MODULE)
|
||||
|
||||
|
||||
|
|
@ -122,6 +123,7 @@ def check_script(cmd, url, version=None):
|
|||
if which(cmd) is None:
|
||||
logger.error('No `'+cmd+'` command found.\n'
|
||||
'Please install it, visit: '+url)
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
if version is not None:
|
||||
check_version(cmd, version)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ PANDOC = 'pandoc'
|
|||
KICAD_VERSION_5_99 = 5099000
|
||||
KICAD_VERSION_6_0_0 = 6000000
|
||||
KICAD_VERSION_6_0_2 = 6000002
|
||||
TRY_INSTALL_CHECK = 'Try running the installation checker: kibot-check'
|
||||
|
||||
# Internal filter names
|
||||
IFILT_MECHANICAL = '_mechanical'
|
||||
|
|
@ -311,7 +312,8 @@ class ToolDependencyRole(object):
|
|||
class ToolDependency(object):
|
||||
""" Class used to define tools needed for an output """
|
||||
def __init__(self, output, name, url=None, url_down=None, is_python=False, deb=None, in_debian=True, extra_deb=None,
|
||||
roles=None, is_kicad_plugin=False, command=None, pypi_name=None):
|
||||
roles=None, plugin_dirs=None, command=None, pypi_name=None, module_name=None, no_cmd_line_version=False,
|
||||
help_option=None, no_cmd_line_version_old=False):
|
||||
# The associated output
|
||||
self.output = output
|
||||
# Name of the tool
|
||||
|
|
@ -325,6 +327,8 @@ class ToolDependency(object):
|
|||
else:
|
||||
self.deb_package = deb
|
||||
self.is_python = is_python
|
||||
if is_python:
|
||||
self.module_name = module_name if module_name is not None else name.lower()
|
||||
# If this tool has an official Debian package
|
||||
self.in_debian = in_debian
|
||||
# Name at PyPi, can be fake for things that aren't at PyPi
|
||||
|
|
@ -336,9 +340,13 @@ class ToolDependency(object):
|
|||
self.url = url
|
||||
self.url_down = url_down
|
||||
# Can be installed as a KiCad plug-in?
|
||||
self.is_kicad_plugin = is_kicad_plugin
|
||||
self.is_kicad_plugin = plugin_dirs is not None
|
||||
self.plugin_dirs = plugin_dirs
|
||||
# Command we run
|
||||
self.command = command
|
||||
self.command = command if command is not None else name.lower()
|
||||
self.no_cmd_line_version = no_cmd_line_version
|
||||
self.no_cmd_line_version_old = no_cmd_line_version_old # An old version doesn't have version
|
||||
self.help_option = help_option if help_option is not None else '--version'
|
||||
# Roles
|
||||
if roles is None:
|
||||
roles = [ToolDependencyRole()]
|
||||
|
|
@ -352,4 +360,9 @@ class ToolDependency(object):
|
|||
def kiauto_dependency(output, version=None):
|
||||
role = None if version is None else ToolDependencyRole(version=version)
|
||||
return ToolDependency(output, 'KiCad Automation tools', URL_EESCHEMA_DO, url_down=URL_EESCHEMA_DO+'/releases',
|
||||
in_debian=False, pypi_name='kiauto', roles=role)
|
||||
in_debian=False, pypi_name='kiauto', command='pcbnew_do', roles=role)
|
||||
|
||||
|
||||
def git_dependency(output):
|
||||
return ToolDependency(output, 'Git', 'https://git-scm.com/',
|
||||
roles=ToolDependencyRole(desc='Find commit hash and/or date'))
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ from tarfile import open as tar_open
|
|||
from collections import OrderedDict
|
||||
from .gs import GS
|
||||
from .kiplot import config_output, get_output_dir, run_output
|
||||
from .misc import MISSING_TOOL, WRONG_INSTALL, W_EMPTYZIP, WRONG_ARGUMENTS, INTERNAL_ERROR, ToolDependency, ToolDependencyRole
|
||||
from .misc import (MISSING_TOOL, WRONG_INSTALL, W_EMPTYZIP, WRONG_ARGUMENTS, INTERNAL_ERROR, ToolDependency,
|
||||
ToolDependencyRole, TRY_INSTALL_CHECK)
|
||||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput, RegDependency
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
|
|
@ -22,7 +23,7 @@ from . import log
|
|||
|
||||
logger = log.get_logger()
|
||||
RegDependency.register(ToolDependency('compress', 'RAR', 'https://www.rarlab.com/',
|
||||
url_down='https://www.rarlab.com/download.htm',
|
||||
url_down='https://www.rarlab.com/download.htm', help_option='-?',
|
||||
roles=ToolDependencyRole(desc='Compress in RAR format')))
|
||||
|
||||
|
||||
|
|
@ -107,6 +108,7 @@ class CompressOptions(BaseOptions):
|
|||
check_output(cmd, stderr=STDOUT)
|
||||
except FileNotFoundError:
|
||||
logger.error('Missing `rar` command, install it')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
except CalledProcessError as e:
|
||||
logger.error('Failed to invoke rar command, error {}'.format(e.returncode))
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ from . import log
|
|||
logger = log.get_logger()
|
||||
WARNING_MIX = "Avoid using it in conjunction with IBoM native filtering options"
|
||||
RegDependency.register(ToolDependency('ibom', 'Interactive HTML BoM', URL_IBOM, url_down=URL_IBOM+'/releases',
|
||||
is_kicad_plugin=True, command=CMD_IBOM, in_debian=False,
|
||||
roles=ToolDependencyRole(version=(2, 4, 1, 3))))
|
||||
command=CMD_IBOM, in_debian=False, no_cmd_line_version_old=True,
|
||||
plugin_dirs=['InteractiveHtmlBom', 'InteractiveHtmlBom/InteractiveHtmlBom'],
|
||||
roles=ToolDependencyRole(version=(2, 4, 1, 4))))
|
||||
|
||||
|
||||
def check_tool():
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from .kicad.config import KiConf
|
|||
from .kicad.v5_sch import SchError
|
||||
from .kicad.pcb import PCB
|
||||
from .misc import (CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, PDF_PCB_PRINT, MISSING_TOOL, W_PDMASKFAIL,
|
||||
KICAD5_SVG_SCALE, W_MISSTOOL, ToolDependency, ToolDependencyRole)
|
||||
KICAD5_SVG_SCALE, W_MISSTOOL, ToolDependency, ToolDependencyRole, TRY_INSTALL_CHECK)
|
||||
from .kiplot import check_script, exec_with_retry, add_extra_options
|
||||
from .registrable import RegDependency
|
||||
from .create_pdf import create_pdf_from_pages
|
||||
|
|
@ -44,11 +44,14 @@ DRAWING_LAYERS = ['Dwgs.User', 'Cmts.User', 'Eco1.User', 'Eco2.User']
|
|||
EXTRA_LAYERS = ['F.Fab', 'B.Fab', 'F.CrtYd', 'B.CrtYd']
|
||||
RegDependency.register(ToolDependency('pcb_print', 'RSVG tools',
|
||||
'https://cran.r-project.org/web/packages/rsvg/index.html', deb='librsvg2-bin',
|
||||
command=SVG2PDF,
|
||||
roles=ToolDependencyRole(desc='Create PDF, PNG, EPS and PS formats')))
|
||||
RegDependency.register(ToolDependency('pcb_print', 'Ghostscript', 'https://www.ghostscript.com/',
|
||||
url_down='https://github.com/ArtifexSoftware/ghostpdl-downloads/releases',
|
||||
roles=ToolDependencyRole(desc='Create PS files')))
|
||||
RegDependency.register(ToolDependency('pcb_print', 'lxml', is_python=True))
|
||||
RegDependency.register(ToolDependency('pcb_print', 'ImageMagick', 'https://imagemagick.org/', command='convert',
|
||||
roles=ToolDependencyRole(desc='Create monochrome prints')))
|
||||
RegDependency.register(ToolDependency('pcb_print', 'LXML', is_python=True))
|
||||
|
||||
|
||||
def _run_command(cmd):
|
||||
|
|
@ -636,6 +639,7 @@ class PCB_PrintOptions(VariantOptions):
|
|||
if monochrome:
|
||||
if which('convert') is None:
|
||||
logger.error('`convert` not installed. install `imagemagick` or equivalent')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
for img in self.last_worksheet.images:
|
||||
with NamedTemporaryFile(mode='wb', suffix='.png', delete=False) as f:
|
||||
|
|
@ -771,6 +775,7 @@ class PCB_PrintOptions(VariantOptions):
|
|||
# Check PcbDraw is available
|
||||
if which('pcbdraw') is None:
|
||||
logger.error('`pcbdraw` not installed, needed for `realistic_solder_mask`')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
# Run PcbDraw to make the heavy work (find the Edge.Cuts path and create masks)
|
||||
pcbdraw_file = os.path.join(temp_dir, out_file.replace('.svg', '-pcbdraw.svg'))
|
||||
|
|
@ -864,10 +869,12 @@ class PCB_PrintOptions(VariantOptions):
|
|||
def generate_output(self, output):
|
||||
if self.format != 'SVG' and which(SVG2PDF) is None:
|
||||
logger.error('`{}` not installed. Install `librsvg2-bin` or equivalent'.format(SVG2PDF))
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
if self.format == 'PS' and which(PDF2PS) is None:
|
||||
logger.error('`{}` not installed. '.format(PDF2PS))
|
||||
logger.error('Install `librsvg2-bin` or equivalent')
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
output_dir = os.path.dirname(output)
|
||||
if self.keep_temporal_files:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from tempfile import NamedTemporaryFile
|
|||
import subprocess
|
||||
import shutil
|
||||
from .misc import (PCBDRAW, PCBDRAW_ERR, URL_PCBDRAW, W_AMBLIST, W_UNRETOOL, W_USESVG2, W_USEIMAGICK, PCB_MAT_COLORS,
|
||||
PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, ToolDependency, ToolDependencyRole)
|
||||
PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, ToolDependency, ToolDependencyRole, TRY_INSTALL_CHECK)
|
||||
from .kiplot import check_script
|
||||
from .registrable import RegDependency
|
||||
from .gs import GS
|
||||
|
|
@ -24,9 +24,9 @@ CONVERT = 'convert'
|
|||
# 0.9.0 implements KiCad 6 support
|
||||
MIN_VERSION = '0.9.0'
|
||||
RegDependency.register(ToolDependency('pcbdraw', 'RSVG tools', 'https://cran.r-project.org/web/packages/rsvg/index.html',
|
||||
deb='librsvg2-bin',
|
||||
deb='librsvg2-bin', command=SVG2PNG,
|
||||
roles=ToolDependencyRole(desc='Create PNG and JPG images')))
|
||||
RegDependency.register(ToolDependency('pcbdraw', 'ImageMagick', 'https://imagemagick.org/',
|
||||
RegDependency.register(ToolDependency('pcbdraw', 'ImageMagick', 'https://imagemagick.org/', command='convert',
|
||||
roles=ToolDependencyRole(desc='Create JPG images')))
|
||||
RegDependency.register(ToolDependency('pcbdraw', 'PcbDraw', URL_PCBDRAW, url_down=URL_PCBDRAW+'/releases', in_debian=False,
|
||||
roles=ToolDependencyRole(version=(0, 9, 0))))
|
||||
|
|
@ -251,10 +251,12 @@ class PcbDrawOptions(VariantOptions):
|
|||
if shutil.which(SVG2PNG) is None:
|
||||
logger.warning(W_UNRETOOL + '`{}` not installed, using unreliable PNG/JPG conversion'.format(SVG2PNG))
|
||||
logger.warning(W_USESVG2 + 'If you experiment problems install `librsvg2-bin` or equivalent')
|
||||
logger.warning(W_USESVG2 + TRY_INSTALL_CHECK)
|
||||
cmd.append(output)
|
||||
elif shutil.which(CONVERT) is None:
|
||||
logger.warning(W_UNRETOOL + '`{}` not installed, using unreliable PNG/JPG conversion'.format(CONVERT))
|
||||
logger.warning(W_USEIMAGICK + 'If you experiment problems install `imagemagick` or equivalent')
|
||||
logger.warning(W_USEIMAGICK + TRY_INSTALL_CHECK)
|
||||
cmd.append(output)
|
||||
else:
|
||||
svg = _get_tmp_name('.svg')
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ QR_ECCS = {'low': QrCode.Ecc.LOW,
|
|||
logger = log.get_logger()
|
||||
TO_SEPARATE = {'kicad_pcb', 'general', 'title_block', 'layers', 'setup', 'pcbplotparams', 'net_class', 'module',
|
||||
'kicad_sch', 'lib_symbols', 'symbol', 'sheet', 'sheet_instances', 'symbol_instances'}
|
||||
RegDependency.register(ToolDependency('qr_lib', 'qrcodegen', is_python=True, roles=ToolDependencyRole()))
|
||||
RegDependency.register(ToolDependency('qr_lib', 'QRCodeGen', is_python=True, roles=ToolDependencyRole()))
|
||||
|
||||
|
||||
def is_symbol(name, sexp):
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ from shutil import which
|
|||
|
||||
from .gs import GS
|
||||
from .misc import (UI_SMD, UI_VIRTUAL, MOD_THROUGH_HOLE, MOD_SMD, MOD_EXCLUDE_FROM_POS_FILES, PANDOC, MISSING_TOOL,
|
||||
FAILED_EXECUTE, W_WRONGEXT, W_WRONGOAR, W_ECCLASST, W_MISSTOOL, ToolDependency, ToolDependencyRole)
|
||||
FAILED_EXECUTE, W_WRONGEXT, W_WRONGOAR, W_ECCLASST, W_MISSTOOL, ToolDependency, ToolDependencyRole,
|
||||
TRY_INSTALL_CHECK)
|
||||
from .registrable import RegOutput, RegDependency
|
||||
from .out_base import BaseOptions
|
||||
from .error import KiPlotConfigurationError
|
||||
|
|
@ -722,6 +723,7 @@ class ReportOptions(BaseOptions):
|
|||
except FileNotFoundError:
|
||||
logger.error("Unable to convert the report, `{}` must be installed.".format(PANDOC))
|
||||
logger.error(PANDOC_INSTALL)
|
||||
logger.error(TRY_INSTALL_CHECK)
|
||||
exit(MISSING_TOOL)
|
||||
except CalledProcessError as e:
|
||||
logger.error('{} error: {}'.format(PANDOC, e.returncode))
|
||||
|
|
@ -803,6 +805,7 @@ class Report(BaseOutput): # noqa: F821
|
|||
def get_conf_examples(name, layers, templates):
|
||||
if which(PANDOC) is None:
|
||||
logger.warning((W_MISSTOOL+'Missing {} tool, disabling report in PDF format\n'+PANDOC_INSTALL).format(PANDOC))
|
||||
logger.warning(W_MISSTOOL+TRY_INSTALL_CHECK)
|
||||
pandoc = False
|
||||
else:
|
||||
pandoc = True
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021 Salvador E. Tropea
|
||||
# Copyright (c) 2021 Instituto Nacional de Tecnología Industrial
|
||||
# Copyright (c) 2021-2022 Salvador E. Tropea
|
||||
# Copyright (c) 2021-2022 Instituto Nacional de Tecnología Industrial
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
from .gs import GS
|
||||
from .pre_any_replace import TagReplaceBase, Base_ReplaceOptions, Base_Replace
|
||||
from .registrable import RegDependency
|
||||
from .misc import git_dependency
|
||||
from .macros import macros, document, pre_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
RegDependency.register(git_dependency('pcb_replace'))
|
||||
|
||||
|
||||
class TagReplacePCB(TagReplaceBase):
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ import os
|
|||
from .gs import GS
|
||||
from .kiplot import load_sch
|
||||
from .pre_any_replace import TagReplaceBase, Base_ReplaceOptions, Base_Replace
|
||||
from .registrable import RegDependency
|
||||
from .misc import git_dependency
|
||||
from .macros import macros, document, pre_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
RegDependency.register(git_dependency('sch_replace'))
|
||||
|
||||
|
||||
class TagReplaceSCH(TagReplaceBase):
|
||||
|
|
|
|||
|
|
@ -8,14 +8,16 @@ import sys
|
|||
import json
|
||||
from subprocess import run, PIPE
|
||||
from .error import KiPlotConfigurationError
|
||||
from .misc import FAILED_EXECUTE, W_EMPTREP
|
||||
from .misc import FAILED_EXECUTE, W_EMPTREP, git_dependency
|
||||
from .optionable import Optionable
|
||||
from .pre_base import BasePreFlight
|
||||
from .gs import GS
|
||||
from .registrable import RegDependency
|
||||
from .macros import macros, document, pre_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
RegDependency.register(git_dependency('set_text_variables'))
|
||||
|
||||
|
||||
class KiCadVariable(Optionable):
|
||||
|
|
|
|||
|
|
@ -170,8 +170,8 @@ class RegDependency(Registrable):
|
|||
|
||||
|
||||
# Here we register some global dependencies
|
||||
RegDependency.register(ToolDependency('global', 'colorama', is_python=True,
|
||||
RegDependency.register(ToolDependency('global', 'Colorama', is_python=True,
|
||||
roles=ToolDependencyRole(desc='get color messages in a portable way')))
|
||||
RegDependency.register(ToolDependency('global', 'distutils', is_python=True))
|
||||
RegDependency.register(ToolDependency('global', 'requests', is_python=True))
|
||||
RegDependency.register(ToolDependency('global', 'PyYAML', is_python=True, deb='python3-yaml'))
|
||||
RegDependency.register(ToolDependency('global', 'Distutils', is_python=True))
|
||||
RegDependency.register(ToolDependency('global', 'Requests', is_python=True))
|
||||
RegDependency.register(ToolDependency('global', 'PyYAML', is_python=True, deb='python3-yaml', module_name='yaml'))
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -18,7 +18,7 @@ setup(name='kibot',
|
|||
url=__url__,
|
||||
# Packages are marked using __init__.py
|
||||
packages=find_packages(),
|
||||
scripts=['src/kibot', 'src/kiplot'],
|
||||
scripts=['src/kibot', 'src/kiplot', 'src/kibot-check'],
|
||||
install_requires=__pypi_deps__,
|
||||
include_package_data=True,
|
||||
classifiers=['Development Status :: 5 - Production/Stable',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,410 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- 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)
|
||||
#
|
||||
# This is the installation checker, should help people to detect installation issues and install needed tools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import platform
|
||||
import subprocess
|
||||
import json
|
||||
import importlib
|
||||
from shutil import which
|
||||
from contextlib import contextmanager
|
||||
|
||||
deps = '@json_dep@'
|
||||
# Dirs to look for plugins
|
||||
kicad_plugins_dirs = []
|
||||
NOT_AVAIL = 'Not available'
|
||||
UNKNOWN = '*UNKNOWN*'
|
||||
CSI = '\033['
|
||||
RED = CSI+str(31)+'m'
|
||||
GREEN = CSI+str(32)+'m'
|
||||
YELLOW = CSI+str(33)+'m'
|
||||
YELLOW2 = CSI+str(93)+'m'
|
||||
RESET = CSI+str(39)+'m'
|
||||
BRIGHT = CSI+";1;4"+'m'
|
||||
NORMAL = CSI+'0'+'m'
|
||||
last_ok = False
|
||||
is_x86 = is_64 = is_linux = False
|
||||
ver_re = re.compile(r'(\d+)\.(\d+)(?:\.(\d+))?(?:[\.-](\d+))?')
|
||||
|
||||
|
||||
def run_command(cmd, only_first_line=True, pre_ver_text=None, no_err_2=False):
|
||||
global last_ok
|
||||
try:
|
||||
cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
|
||||
except FileNotFoundError as e:
|
||||
last_ok = False
|
||||
return NOT_AVAIL
|
||||
except subprocess.CalledProcessError as e:
|
||||
if e.returncode != 2 or not no_err_2:
|
||||
print('Failed to run %s, error %d' % (cmd[0], e.returncode))
|
||||
if e.output:
|
||||
print('Output from command: '+e.output.decode())
|
||||
last_ok = False
|
||||
return UNKNOWN
|
||||
res = cmd_output.decode().strip()
|
||||
if only_first_line:
|
||||
res = res.split('\n')[0]
|
||||
pre_vers = (cmd[0]+' version ', cmd[0]+' ', pre_ver_text)
|
||||
for pre_ver in pre_vers:
|
||||
if pre_ver and res.startswith(pre_ver):
|
||||
res = res[len(pre_ver):]
|
||||
last_ok = True
|
||||
return res
|
||||
|
||||
|
||||
def simple_run_command(cmd):
|
||||
res = run_command(cmd)
|
||||
sev, ver = check_version(res, [{'mandatory': True, 'output': 'global', 'version': None}], no_ver=True)
|
||||
return do_color(res, sev, version=ver)
|
||||
|
||||
|
||||
def search_as_plugin(cmd, names):
|
||||
""" If a command isn't in the path look for it in the KiCad plugins """
|
||||
if which(cmd) is not None:
|
||||
return cmd
|
||||
for dir in kicad_plugins_dirs:
|
||||
for name in names:
|
||||
fname = os.path.join(dir, name, cmd)
|
||||
if os.path.isfile(fname):
|
||||
logger.debug('Using `{}` for `{}` ({})'.format(fname, cmd, name))
|
||||
return fname
|
||||
return cmd
|
||||
|
||||
|
||||
@contextmanager
|
||||
def hide_stderr():
|
||||
""" Low level stderr suppression, used to hide KiCad bugs. """
|
||||
newstderr = os.dup(2)
|
||||
devnull = os.open('/dev/null', os.O_WRONLY)
|
||||
os.dup2(devnull, 2)
|
||||
os.close(devnull)
|
||||
yield
|
||||
os.dup2(newstderr, 2)
|
||||
|
||||
|
||||
def do_int(v):
|
||||
return int(v) if v is not None else 0
|
||||
|
||||
|
||||
def check_version(version, roles, no_ver=False):
|
||||
res = ver_re.search(version)
|
||||
if res:
|
||||
ver = list(map(do_int, res.groups()))
|
||||
else:
|
||||
ver = [0, 0, 0]
|
||||
not_avail = version == NOT_AVAIL or version == UNKNOWN
|
||||
severity = 0
|
||||
for r in roles:
|
||||
mandatory = r['mandatory']
|
||||
glb = r['output'] == 'global'
|
||||
this_sever = 0
|
||||
if not_avail or (r['version'] and ver < r['version']):
|
||||
if mandatory:
|
||||
this_sever = 4 if glb else 3
|
||||
else:
|
||||
this_sever = 2 if glb else 1
|
||||
severity = max(severity, this_sever)
|
||||
r['sev'] = this_sever
|
||||
return severity, ver
|
||||
|
||||
|
||||
def sev2color(severity):
|
||||
if severity == 4:
|
||||
return RED
|
||||
elif severity == 3:
|
||||
return YELLOW2
|
||||
elif severity:
|
||||
return YELLOW
|
||||
else:
|
||||
return GREEN
|
||||
|
||||
|
||||
def do_color(msg, severity, version=None):
|
||||
if version is not None and version != [0, 0, 0]:
|
||||
if len(version) == 4 and version[3] == 0:
|
||||
version = version[:-1]
|
||||
ver_str = '.'.join(map(str, version))
|
||||
if ver_str != msg:
|
||||
msg = ver_str+' ('+msg+')'
|
||||
return sev2color(severity)+msg+RESET
|
||||
|
||||
|
||||
def error(msg):
|
||||
print(sev2color(4)+'**> '+msg+RESET)
|
||||
|
||||
|
||||
def do_bright(msg):
|
||||
return BRIGHT+msg+NORMAL
|
||||
|
||||
|
||||
def global2human(name):
|
||||
return '`'+name+'`' if name != 'global' else 'general use'
|
||||
|
||||
|
||||
def show_roles(roles):
|
||||
needed = []
|
||||
optional = []
|
||||
for r in roles:
|
||||
if r['mandatory']:
|
||||
needed.append(r)
|
||||
else:
|
||||
optional.append(r)
|
||||
r['output'] = global2human(r['output'])
|
||||
if needed:
|
||||
if len(needed) == 1:
|
||||
color = sev2color(needed[0]['sev'])
|
||||
name = needed[0]['output']
|
||||
if name == 'general use':
|
||||
print(color+' - Mandatory')
|
||||
else:
|
||||
print(color+' - Mandatory for '+name)
|
||||
else:
|
||||
need_s = sorted(needed, key=lambda x: x['output'])
|
||||
print(RESET+' - Mandatory for: '+', '.join([sev2color(f['sev'])+f['output']+RESET for f in need_s]))
|
||||
if optional:
|
||||
if len(optional) == 1:
|
||||
o = optional[0]
|
||||
desc = o['desc'][0].lower()+o['desc'][1:]
|
||||
print(sev2color(o['sev'])+' - Optional to {} for {}'.format(desc, o['output']))
|
||||
else:
|
||||
print(RESET+' - Optional to:')
|
||||
for o in optional:
|
||||
ver = ''
|
||||
if o['version']:
|
||||
ver = ' (v'+'.'.join(map(str, o['version']))+')'
|
||||
print(sev2color(o['sev'])+' - {} for {}{}'.format(o['desc'], o['output'], ver))
|
||||
|
||||
|
||||
def python_module(severity, name, deb_package, roles):
|
||||
if not severity:
|
||||
return
|
||||
print(sev2color(severity)+'* Python module `{}` not installed or too old'.format(name))
|
||||
if debian_support:
|
||||
if deb_package is None:
|
||||
deb_package = 'python3-'+name
|
||||
print(' Install the `{0}` package, i.e.: `sudo apt-get install {0}`'.format(deb_package))
|
||||
elif pip_ok:
|
||||
print(' run `{} install {}` as root,'.format(pip_command, name))
|
||||
print(' or run `{} install --user {}` as a regular user'.format(pip_command, name))
|
||||
else:
|
||||
print(' Install the Package Installer for Python (pip) and run this script again')
|
||||
show_roles(roles)
|
||||
print(RESET)
|
||||
|
||||
|
||||
def binary_tool(severity, name, url, url_down, deb_package, deb, extra_deb, roles):
|
||||
if not severity:
|
||||
return
|
||||
print(sev2color(severity)+'* {} not installed or too old'.format(name))
|
||||
if deb and debian_support:
|
||||
if deb_package is None:
|
||||
deb_package = name.lower()
|
||||
print(' Install the `{0}` package, i.e.: `sudo apt-get install {0}`'.format(deb_package))
|
||||
if extra_deb:
|
||||
print(' You should also install the following packages: '+', '.join(extra_deb))
|
||||
else:
|
||||
print(' Visit: '+url)
|
||||
if url_down:
|
||||
print(' Download it from: '+url_down)
|
||||
show_roles(roles)
|
||||
print(RESET)
|
||||
|
||||
# ######################################################################################################################
|
||||
# Core tools
|
||||
# ######################################################################################################################
|
||||
|
||||
print('KiBot installation checker\n')
|
||||
|
||||
print(do_bright('Core:'))
|
||||
# Operating system
|
||||
system = platform.system()
|
||||
if system == 'Linux':
|
||||
linux_version = simple_run_command(['uname', '-a'])
|
||||
print('Linux: '+linux_version)
|
||||
os_ok = True
|
||||
is_x86 = 'x86' in linux_version
|
||||
is_64 = ('x86_64' in linux_version) or ('amd64' in linux_version)
|
||||
is_linux = True
|
||||
else:
|
||||
print(system)
|
||||
os_ok = False
|
||||
# Python version
|
||||
if sys.version_info >= (3, 6):
|
||||
py_ok = True
|
||||
sev = 0
|
||||
else:
|
||||
py_ok = False
|
||||
sev = 4
|
||||
print('Python: '+do_color(sys.version.replace('\n', ' '), sev))
|
||||
# KiCad
|
||||
try:
|
||||
import pcbnew
|
||||
kicad_ok = True
|
||||
# Fill the plug-in locations
|
||||
# TODO: Windows? MacOSX?
|
||||
kicad_share_path = '/usr/share/kicad'
|
||||
if hasattr(pcbnew, 'GetKicadConfigPath'):
|
||||
with hide_stderr():
|
||||
kicad_conf_path = pcbnew.GetKicadConfigPath()
|
||||
elif hasattr(pcbnew, 'GetSettingsManager'):
|
||||
kicad_conf_path = pcbnew.GetSettingsManager().GetUserSettingsPath()
|
||||
else:
|
||||
kicad_conf_path = None
|
||||
# /usr/share/kicad/*
|
||||
kicad_plugins_dirs.append(os.path.join(kicad_share_path, 'scripting'))
|
||||
kicad_plugins_dirs.append(os.path.join(kicad_share_path, 'scripting', 'plugins'))
|
||||
# ~/.config/kicad/*
|
||||
if kicad_conf_path:
|
||||
kicad_plugins_dirs.append(os.path.join(kicad_conf_path, 'scripting'))
|
||||
kicad_plugins_dirs.append(os.path.join(kicad_conf_path, 'scripting', 'plugins'))
|
||||
# ~/.kicad_plugins and ~/.kicad
|
||||
if 'HOME' in os.environ:
|
||||
home = os.environ['HOME']
|
||||
kicad_plugins_dirs.append(os.path.join(home, '.kicad_plugins'))
|
||||
kicad_plugins_dirs.append(os.path.join(home, '.kicad', 'scripting'))
|
||||
kicad_plugins_dirs.append(os.path.join(home, '.kicad', 'scripting', 'plugins'))
|
||||
except FileNotFoundError:
|
||||
kicad_ok = False
|
||||
kicad_version = (0, 0, 0)
|
||||
if kicad_ok:
|
||||
try:
|
||||
version = pcbnew.GetBuildVersion()
|
||||
# KiCad version
|
||||
m = re.search(r'(\d+)\.(\d+)\.(\d+)', version)
|
||||
if m is None:
|
||||
error("Unable to detect KiCad version, got: `{}`".format(version))
|
||||
else:
|
||||
kicad_version = (int(m.group(1)), int(m.group(2)), int(m.group(3)))
|
||||
except:
|
||||
version = 'Older than 5.1.6'
|
||||
else:
|
||||
version = NOT_AVAIL
|
||||
if kicad_version >= (5, 1, 6) and kicad_version < (6, 99):
|
||||
sev = 0
|
||||
else:
|
||||
sev = 4
|
||||
print('KiCad: '+do_color(version, sev))
|
||||
# KiBot version
|
||||
try:
|
||||
from kibot.__main__ import __version__
|
||||
kibot_ok = True
|
||||
sev = 0
|
||||
except:
|
||||
__version__ = NOT_AVAIL
|
||||
kibot_ok = False
|
||||
sev = 4
|
||||
print('Kibot: '+do_color(__version__, sev))
|
||||
if kibot_ok and which('kibot') is None:
|
||||
print(sev2color(4)+'* KiBot is installed but not available in your PATH')
|
||||
import kibot
|
||||
if '/lib/' in kibot.__file__:
|
||||
v = re.sub(r'\/lib\/.*', '/bin/kibot', kibot.__file__)
|
||||
if os.path.isfile(v):
|
||||
print(' Try adding `{}` to your PATH'.format(v[:-5]))
|
||||
print(' I.e.: export PATH=$PATH:'+v[:-5])
|
||||
sys.exit(1)
|
||||
|
||||
dependencies = json.loads(deps)
|
||||
print(do_bright('\nModules:'))
|
||||
for name, d in dependencies.items():
|
||||
if not d['is_python']:
|
||||
continue
|
||||
try:
|
||||
mod = importlib.import_module(d['module_name'])
|
||||
if hasattr(mod, '__version__'):
|
||||
version = mod.__version__
|
||||
else:
|
||||
version = 'Ok'
|
||||
except:
|
||||
version = NOT_AVAIL
|
||||
sev, ver = check_version(version, d['roles'])
|
||||
d['sev'] = sev
|
||||
print(name+': '+do_color(version, sev, version=ver))
|
||||
|
||||
print(do_bright('\nTools:'))
|
||||
for name, d in dependencies.items():
|
||||
if d['is_python']:
|
||||
continue
|
||||
command = d['command']
|
||||
if d['is_kicad_plugin']:
|
||||
command = search_as_plugin(command, d['plugin_dirs'])
|
||||
if d['no_cmd_line_version']:
|
||||
version = 'Ok ({})'.format(command) if which(command) is not None else NOT_AVAIL
|
||||
else:
|
||||
version = run_command([command, d['help_option']], no_err_2=d['no_cmd_line_version_old'])
|
||||
sev, ver = check_version(version, d['roles'])
|
||||
d['sev'] = sev
|
||||
print(name+': '+do_color(version, sev, version=ver))
|
||||
|
||||
# ######################################################################################################################
|
||||
# Recommendations
|
||||
# ######################################################################################################################
|
||||
|
||||
print()
|
||||
|
||||
debian_support = False
|
||||
if which('apt-get'):
|
||||
debian_support = True
|
||||
pip_ok = False
|
||||
if which('pip3'):
|
||||
pip_ok = True
|
||||
pip_command = 'pip3'
|
||||
elif which('pip'):
|
||||
pip_ok = True
|
||||
pip_command = 'pip'
|
||||
|
||||
if not os_ok:
|
||||
print(sev2color(4)+'* KiBot is currently tested under Linux')
|
||||
if system == 'Darwin':
|
||||
print(' MacOSX should be supported for KiCad 6.x')
|
||||
elif system == 'Windows':
|
||||
print(' Windows may work with some limitations for KiCad 6.x')
|
||||
print(' Consider using a docker image, Windows docker can run Linux images (using virtualization)')
|
||||
else:
|
||||
print(' What OS are you using? Is KiCad available for it?')
|
||||
print(' Please consult: https://github.com/INTI-CMNB/KiBot/issues')
|
||||
print(RESET)
|
||||
|
||||
if not py_ok:
|
||||
print(sev2color(4)+'* Install Python 3.6 or newer')
|
||||
print(RESET)
|
||||
|
||||
if not kicad_ok:
|
||||
print(sev2color(4)+'* Install KiCad 5.1.6 or newer')
|
||||
if debian_support:
|
||||
print(' Try `apt-get install kicad` as root')
|
||||
else:
|
||||
print(' Download it from: https://www.kicad.org/download/')
|
||||
print(RESET)
|
||||
|
||||
if not kibot_ok:
|
||||
print(sev2color(4)+'* Install KiBot!')
|
||||
if debian_support:
|
||||
print(' Follow the instructions here: https://set-soft.github.io/debian/')
|
||||
elif pip_ok:
|
||||
print(' run `{} install --no-compile kibot` as root,'.format(pip_command))
|
||||
print(' or run `{} install --user --no-compile kibot` as a regular user'.format(pip_command))
|
||||
else:
|
||||
print(' Install the Package Installer for Python (pip) and run this script again')
|
||||
print(RESET)
|
||||
|
||||
for name, d in dependencies.items():
|
||||
if d['is_python']:
|
||||
python_module(d['sev'], d['pypi_name'], d['deb_package'], d['roles'])
|
||||
else:
|
||||
binary_tool(d['sev'], d['name'], d['url'], d['url_down'], d['deb_package'], d['in_debian'], d['extra_deb'],
|
||||
d['roles'])
|
||||
|
||||
labels = ('ok', 'optional for an output', 'optional for general use', 'mandatory for an output', 'mandatory for general use')
|
||||
text = ', '.join([sev2color(c)+l+RESET for c, l in enumerate(labels)])
|
||||
print(do_bright('\nColor reference:')+' '+text)
|
||||
|
||||
print('\nDid this help? Please consider commenting it on https://github.com/INTI-CMNB/KiBot/issues/200')
|
||||
|
||||
Loading…
Reference in New Issue