Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Baptiste Lab committed Jan 9, 2023
2 parents 53aa6d4 + 6f53a5f commit c2907ce
Show file tree
Hide file tree
Showing 15 changed files with 365 additions and 76 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Python package

on:
push:
branches: [master]

pull_request:
branches: [master]

workflow_dispatch:

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# note: 3.5 + 3.6 are EOL as of 2022-09-16. tests do fail on python3.5,
# see https://github.com/HBehrens/puncover/issues/36
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
# it's convenient to stay on an older ubuntu as long as we need
# python3.6:
# https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
os: [
ubuntu-20.04,
macos-12,
# windows is disabled until path support works there
# windows-2022,
]
fail-fast: false

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
# this is the latest version of pip that supports python 3.6
# install a specific version to hopefully avoid breakage
pip install --upgrade pip==21.3.1
pip install -r requirements-test.txt
- name: Run tox
# use the version of python in PATH, from the github runner
run: tox -e py

- name: Build release archive
# only upload coverage for the 3.10 run
if: ${{ matrix.python-version == '3.10' }}
run: |
pip install wheel==0.37.1
python setup.py sdist bdist_wheel
- name: Archive release
if: ${{ matrix.python-version == '3.10' }}
uses: actions/upload-artifact@v3
with:
name: release_dist
path: dist

- name: Upload coverage to Codecov
# only upload coverage for the 3.10 run
if: ${{ matrix.python-version == '3.10' }}
uses: codecov/codecov-action@v3
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
**/.idea/
*.pyc
/puncover.egg-info/
*.egg-info/
/build/
/dist/
/dist/
.tox
.coverage
6 changes: 6 additions & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
3.6.15
3.7.15
3.8.15
3.9.15
3.10.8
3.11.0
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

4 changes: 3 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
include requirements.txt
include requirements-test.txt
include puncover/static/**/*
include puncover/templates/**
include puncover/templates/**
124 changes: 118 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,125 @@
.. image:: https://img.shields.io/travis/HBehrens/puncover.svg
:target: https://travis-ci.org/HBehrens/puncover
.. image:: https://img.shields.io/codecov/c/github/HBehrens/puncover.svg
:target: https://codecov.io/gh/HBehrens/puncover

.. image:: https://img.shields.io/badge/GitHub-HBehrens/puncover-8da0cb?style=flat-square&logo=github
:alt: GitHub Link
:target: https://github.com/HBehrens/puncover

.. image:: https://img.shields.io/github/actions/workflow/status/HBehrens/puncover/ci.yml?style=flat-square&branch=master
:alt: GitHub Workflow Status (branch)
:target: https://github.com/HBehrens/puncover/actions?query=branch%3Amaster+

.. image:: https://img.shields.io/codecov/c/github/HBehrens/puncover/master?style=flat-square
:alt: Codecov branch
:target: https://codecov.io/gh/HBehrens/puncover

.. image:: https://img.shields.io/pypi/v/puncover?style=flat-square
:alt: PyPI
:target: https://pypi.org/project/puncover

.. image:: https://img.shields.io/pypi/pyversions/puncover?style=flat-square
:alt: PyPI - Python Version
:target: https://pypi.org/project/puncover

.. image:: https://img.shields.io/github/license/HBehrens/puncover?color=blue&style=flat-square
:alt: License - MIT
:target: https://github.com/HBehrens/puncover

puncover
========

.. image:: https://raw.githubusercontent.com/HBehrens/puncover/master/images/overview.png

Analyzes C/C++ binaries for code size, static variables and stack usages.
It creates a report with dissambler and call-stack analysis per directory, file, or function.
Analyzes C/C++ binaries for code size, static variables and stack usages. It
creates a report with disassembler and call-stack analysis per directory, file,
or function.

Installation and Usage
======================

Install with pip:

.. code-block:: bash
pip install puncover
Run it by passing the binary to analyze:

.. code-block:: bash
puncover --elf_file project.elf
...
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Open the link in your browser to view the analysis.

Running Tests Locally
=====================

To run the tests locally, you need to install the development dependencies:

1. install pyenv: https://github.com/pyenv/pyenv

.. code-block:: bash
curl https://pyenv.run | bash
2. install all the python environments, using this bashism (this can take a few
minutes):

.. code-block:: bash
for _py in $(<.python-version ); do pyenv install ${_py}; done
3. install the development dependencies:

.. code-block:: bash
pip install -r requirements-dev.txt
Then you can run the tests with:

.. code-block:: bash
tox
Publishing Release
==================

1. Update the version in ``puncover/__version__.py``.
2. Commit the version update:
.. code-block:: bash
git add . && git commit -m "Bump version to x.y.z"


3. Create an annotated tag:
.. code-block:: bash
git tag -a {-m=,}x.y.z

4. Push the commit and tag:
.. code-block:: bash
git push && git push --tags

5. Either wait for the GitHub Action to complete and download the release
artifact for uploading: https://github.com/HBehrens/puncover/actions OR Build
the package locally: ``python setup.py sdist bdist_wheel``
6. Upload the package to PyPI:
.. code-block:: bash
twine upload dist/*

7. Create GitHub releases:
- ``gh release create --generate-notes x.y.z``
- attach the artifacts to the release too: ``gh release upload x.y.z dist/*``

Release Script
--------------

See ``scripts/release.sh`` for a script that automates the above steps.

Contributing
============

Contributions are welcome! Please open an issue or pull request on GitHub.
2 changes: 1 addition & 1 deletion puncover/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def parse_stack_usage_line(self, line):
if not match:
return False

base_file_name = match.group(1)
base_file_name = os.path.basename(match.group(1)) # Seems this can sometimes be the complete file name instead of base_file_name
line = int(match.group(3))
symbol_name = match.group(5)
stack_size = int(match.group(6))
Expand Down
27 changes: 23 additions & 4 deletions puncover/puncover.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

import argparse
import os
import webbrowser
from distutils.spawn import find_executable
from flask import Flask
from os.path import dirname
from puncover.collector import Collector
from puncover.builders import ElfBuilder
from puncover.middleware import BuilderMiddleware
from threading import Timer

from flask import Flask

from puncover import renderers
from puncover.builders import ElfBuilder
from puncover.collector import Collector
from puncover.gcc_tools import GCCTools
from puncover.middleware import BuilderMiddleware
from puncover.version import __version__


def create_builder(gcc_base_filename, elf_file=None, su_dir=None, src_root=None):
c = Collector(GCCTools(gcc_base_filename))
if elf_file:
Expand All @@ -27,6 +32,10 @@ def find_arm_tools_location():
return dirname(dirname(obj_dump)) if obj_dump else None


def open_browser(host, port):
webbrowser.open_new("http://{}:{}/".format(host, port))


def main():
parser = argparse.ArgumentParser(
description="Analyses C/C++ build output for code size, static variables, and stack usage.")
Expand All @@ -46,6 +55,8 @@ def main():
help='port the HTTP server runs on')
parser.add_argument('--host', dest='host', default='127.0.0.1',
help='host IP the HTTP server runs on')
parser.add_argument('--no-open-browser', action='store_true',
help="don't automatically open a browser window")
args = parser.parse_args()

if not args.gcc_tools_base:
Expand All @@ -62,6 +73,14 @@ def main():

if args.debug:
app.debug = True

# Open a browser window, only if this is the first instance of the server
# from https://stackoverflow.com/a/63216793
if not args.no_open_browser and not os.environ.get("WERKZEUG_RUN_MAIN"):
# wait one second before starting, so the flask server is ready and we
# don't see a 404 for a moment first
Timer(1, open_browser, kwargs={"host":args.host, "port":args.port}).start()

app.run(host=args.host, port=args.port)


Expand Down
Loading

0 comments on commit c2907ce

Please sign in to comment.