Giter VIP home page Giter VIP logo

oelint-adv's Introduction

oelint-adv

Build status PyPI version Python version Downloads

Advanced oelint

Purpose

Based on the OpenEmbedded Styleguide and work done by oe-stylize-tool this module offers a (nearly) complete linter for bitbake-recipes.

The tool should help anyone working with YOCTO/OpenEmbedded to write more clean, less 'magical' recipes, without the need to know all the internals of your used poky/OpenEmbedded version.

It could also be used as part of a CI to avoid hard to debug issues slipping to your code base - be sure to checkout rulefile for that use case.

As every linter this tool is sometimes extra picky, but for the good of it, not just to bug people. Especially for novice users it might be a help to avoid the most common pitfalls of bitbake recipes.

The tool does handle includes/requires automatically, so you don't have to pass them via CLI.

NOTE: .bbappend-files have to be passed via CLI - these are NOT gathered automatically.

Install

With pip (recommended)

pip3 install oelint_adv

from source

git clone https://github.com/priv-kweihmann/oelint-adv
cd oelint-adv
python3 setup.py install # might require sudo/root permissions

NOTE if you install from source, you'll have to provide all matching required python libraries on your own. See requirements.txt for details

Usage

usage: oelint-adv [-h] [--suppress SUPPRESS] [--output OUTPUT] [--fix] [--nobackup] [--addrules ADDRULES [ADDRULES ...]]
                  [--customrules CUSTOMRULES [CUSTOMRULES ...]] [--rulefile RULEFILE] [--jobs JOBS] [--color] [--quiet] [--hide SEVERITY]
                  [--relpaths] [--noid] [--messageformat MESSAGEFORMAT] [--constantmods CONSTANTMODS [CONSTANTMODS ...]] [--print-rulefile] [--exit-zero]
                  [--version]
                  [files ...]

Advanced OELint - Check bitbake recipes against OECore styleguide

positional arguments:
  files                 File to parse

options:
  -h, --help            show this help message and exit
  --suppress SUPPRESS   Rules to suppress
  --output OUTPUT       Where to flush the findings (default: stderr)
  --fix                 Automatically try to fix the issues
  --nobackup            Don't create backup file when auto fixing
  --addrules ADDRULES [ADDRULES ...]
                        Additional non-default rulessets to add
  --customrules CUSTOMRULES [CUSTOMRULES ...]
                        Additional directories to parse for rulessets
  --rulefile RULEFILE   Rulefile
  --jobs JOBS           Number of jobs to run (default all cores)
  --color               Add color to the output based on the severity
  --quiet               Print findings only
  --hide SEVERITY       Hide mesesages of specified severity
  --relpaths            Show relative paths instead of absolute paths in results
  --noid                Don't show the error-ID in the output
  --messageformat MESSAGEFORMAT
                        Format of message output
  --constantmods CONSTANTMODS [CONSTANTMODS ...]
                        Modifications to the constant db.
                        prefix with: + - to add to DB, - - to remove from DB, None - to override DB
  --print-rulefile      Print loaded rules as a rulefile and exit
  --release             Run against a specific Yocto release (default: latest)
  --exit-zero           Always return a 0 (non-error) status code, even if lint errors are found
  --version             show program's version number and exit

Output

Will be [file]:[line]:[severity]:[id]:[message]. To change the default message format, please see Output message format section.

Example:

/disk/meta-some/cppcheck-native/cppcheck.inc:26:error:oelint.task.nomkdir:'mkdir' shall not be used in do_install. Use 'install'
/disk/meta-some/cppcheck-native/cppcheck-native_1.87.bb:0:error:oelint.var.mandatoryvar.SECTION:Variable 'SECTION' should be set
/disk/meta-some/cppcheck-native/cppcheck.inc:1:warning:oelint.vars.summary80chars:'SUMMARY' should not be longer than 80 characters
/disk/meta-some/cppcheck-native/cppcheck.inc:4:warning:oelint.vars.homepageprefix:'HOMEPAGE' should start with 'http://' or 'https://'
/disk/meta-some/cppcheck-native/cppcheck.inc:28:warning:oelint.spaces.lineend:Line shall not end with a space
/disk/meta-some/cppcheck-native/cppcheck-native_1.87.bb:0:error:oelint.var.mandatoryvar.AUTHOR:Variable 'AUTHOR' should be set
/disk/meta-some/cppcheck-native/cppcheck.inc:26:error:oelint.task.nocopy:'cp' shall not be used in do_install. Use 'install'
/disk/meta-some/cppcheck-native/cppcheck.inc:12:warning:oelint.var.order.DEPENDS:'DEPENDS' should be placed before 'inherit'

Apply automatic fixing

Some of the rules are capable of fixing the issues found automatically. This will be done if you pass --fix as a startup parameter.

As long as you don't pass --nobackup a backup copy (filename + .bak) will be created for all files fixed.

Available rules

Rules marked with [F] are able to perform automatic fixing Rules marked with [S] can have multiple sub-IDs

Non-default rulesets

To enable rulesets that are not part of the standard ruleset pass --addrules <ruleset-name> to CLI.

These rules are sometimes contrary to OE-style-guide, so use them with caution.

jetm ruleset

To enable pass --addrules jetm to CLI.

Rules marked with [F] are able to perform automatic fixing.

Writing your own additional rules

By passing --customrules via CLI you could add additional rules to be checked. The argument should point to a directory - every class derived from Rule will be automatically loaded. Please use the following as a template for your own:

from oelint_adv.cls_rule import Rule


class FooMagicRule(Rule):
    def __init__(self):
        super().__init__(id="foocorp.foo.magic",
                         severity="error",
                         message="Too much foo happening here")

    def check(self, _file, stash):
        res = []
        items = stash.GetItemsFor(filename=_file)
        for i in items:
            if "Foo" in i.Raw:
                res += self.finding(i.Origin, i.InFileLine)
        return res

    # To provide automatic fixing capability
    # add the following optional function
    def fix(self, _file, stash):
        res = []
        items = stash.GetItemsFor(filename=_file)
        for i in items:
            if 'Foo' in i.Raw:
                # you have to replace the content of `RealRaw` and `Raw`
                # with the fixed content
                # `Raw` is the raw block with expanded inlines blocks
                # `RealRaw` is the raw block without any modifications
                #           this is what will be actually written to the file
                i.RealRaw = i.RealRaw.replace('Foo', 'Bar')
                i.Raw = i.Raw.replace('Foo', 'Bar')
                # Return the file name to signalize that fixes have been
                # applied
                res.append(_file)
        return res

For more details please see the function docstrings of the API.

You can find this example also in the development source tree

Additional real-life examples can be found in e.g. meta-rubygems

Release constrained rules

Rules can be also configured to work on specific releases of YP only, if determined not to be applicable, the rules will be skipped during the loading process and therefore won't show up if e.g. --print-rulefile is used

Rules working up to a certain release

from oelint_adv.cls_rule import Rule


class FooMagicRule(Rule):
    def __init__(self):
        super().__init__(id="foocorp.foo.magic",
                         severity="error",
                         message="Too much foo happening here",
                         valid_till_release="kirkstone")

Would enable the rule, but only if --release is set to a YP release earlier than kirkstone

Rules working from a certain release

from oelint_adv.cls_rule import Rule


class FooMagicRule(Rule):
    def __init__(self):
        super().__init__(id="foocorp.foo.magic",
                         severity="error",
                         message="Too much foo happening here",
                         valid_from_release="kirkstone")

Would enable the rule, but only if --release is set to a YP release later than kirkstone (including kirkstone)

Enable special settings per release

from oelint_adv.cls_rule import Rule


class FooMagicRule(Rule):
    def __init__(self):
        super().__init__(id="foocorp.foo.magic",
                         severity="error",
                         message="Too much foo happening here")

    def check_release_range(self, release_range: List[str]) -> bool:
        if 'kirkstone' in release_range:
            self._we_are_running_on_kirkstone = True
            self.Appendix.append('kirkstone')
        return super().check_release_range(release_range)

Enables the special Appendix kirkstone, if kirkstone is part of the calculated --release list.

It also sets the variable self._we_are_running_on_kirkstone, which can be used as part of check() to code special code paths.

Defining a ruleset

If you pass the option --rulefile you could define the rules to be checked and their severity via a simple json file.

The rule file could look like this:

{
  "<rule>": "<severity>"
}

to override the severity, or

{
  "<rule>": ""
}

to keep the original severity.

Example

{
  "oelint.file.includenotfound": "",
  "oelint.file.requirenotfound": "warning"
}

would enable the two rules oelint.file.includenotfound and oelint.file.requirenotfound. The severity of oelint.file.includenotfound will be the default of the tool, while oelint.file.requirenotfound will report warning instead of the original suggested severity.

Adding additional constants

Please see oelint-parser for further details, how to add your own constants to the parser.

Output message format

You can freely define a custom output format. The following placeholder symbols will be automatically replaced

name replaced by
{path} path of the file
{line} line of the finding
{severity} severity of the finding
{id} error-ID of the finding
{msg} description of the finding
{wikiurl} a link to the online wiki

Configuration file

You can define your own global or project wide defaults for all CLI parameters with an ini-style configuration file.

In the following order files are probed

  • file pointed to by environment variable OELINT_CONFIG
  • file .oelint.cfg in current work directory
  • file .oelint.cfg in your HOME directory

Explicitly passed options to CLI are always chosen over the defaults defined by the configuration file.

To skip the loading of any configuration file, set OELINT_SKIP_CONFIG to a non empty value in your environment.

File format

[oelint]
# this will set the --hide warning parameter automatically
hide = warning
# this will set A + B as suppress item
# use indent (tab) and line breaks for multiple items
suppress = 
  A
  B
# this will set messageformat parameter
messageformat = {severity}:{id}:{msg}
# will configure --release to dunfell
release=dunfell

You can find an example file here

Inline suppression

You can suppress one or more checks on a line by line basis

# nooelint: <id>[,<id>,...]

suppresses all the specified IDs for the next line. Multiple IDs can be separated by commas.

Example

# nooelint: oelint.vars.insaneskip
INSANE_SKIP:${PN} = "foo"

will not warn about the usage of INSANE_SKIP.

Configure your custom machine or distro settings

You can let oelint-adv know about your custom MACHINE and DISTRO overrides, so they won't produce any findings, when used in your setup.

Create a layer specific oelint configuration file

Copy over the template this file to the root of your layer

LAYER_PATH=<path to your layer>
cp docs/.oelint.cfg.custom-layer $LAYER_PATH/.oelint.cfg

Create the known MACHINE and DISTRO settings

Source your bitbake build directory and run the following commands (**) (***)

LAYER_PATH=<path to your layer>
bitbake-getvar --quiet --value MACHINEOVERRIDES | tr ':' '\n' | jq -Rn  '{replacements:{ machines: [inputs]}}' > $LAYER_PATH/.oelint-custom-machines.json
bitbake-getvar --quiet --value DISTROOVERRIDES | tr ':' '\n' | jq -Rn  '{replacements:{ distros: [inputs]}}' > $LAYER_PATH/.oelint-custom-distros.json

(**) you'll need to have jq installed on your local machine.

(***) bitbake-getvar command is available since kirkstone release. For older release you can use bitbake core-image-minimal -e | grep ^MACHINEOVERRIDES resp. bitbake core-image-minimal -e | grep ^DISTROOVERRIDES and pass them into the rest of the pipe.

vscode extension

Find the extension in the marketplace, or search for oelint-vscode.

Vim / NeoVim integration

Integration for Vim / NeoVim is provided by ale or nvim-lint.

Jenkins integration

Jenkins integration is provided by warnings-ng.

Use as a library

To use the linter as part of calling application do

from oelint_adv.core import create_lib_arguments, run

args = create_lib_arguments(['file to check', 'another file to check']])

# check the docstring of create_lib_arguments for more options

results = run(args)

# the results will be a List[Tuple[Tuple[str, int], str]]
# each item is
#  [0] - 'path to the finding', 'line of the finding'
#  [1] - 'message'

The caller is responsible for appropriate exception handling

Missing anything?

You think there's something missing, wrong, 'improvable'... Just file an issue to get in contact.

Contribute

Any sort of ideas, pull requests, bug reports, reports of false positives are welcome. This project is open to anyone - no pitfalls or legal inconveniences.

oelint-adv's People

Contributors

amuetzel avatar angus71 avatar antznin avatar dependabot[bot] avatar dwagenk avatar gstroz avatar herrmuellerluedenscheid avatar jetm avatar jm-costa avatar lbarthelemy avatar mario-goulart avatar mersho avatar mzink89 avatar noahp avatar offa avatar plangowski avatar priv-kweihmann avatar rahix avatar sangmo-kang avatar skycaptain avatar trainmaster avatar uvv-gh avatar vermaete avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

oelint-adv's Issues

Close output stream

Deepcode.ai found the issue 'Missing close for open, add close or use a "with" block.' in main.py:59 -> Fix it

False positive for oelint.var.override

Snippet

COMPATIBLE_MACHINE_armv4 = "(!.*armv4).*"
COMPATIBLE_MACHINE_armv5 = "(!.*armv5).*"
COMPATIBLE_MACHINE_mips64 = "(!.*mips64).*"

COMPATIBLE_HOST_riscv64 = "null"
COMPATIBLE_HOST_riscv32 = "null"

Rule: check on CVE_PRODUCT being set

cve-check.bbclass is working with CVE_PRODUCT and CVE_VERSION. To make it fully work it is advisable to have them set explicitly. Cover this by a rule

Rule: SRC_URI shall not contain wildcards

Because wildcards or simple just folders can't be resolved by the bitbake task-cache/hash, leading to the effect that a source change might not be recognized in the recipe

Add rule: sort alphabetically DEPENDS and RDEPENDS entries

This rule is not based in OE style, but I have found useful to sort alphabetically DEPENDS and RDEPENDS to avoid duplicated entries in recipes with long [R]DEPENDS lists. Example:

DEPENDS_${PN} = "foo"
DEPENDS_${PN} += "bar"

It will become:

DEPENDS_${PN} = "bar"
DEPENDS_${PN} += "foo"

There is a case that would require more work to apply this rule. Bitbake allows put all the entries in one line, but with the time, that line will increase and will be harder to review it. That is why one recipe per line with [R]DEPENDS is better. Example:

DEPENDS = "foo bar"

Preferred style:

DEPENDS = "bar"
DEPENDS += "foo"

So, maybe this issue could become in two separated rules; one to sort the [R]DEPENDS entries and 2nd to convert on the one line [R]DEPENDS entries in separated lines. The latter could do both things, but found easier to do the former.

Add rule: variable append instead of overwrite

An assignment like
DEPENSDS= "foo"
could easily overwrite any previously included DEPENDS, without further notice - Let's warn about that, esp if inherit or include statements are used in the recipe (which is commonly the case)

Rule: inconsitent use of spaces

This one is from the bitbake mailing list:

  • Avoid adding extra whitespace when using += and =+
    BAD: FOO += " bar"
    OKAY: FOO += "bar"

  • Avoid forgetting to add whitespace when appending via override syntax.
    BAD: FOO_append = "bar"
    OKAY: FOO_append = " bar"

sounds like a good idea for some linting rules

Add some tests

As the functionality of this tool is becoming more and more complex it might be a good idea to add some automatic tests to cover up things

Rule: task order

#14 should give the basis to analyze the task order - issue an error when somethings is breaking this

v1.9.0 fails to install with pip

I'm having trouble getting version 1.9.0 to install with pip.

$ pip3 install -Iv oelint-adv==1.9.0                                                                                  1 ↵
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
Defaulting to user installation because normal site-packages is not writeable
Created temporary directory: /tmp/pip-ephem-wheel-cache-q7_bw_w8
Created temporary directory: /tmp/pip-req-tracker-_ad0eh_k
Initialized build tracking at /tmp/pip-req-tracker-_ad0eh_k
Created build tracker: /tmp/pip-req-tracker-_ad0eh_k
Entered build tracker: /tmp/pip-req-tracker-_ad0eh_k
Created temporary directory: /tmp/pip-install-04x1s335
1 location(s) to search for versions of oelint-adv:
* https://pypi.org/simple/oelint-adv/
Fetching project page and analyzing links: https://pypi.org/simple/oelint-adv/
Getting page https://pypi.org/simple/oelint-adv/
Found index url https://pypi.org/simple
Looking up "https://pypi.org/simple/oelint-adv/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): pypi.org:443
https://pypi.org:443 "GET /simple/oelint-adv/ HTTP/1.1" 304 0
  Found link https://files.pythonhosted.org/packages/d6/ba/4af739e2b02b0469176b130722106bd89838ac34569cc288533dc0f5d34b/oelint_adv-1.1.0.tar.gz#sha256=28c672b085dd1a5e8acf6eccd86b7f82beac274a50e361825b212a796d01c0c7 (from https://pypi.org/simple/oelint-adv/), version: 1.1.0
  Found link https://files.pythonhosted.org/packages/38/dc/e54faca0c0daca6ea24c109e8211c90df6aa0feee11a659dbe6ebcc1e69d/oelint_adv-1.2.0.tar.gz#sha256=af1fe88435226ce56048c31ea484d4231c135b7c4d1f0b81b6d2f8afe92c6d02 (from https://pypi.org/simple/oelint-adv/), version: 1.2.0
  Found link https://files.pythonhosted.org/packages/e0/87/cf14cae6062817de4696c51cded17db3aa37070d868590a60f127f24bfeb/oelint_adv-1.3.0.tar.gz#sha256=19f956d203e413f3ffffd84588962c8d6fb32618a7b59fa42c2f8d89744ba1f5 (from https://pypi.org/simple/oelint-adv/), version: 1.3.0
  Skipping link: unsupported archive format: .egg: https://files.pythonhosted.org/packages/aa/33/084b883e259f0653ee03161a93cc572d619bb4b9b4e0f92fd4a2545a2663/oelint_adv-1.4.0-py3.6.egg#sha256=802599ab3a4115961a276e19960a4648259ff0c6395378c072d1a91498f36d41 (from https://pypi.org/simple/oelint-adv/)
  Found link https://files.pythonhosted.org/packages/01/fb/55b696860db018e8b4a2d93fd142bd34c0244afa410a59cb17e2a7ad6734/oelint_adv-1.4.0.tar.gz#sha256=07dd8361802404b1653f2eb73392e0119df9c57870878e27df7fb729c3672fbe (from https://pypi.org/simple/oelint-adv/), version: 1.4.0
  Skipping link: unsupported archive format: .egg: https://files.pythonhosted.org/packages/af/ed/14159a54e1541b604c24d013033227e2a7e511e0ba4d14f0303997ad6107/oelint_adv-1.5.0-py3.6.egg#sha256=779141e160ca60a52a1c6ce98ed4528db52ae2eb6700853521c5393238b82d47 (from https://pypi.org/simple/oelint-adv/)
  Found link https://files.pythonhosted.org/packages/b9/9e/bd34c3dfa3ca0cbe15ecff82b10c40da2f8c90198b746263bc30be04944b/oelint_adv-1.5.0.tar.gz#sha256=da442e4d1600a2ac48e7122aaaaff452201db84e98dc6fb4320b9def6a94a7d6 (from https://pypi.org/simple/oelint-adv/), version: 1.5.0
  Skipping link: unsupported archive format: .egg: https://files.pythonhosted.org/packages/9a/b0/6fce129f5ac449ab6624e728300faafc49d62c59ee188ef9b57ada5450aa/oelint_adv-1.6.0-py3.6.egg#sha256=a76550b26e90911b4cf33b0c897ff6f603ebc29f7e0b3bb847aa089906ea9992 (from https://pypi.org/simple/oelint-adv/)
  Found link https://files.pythonhosted.org/packages/6c/e9/11bc48e77cbee7a11a563662f73d01b4f82251ac6f40cbd7c402be8d4183/oelint_adv-1.6.0.tar.gz#sha256=1c0070afff8a757b3434c81ff3898c64b813e73dbfcf290428f6dfc806ccd51c (from https://pypi.org/simple/oelint-adv/), version: 1.6.0
  Skipping link: unsupported archive format: .egg: https://files.pythonhosted.org/packages/97/65/c1a8e044e48339928fc8f6ba778e5e8ada077f55f08b079c402cd0ae412c/oelint_adv-1.7.0-py3.6.egg#sha256=e8b9987f5f2c7a6c9c3a909100c02ee7e0dc2c2cf210ca8fd30cc6a79af3e4d4 (from https://pypi.org/simple/oelint-adv/)
  Found link https://files.pythonhosted.org/packages/38/8b/62574cbf5ecacd34bb5e7c50b01823352c26a42a5515b8a6f6a712e94864/oelint_adv-1.7.0.tar.gz#sha256=9ea03b3e385b772f3242aa442d147fe53a2bd3d9e404cd3f77b689e266b0dee6 (from https://pypi.org/simple/oelint-adv/), version: 1.7.0
  Skipping link: unsupported archive format: .egg: https://files.pythonhosted.org/packages/c5/d8/3d5ef2cd13a8fd0fd874736cbdced33db7c59e28a77d7aff3ffc44aab81a/oelint_adv-1.8.0-py3.6.egg#sha256=0b4f1a042f3027fb95a6e2119dbc98e2664cd1cdb0287c0cdf1e522f9c37ea29 (from https://pypi.org/simple/oelint-adv/)
  Found link https://files.pythonhosted.org/packages/bb/30/74ba344fcd80879f794593932404a22da20538f3ec1e4d1ca737c92a730d/oelint_adv-1.8.0.tar.gz#sha256=d3f69d0b3e80b1cd0ed3ec61689429b29fa8b43a6952fdd6bc1194ae66fd30bd (from https://pypi.org/simple/oelint-adv/), version: 1.8.0
  Found link https://files.pythonhosted.org/packages/3e/66/890d955644bd9cc5977785a79ba607a2d7c398d37c15da74c79a5d36419c/oelint_adv-1.9.0.tar.gz#sha256=afdab496495793ca554c7d9fbc3abe03956d761d74c1adbb728e6a379ba66535 (from https://pypi.org/simple/oelint-adv/), version: 1.9.0
Given no hashes to check 1 links for project 'oelint-adv': discarding no candidates
Using version 1.9.0 (newest of versions: 1.9.0)
Collecting oelint-adv==1.9.0
  Created temporary directory: /tmp/pip-unpack-xz386b4k
  Looking up "https://files.pythonhosted.org/packages/3e/66/890d955644bd9cc5977785a79ba607a2d7c398d37c15da74c79a5d36419c/oelint_adv-1.9.0.tar.gz" in the cache
  Current age based on date: 4502
  Ignoring unknown cache-control directive: immutable
  Freshness lifetime from max-age: 365000000
  The response is "fresh", returning cached response
  365000000 > 4502
  Using cached oelint_adv-1.9.0.tar.gz (25 kB)
  Added oelint-adv==1.9.0 from https://files.pythonhosted.org/packages/3e/66/890d955644bd9cc5977785a79ba607a2d7c398d37c15da74c79a5d36419c/oelint_adv-1.9.0.tar.gz#sha256=afdab496495793ca554c7d9fbc3abe03956d761d74c1adbb728e6a379ba66535 to build tracker '/tmp/pip-req-tracker-_ad0eh_k'
    Running setup.py (path:/tmp/pip-install-04x1s335/oelint-adv/setup.py) egg_info for package oelint-adv
    Running command python setup.py egg_info
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-04x1s335/oelint-adv/setup.py", line 14, in <module>
        with open('requirements.txt') as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
Cleaning up...
  Removing source in /tmp/pip-install-04x1s335/oelint-adv
Removed oelint-adv==1.9.0 from https://files.pythonhosted.org/packages/3e/66/890d955644bd9cc5977785a79ba607a2d7c398d37c15da74c79a5d36419c/oelint_adv-1.9.0.tar.gz#sha256=afdab496495793ca554c7d9fbc3abe03956d761d74c1adbb728e6a379ba66535 from build tracker '/tmp/pip-req-tracker-_ad0eh_k'
Removed build tracker: '/tmp/pip-req-tracker-_ad0eh_k'
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
Exception information:
Traceback (most recent call last):
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/cli/base_command.py", line 186, in _main
    status = self.run(options, args)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/commands/install.py", line 331, in run
    resolver.resolve(requirement_set)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/legacy_resolve.py", line 177, in resolve
    discovered_reqs.extend(self._resolve_one(requirement_set, req))
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/legacy_resolve.py", line 333, in _resolve_one
    abstract_dist = self._get_abstract_dist_for(req_to_install)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/legacy_resolve.py", line 282, in _get_abstract_dist_for
    abstract_dist = self.preparer.prepare_linked_requirement(req)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/operations/prepare.py", line 516, in prepare_linked_requirement
    req, self.req_tracker, self.finder, self.build_isolation,
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/operations/prepare.py", line 95, in _get_prepared_distribution
    abstract_dist.prepare_distribution_metadata(finder, build_isolation)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/distributions/sdist.py", line 40, in prepare_distribution_metadata
    self.req.prepare_metadata()
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/req/req_install.py", line 564, in prepare_metadata
    self.metadata_directory = self._generate_metadata()
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/req/req_install.py", line 544, in _generate_metadata
    details=self.name or "from {}".format(self.link)
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/operations/build/metadata_legacy.py", line 118, in generate_metadata
    command_desc='python setup.py egg_info',
  File "/home/gstroz/.local/lib/python3.6/site-packages/pip/_internal/utils/subprocess.py", line 242, in call_subprocess
    raise InstallationError(exc_msg)
pip._internal.exceptions.InstallationError: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

v1.8.0 is able to install successfully. I have tried this in my default python environment as well as in a venv. The error message is the same.

~/dev/na(master*) » pip3 --version                                                                                                      1 ↵
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
pip 20.0.2 from /home/gstroz/.local/lib/python3.6/site-packages/pip (python 3.6)

Rule: warn about hardcoded paths

Warn about stuff like /usr/share, which should be ${datadir}

path variable
/usr/bin ${bindir}
/usr/share ${datadir}
/usr/share/doc ${docdir}
/usr/include ${includedir}
/usr/share/info ${infodir}
/usr/lib ${libdir}
/usr/libexec ${libexecdir}
/var ${localstatedir}
/usr/share/man ${mandir}
/lib ${nonarch_base_libdir}
/usr/lib ${nonarch_libdir}
/usr/include ${oldincludedir}
/usr/sbin ${sbindir}
/srv ${servicedir}
/com ${sharedstatedir}
/etc ${sysconfdir}
/lib/systemd/system ${systemd_system_unitdir}
/lib/systemd ${systemd_unitdir}
/usr/lib/systemd/user ${systemd_user_unitdir}

Switch to requirements.txt

To use github features such as security alerts, a requirements.txt is needed, instead of coding them into setup.py

Create CI pipeline

Create a CI pipeline (preferably using Travis CI) which does build and run all tests for each push + PR

Rule: Warn about misconfiguration in SRC_URI

It happened to me that I wrote

git://some.tld/some.git;protcol=https

instead of

git://some.tld/some.git;protocol=https

Which wasn't an issue on the development machine, but on another machine I was running the recipe it didn't run fetch properly.

So it would be good to analyze the SRC_URI entries a little bit more to warn about such issues

oelint false positive 'HOMEPAGE' should start with 'http://' or 'https://'

<?xml version="1.0" ?>
<checkstyle version="4.3">
  <file name="/tmp/yocto-autobuilder/yocto-autobuilder/yocto-worker/poky/build/imx6q-phytec-mira-rdk-nand-virt-wic/tmp/deploy/images/imx6q-phytec-mira-rdk-nand/sca/sources/simple-hello-world/tmp/yocto-autobuilder/yocto-autobuilder/yocto-worker/poky/sources/meta-resy/recipes-connectivity/simple-hello-world/simple-hello-world_1.0.0.bb">
    <error column="1" line="10" message="[Package:simple-hello-world Tool:oelint] 'HOMEPAGE' should start with 'http://' or 'https://'" severity="warning" source="oelint.oelint_vars_homepageprefix"/>
    <error column="1" line="13" message="[Package:simple-hello-world Tool:oelint] License-File should be a remote file" severity="warning" source="oelint.oelint_var_licenseremotefile"/>
  </file>
</checkstyle>
#
#   Copyright (C) 2019 Robert Berger - Reliable Embedded Systems e.U.
#   SPDX-License-Identifier: MIT
#

# Proper header as required by oelint
SUMMARY = "A simple hello world C application"
DESCRIPTION = "Simple helloworld application"
AUTHOR = "Robert Berger  <[email protected]>"
HOMEPAGE = "https://www.ReliableEmbeddedSystems.com"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://simple-hello-world.c"
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.