ledgered 0.9.1.dev4__tar.gz → 0.10.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. ledgered-0.10.1/.github/workflows/build_and_tests.yml +69 -0
  2. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/.github/workflows/codeql-analysis.yml +4 -0
  3. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/.github/workflows/fast-checks.yml +4 -0
  4. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/CHANGELOG.md +17 -0
  5. ledgered-0.10.1/MANIFEST.in +1 -0
  6. {ledgered-0.9.1.dev4/src/ledgered.egg-info → ledgered-0.10.1}/PKG-INFO +3 -2
  7. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/pyproject.toml +2 -1
  8. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/__version__.py +2 -2
  9. ledgered-0.10.1/src/ledgered/devices/__init__.py +81 -0
  10. ledgered-0.10.1/src/ledgered/devices/devices.json +7 -0
  11. ledgered-0.10.1/src/ledgered/manifest/__init__.py +6 -0
  12. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/app.py +2 -7
  13. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/constants.py +0 -1
  14. {ledgered-0.9.1.dev4 → ledgered-0.10.1/src/ledgered.egg-info}/PKG-INFO +3 -2
  15. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered.egg-info/SOURCES.txt +5 -0
  16. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered.egg-info/requires.txt +2 -1
  17. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/full_correct.toml +1 -1
  18. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/functional/manifest/test_cli.py +2 -2
  19. ledgered-0.10.1/tests/unit/devices/test___init__.py +65 -0
  20. ledgered-0.10.1/tests/unit/manifest/__init__.py +0 -0
  21. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/manifest/test_app.py +3 -5
  22. ledgered-0.9.1.dev4/.github/workflows/build_and_tests.yml +0 -154
  23. ledgered-0.9.1.dev4/src/ledgered/manifest/__init__.py +0 -6
  24. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/.codecov.yml +0 -0
  25. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/.gitignore +0 -0
  26. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/.pre-commit-config.yaml +0 -0
  27. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/LICENSE +0 -0
  28. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/README.md +0 -0
  29. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/doc/binary.md +0 -0
  30. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/doc/manifest.md +0 -0
  31. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/setup.cfg +0 -0
  32. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/__init__.py +0 -0
  33. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/binary.py +0 -0
  34. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/github.py +0 -0
  35. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/cli.py +0 -0
  36. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/errors.py +0 -0
  37. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/manifest.py +0 -0
  38. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/tests.py +0 -0
  39. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/use_cases.py +0 -0
  40. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/manifest/utils.py +0 -0
  41. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/serializers.py +0 -0
  42. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered/utils/__init__.py +0 -0
  43. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered.egg-info/dependency_links.txt +0 -0
  44. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered.egg-info/entry_points.txt +0 -0
  45. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/src/ledgered.egg-info/top_level.txt +0 -0
  46. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/Cargo.toml +0 -0
  47. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/Makefile +0 -0
  48. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/ledger_app.toml +0 -0
  49. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/minimal.toml +0 -0
  50. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/_data/one_leaf.toml +0 -0
  51. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/functional/__init__.py +0 -0
  52. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/functional/conftest.py +0 -0
  53. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/functional/manifest/__init__.py +0 -0
  54. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/functional/test_github.py +0 -0
  55. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/__init__.py +0 -0
  56. {ledgered-0.9.1.dev4/tests/unit/manifest → ledgered-0.10.1/tests/unit/devices}/__init__.py +0 -0
  57. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/manifest/test_manifest.py +0 -0
  58. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/manifest/test_tests.py +0 -0
  59. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/manifest/test_use_cases.py +0 -0
  60. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/test_binary.py +0 -0
  61. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/test_github.py +0 -0
  62. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/test_github_AppRepository.py +0 -0
  63. {ledgered-0.9.1.dev4 → ledgered-0.10.1}/tests/unit/test_serializers.py +0 -0
@@ -0,0 +1,69 @@
1
+ name: Build, test and deploy Ledgered
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - '*'
8
+ branches:
9
+ - master
10
+ - develop
11
+ pull_request:
12
+ branches:
13
+ - master
14
+ - develop
15
+ paths:
16
+ - 'src/**'
17
+ - 'tests/**'
18
+ - .github/workflows/build_and_tests.yml
19
+ # Cancel previous runs on this reference
20
+ concurrency:
21
+ group: ${{ github.workflow }}-${{ github.ref }}
22
+ cancel-in-progress: true
23
+
24
+
25
+ jobs:
26
+
27
+ build_install_test:
28
+ name: Build, install and test the Ledgered Python package
29
+ runs-on: ubuntu-latest
30
+ strategy:
31
+ fail-fast: false
32
+ matrix:
33
+ python_version: ['3.9', '3.10', '3.11', '3.12', '3.13']
34
+ steps:
35
+ - name: Clone
36
+ uses: actions/checkout@v4
37
+
38
+ - name: Setup Python version
39
+ uses: actions/setup-python@v5
40
+ with:
41
+ python-version: ${{ matrix.python_version }}
42
+
43
+ - name: Build & install
44
+ run: |
45
+ pip install -U pip
46
+ pip install -U .[dev]
47
+
48
+ - name: Run unit tests and generate coverage
49
+ run: pytest -v --tb=short tests/unit --cov ledgered --cov-report xml
50
+
51
+ - name: Run functional tests and generate coverage
52
+ run: pytest -v --tb=short tests/functional --cov ledgered --cov-report xml --cov-append --token "${{ secrets.GITHUB_TOKEN }}"
53
+
54
+ - name: Upload coverage to Codecov
55
+ uses: codecov/codecov-action@v4
56
+ with:
57
+ name: codecov-ledgered
58
+ token: ${{ secrets.CODECOV_TOKEN }}
59
+
60
+
61
+ package_and_deploy:
62
+ name: Build and deploy the Ledgered Python package
63
+ needs: [build_install_test]
64
+ uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_pypi_deployment.yml@v1
65
+ with:
66
+ package_name: ledgered
67
+ publish: ${{ startsWith(github.ref, 'refs/tags/') }}
68
+ secrets:
69
+ pypi_token: ${{ secrets.PYPI_PUBLIC_API_TOKEN }}
@@ -15,6 +15,10 @@ on:
15
15
  - tests
16
16
  schedule:
17
17
  - cron: '35 0 * * 5'
18
+ # Cancel previous runs on this reference
19
+ concurrency:
20
+ group: ${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: true
18
22
 
19
23
  jobs:
20
24
  analyze:
@@ -7,6 +7,10 @@ on:
7
7
  - develop
8
8
  - master
9
9
  pull_request:
10
+ # Cancel previous runs on this reference
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
10
14
 
11
15
  jobs:
12
16
  ruff:
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.10.1] - 2025-05-14
9
+
10
+ ### Fix
11
+
12
+ - Parsing 'nanos+' in manifests now returns 'nanosp', which is breaking when this name is used to
13
+ gather a SDK tag.
14
+ Added a specific "sdk_name" field in the JSON / `Device` to be returned when parsing the manifest,
15
+ to get back the previous, 0.9.1- behavior.
16
+
17
+ ## [0.10.0] - 2025-05-09
18
+
19
+ ### Added
20
+
21
+ - Added `devices` module, declaring Ledger devices as class / enum, dynamically generated from a
22
+ JSON configuration file. This should enable to add new devices more easily, and device
23
+ characteristics are now reachable from a centralized place.
24
+
8
25
  ## [0.9.1] - 2025-03-26
9
26
 
10
27
  ### Fixed
@@ -0,0 +1 @@
1
+ include src/ledgered/devices.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ledgered
3
- Version: 0.9.1.dev4
3
+ Version: 0.10.1
4
4
  Summary: Python tools, utils, libraries, to be used with Ledger cryptodevices
5
5
  Author-email: Ledger <hello@ledger.fr>
6
6
  License: MIT License
@@ -40,9 +40,10 @@ Classifier: Typing :: Typed
40
40
  Requires-Python: >=3.9
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
- Requires-Dist: toml
43
+ Requires-Dist: pydantic
44
44
  Requires-Dist: pyelftools
45
45
  Requires-Dist: pygithub
46
+ Requires-Dist: toml
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: pytest; extra == "dev"
48
49
  Requires-Dist: pytest-cov; extra == "dev"
@@ -30,9 +30,10 @@ classifiers = [
30
30
  dynamic = [ "version" ]
31
31
  requires-python = ">=3.9"
32
32
  dependencies = [
33
- "toml",
33
+ "pydantic",
34
34
  "pyelftools",
35
35
  "pygithub",
36
+ "toml",
36
37
  ]
37
38
 
38
39
  [project.optional-dependencies]
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.9.1.dev4'
21
- __version_tuple__ = version_tuple = (0, 9, 1, 'dev4')
20
+ __version__ = version = '0.10.1'
21
+ __version_tuple__ = version_tuple = (0, 10, 1)
@@ -0,0 +1,81 @@
1
+ import dataclasses
2
+ import json
3
+ from enum import IntEnum, auto
4
+ from pathlib import Path
5
+ from pydantic.dataclasses import dataclass
6
+ from typing import Optional
7
+
8
+
9
+ class DeviceType(IntEnum):
10
+ NANOS = auto()
11
+ NANOSP = auto()
12
+ NANOX = auto()
13
+ STAX = auto()
14
+ FLEX = auto()
15
+
16
+
17
+ @dataclass
18
+ class Resolution:
19
+ x: int
20
+ y: int
21
+
22
+
23
+ @dataclass
24
+ class Device:
25
+ type: DeviceType
26
+ resolution: Resolution
27
+ touchable: bool = True
28
+ deprecated: bool = False
29
+ names: list[str] = dataclasses.field(default_factory=lambda: [])
30
+ _sdk_name: Optional[str] = None
31
+
32
+ @property
33
+ def name(self) -> str:
34
+ """
35
+ Returns the name of the current firmware's device
36
+ """
37
+ return self.type.name.lower()
38
+
39
+ @property
40
+ def sdk_name(self) -> str:
41
+ """
42
+ Returns the SDK name, meaning the device name used to tag the SDK.
43
+ If the device does not have a SDK name, returns the default name
44
+ """
45
+ return self._sdk_name or self.name
46
+
47
+ @property
48
+ def is_nano(self):
49
+ """
50
+ States if the firmware's name starts with 'nano' or not.
51
+ """
52
+ return self.type in [DeviceType.NANOS, DeviceType.NANOSP, DeviceType.NANOX]
53
+
54
+ @classmethod
55
+ def from_dict(cls, dico: dict) -> "Device":
56
+ type = dico.pop("type")
57
+ dico["type"] = DeviceType[type.upper()]
58
+ return Device(**dico)
59
+
60
+
61
+ class Devices:
62
+ _devices_file = Path(__file__).absolute().parent / "devices.json"
63
+ with _devices_file.open() as filee:
64
+ _devices = json.load(filee)
65
+
66
+ DEVICE_DATA = {item.type: item for item in [Device.from_dict(i) for i in _devices]}
67
+
68
+ def __iter__(self):
69
+ for d in self.DEVICE_DATA.values():
70
+ yield d
71
+
72
+ @classmethod
73
+ def get_by_type(cls, device_type: DeviceType) -> Device:
74
+ return cls.DEVICE_DATA[device_type]
75
+
76
+ @classmethod
77
+ def get_by_name(cls, name: str) -> Device:
78
+ for device in cls.DEVICE_DATA.values():
79
+ if name.lower() == device.name or name.lower() in device.names:
80
+ return device
81
+ raise KeyError(f"Device named '{name}' unknown")
@@ -0,0 +1,7 @@
1
+ [
2
+ {"type": "nanos", "resolution": {"x": 128, "y": 32}, "touchable": false, "deprecated": true},
3
+ {"type": "nanosp", "resolution": {"x": 128, "y": 64}, "touchable": false, "names": ["nanos+", "nanos2", "nanosplus"], "_sdk_name": "nanos+"},
4
+ {"type": "nanox", "resolution": {"x": 128, "y": 64}, "touchable": false},
5
+ {"type": "flex", "resolution": {"x": 480, "y": 600}},
6
+ {"type": "stax", "resolution": {"x": 400, "y": 670}}
7
+ ]
@@ -0,0 +1,6 @@
1
+ from .app import AppConfig
2
+ from .constants import MANIFEST_FILE_NAME
3
+ from .manifest import Manifest
4
+ from .tests import TestsConfig
5
+
6
+ __all__ = ["AppConfig", "Manifest", "MANIFEST_FILE_NAME", "TestsConfig"]
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from typing import Iterable, Union
4
4
 
5
5
  from ledgered.serializers import Jsonable, JsonSet
6
- from .constants import EXISTING_DEVICES
6
+ from ledgered.devices import Devices
7
7
 
8
8
 
9
9
  @dataclass
@@ -18,12 +18,7 @@ class AppConfig(Jsonable):
18
18
  raise ValueError(f"'{sdk}' unknown. Must be either 'C' or 'Rust'")
19
19
  self.sdk = sdk
20
20
  self.build_directory = Path(build_directory)
21
- devices = JsonSet(device.lower() for device in devices)
22
- unknown_devices = devices.difference(EXISTING_DEVICES)
23
- if unknown_devices:
24
- unknown_devices_str = "', '".join(unknown_devices)
25
- raise ValueError(f"Unknown devices: '{unknown_devices_str}'")
26
- self.devices = devices
21
+ self.devices = JsonSet(Devices.get_by_name(device).sdk_name for device in devices)
27
22
 
28
23
  @property
29
24
  def is_rust(self) -> bool:
@@ -1,3 +1,2 @@
1
- EXISTING_DEVICES = ["nanos", "nanox", "nanos+", "stax", "flex"]
2
1
  MANIFEST_FILE_NAME = "ledger_app.toml"
3
2
  DEFAULT_USE_CASE = "default"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ledgered
3
- Version: 0.9.1.dev4
3
+ Version: 0.10.1
4
4
  Summary: Python tools, utils, libraries, to be used with Ledger cryptodevices
5
5
  Author-email: Ledger <hello@ledger.fr>
6
6
  License: MIT License
@@ -40,9 +40,10 @@ Classifier: Typing :: Typed
40
40
  Requires-Python: >=3.9
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
- Requires-Dist: toml
43
+ Requires-Dist: pydantic
44
44
  Requires-Dist: pyelftools
45
45
  Requires-Dist: pygithub
46
+ Requires-Dist: toml
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: pytest; extra == "dev"
48
49
  Requires-Dist: pytest-cov; extra == "dev"
@@ -3,6 +3,7 @@
3
3
  .pre-commit-config.yaml
4
4
  CHANGELOG.md
5
5
  LICENSE
6
+ MANIFEST.in
6
7
  README.md
7
8
  pyproject.toml
8
9
  .github/workflows/build_and_tests.yml
@@ -21,6 +22,8 @@ src/ledgered.egg-info/dependency_links.txt
21
22
  src/ledgered.egg-info/entry_points.txt
22
23
  src/ledgered.egg-info/requires.txt
23
24
  src/ledgered.egg-info/top_level.txt
25
+ src/ledgered/devices/__init__.py
26
+ src/ledgered/devices/devices.json
24
27
  src/ledgered/manifest/__init__.py
25
28
  src/ledgered/manifest/app.py
26
29
  src/ledgered/manifest/cli.py
@@ -47,6 +50,8 @@ tests/unit/test_binary.py
47
50
  tests/unit/test_github.py
48
51
  tests/unit/test_github_AppRepository.py
49
52
  tests/unit/test_serializers.py
53
+ tests/unit/devices/__init__.py
54
+ tests/unit/devices/test___init__.py
50
55
  tests/unit/manifest/__init__.py
51
56
  tests/unit/manifest/test_app.py
52
57
  tests/unit/manifest/test_manifest.py
@@ -1,6 +1,7 @@
1
- toml
1
+ pydantic
2
2
  pyelftools
3
3
  pygithub
4
+ toml
4
5
 
5
6
  [dev]
6
7
  pytest
@@ -1,7 +1,7 @@
1
1
  [app]
2
2
  build_directory = "./"
3
3
  sdk = "C"
4
- devices = ["nanox"]
4
+ devices = ["nanos+"]
5
5
 
6
6
  [use_cases]
7
7
  debug = "DEBUG=1"
@@ -20,7 +20,7 @@ class PrintMock(MagicMock):
20
20
  FULL_EXPECTED_TEXT = """build_directory: .
21
21
  sdk: c
22
22
  devices:
23
- 0. nanox
23
+ 0. nanos+
24
24
  use_cases:
25
25
  debug: DEBUG=1
26
26
  test: DEBUG=1
@@ -31,7 +31,7 @@ tests:
31
31
  FULL_EXPECTED_JSON = {
32
32
  "build_directory": ".",
33
33
  "sdk": "c",
34
- "devices": ["nanox"],
34
+ "devices": ["nanos+"],
35
35
  "use_cases": {"debug": "DEBUG=1", "test": "DEBUG=1"},
36
36
  "tests": {"unit_directory": "tests/unit", "pytest_directory": "tests/functional"},
37
37
  }
@@ -0,0 +1,65 @@
1
+ from ledgered.devices import Device, DeviceType, Devices, Resolution
2
+ from unittest import TestCase
3
+
4
+
5
+ class TestDevice(TestCase):
6
+ def setUp(self):
7
+ self.res = Resolution(x=10, y=20)
8
+
9
+ def test___init__simple(self):
10
+ type = DeviceType.NANOS
11
+ device = Device(type, self.res)
12
+ self.assertEqual(device.type, type)
13
+ self.assertEqual(device.touchable, True)
14
+ self.assertFalse(device.deprecated)
15
+ self.assertEqual(device.name, type.name.lower())
16
+ self.assertEqual(device.resolution, self.res)
17
+
18
+ def test_is_nano(self):
19
+ device = Device(DeviceType.NANOS, self.res)
20
+ self.assertTrue(device.is_nano)
21
+ device = Device(DeviceType.STAX, self.res)
22
+ self.assertFalse(device.is_nano)
23
+
24
+ def test_from_dict(self):
25
+ type, touchable, deprecated = "flex", False, True
26
+ device = Device.from_dict(
27
+ {
28
+ "type": type,
29
+ "resolution": {"x": self.res.x, "y": self.res.y},
30
+ "touchable": touchable,
31
+ "deprecated": deprecated,
32
+ }
33
+ )
34
+ self.assertEqual(device.type, DeviceType[type.upper()])
35
+ self.assertEqual(device.touchable, touchable)
36
+ self.assertEqual(device.deprecated, deprecated)
37
+ self.assertEqual(device.name, type)
38
+ self.assertEqual(device.resolution, Resolution(x=self.res.x, y=self.res.y))
39
+
40
+
41
+ class TestDevices(TestCase):
42
+ def test_get_type_ok(self):
43
+ type = DeviceType.STAX
44
+ device = Devices.get_by_type(type)
45
+ self.assertIsInstance(device, Device)
46
+ self.assertEqual(device.type, type)
47
+
48
+ def test_get_type_nok(self):
49
+ with self.assertRaises(KeyError):
50
+ Devices.get_by_type(9)
51
+
52
+ def test_get_by_name_ok(self):
53
+ device = Devices.get_by_name("nanos+")
54
+ self.assertIsInstance(device, Device)
55
+ self.assertEqual(device.type, DeviceType.NANOSP)
56
+ self.assertEqual(device.name, "nanosp")
57
+ self.assertEqual(device.sdk_name, "nanos+")
58
+
59
+ def test_get_by_name_nok(self):
60
+ with self.assertRaises(KeyError):
61
+ Devices.get_by_name("non existent")
62
+
63
+ def test___iter__(self):
64
+ for d in Devices():
65
+ self.assertIsInstance(d, Device)
File without changes
@@ -12,7 +12,7 @@ class TestAppConfig(TestCase):
12
12
  config = AppConfig(sdk=sdk, build_directory=str(bd), devices=devices)
13
13
  self.assertEqual(config.sdk, sdk.lower())
14
14
  self.assertEqual(config.build_directory, bd)
15
- self.assertEqual(config.devices, {device.lower() for device in devices})
15
+ self.assertEqual(config.devices, {"nanos", "nanos+"})
16
16
  self.assertTrue(config.is_rust)
17
17
  self.assertFalse(config.is_c)
18
18
 
@@ -21,8 +21,6 @@ class TestAppConfig(TestCase):
21
21
  AppConfig(sdk="Java", build_directory=str(), devices=set())
22
22
 
23
23
  def test___init___nok_unknown_device(self):
24
- devices = {"hic sunt", "dracones"}
25
- with self.assertRaises(ValueError) as error:
24
+ devices = {"nanosp", "flex", "hic sunt", "dracones"}
25
+ with self.assertRaises(KeyError):
26
26
  AppConfig(sdk="rust", build_directory=str(), devices=devices)
27
- for device in devices:
28
- self.assertIn(device, str(error.exception))
@@ -1,154 +0,0 @@
1
- name: Build, test and deploy Ledgered
2
-
3
- on:
4
- workflow_dispatch:
5
- push:
6
- tags:
7
- - '*'
8
- branches:
9
- - master
10
- - develop
11
- pull_request:
12
- branches:
13
- - master
14
- - develop
15
- paths:
16
- - 'src/**'
17
- - 'tests/**'
18
- - .github/workflows/build_and_tests.yml
19
-
20
- jobs:
21
-
22
- build_install_test:
23
- name: Build, install and test the Ledgered Python package
24
- runs-on: ubuntu-latest
25
- strategy:
26
- fail-fast: false
27
- matrix:
28
- python_version: ['3.9', '3.10', '3.11', '3.12', '3.13']
29
- steps:
30
- - name: Clone
31
- uses: actions/checkout@v4
32
-
33
- - name: Setup Python version
34
- uses: actions/setup-python@v5
35
- with:
36
- python-version: ${{ matrix.python_version }}
37
-
38
- - name: Build & install
39
- run: |
40
- pip install -U pip
41
- pip install -U .[dev]
42
-
43
- - name: Run tests and generate coverage
44
- run: pytest -v --tb=short tests/ --cov ledgered --cov-report xml
45
-
46
- - name: Run unit tests and generate coverage
47
- run: pytest -v --tb=short tests/unit --cov ledgered --cov-report xml
48
-
49
- - name: Run functional tests and generate coverage
50
- run: pytest -v --tb=short tests/functional --cov ledgered --cov-report xml --cov-append --token "${{ secrets.GITHUB_TOKEN }}"
51
-
52
- - name: Upload coverage to Codecov
53
- uses: codecov/codecov-action@v4
54
- with:
55
- name: codecov-ledgered
56
- token: ${{ secrets.CODECOV_TOKEN }}
57
-
58
-
59
- package_and_deploy:
60
- name: Build and deploy Ledgered Python package
61
- runs-on: public-ledgerhq-shared-small
62
- needs: [build_install_test]
63
- permissions:
64
- id-token: write
65
- attestations: write
66
- contents: write
67
- steps:
68
-
69
- - name: Clone
70
- uses: actions/checkout@v4
71
- with:
72
- fetch-depth: 0
73
-
74
- - name: Build Ledgered Python package
75
- run: |
76
- # Needed to workaround this bug https://github.com/pypa/setuptools/issues/4759
77
- # To be removed when it's fixed
78
- pip install -U packaging
79
- pip install --upgrade pip build twine
80
- python -m build
81
- pip install .
82
- python -m twine check dist/*
83
- echo "TAG_VERSION=$(python -c 'from ledgered import __version__; print(__version__)')" >> "$GITHUB_ENV"
84
-
85
- - name: Display current status
86
- run: |
87
- echo "Current status is:"
88
- if [[ ${{ github.ref }} == "refs/tags/"* ]];
89
- then
90
- echo "- Triggered from tag, package will be a release";
91
- else
92
- echo "- Not triggered from tag, package will be a pre-release";
93
- fi
94
- echo "- Tag version: ${{ env.TAG_VERSION }}"
95
-
96
- - name: Check version against CHANGELOG
97
- if: startsWith(github.ref, 'refs/tags/')
98
- run: |
99
- CHANGELOG_VERSION=$(grep -Po '(?<=## \[)(\d+\.)+[^\]]' CHANGELOG.md | head -n 1)
100
- if [ "${{ env.TAG_VERSION }}" == "${CHANGELOG_VERSION}" ]; \
101
- then \
102
- exit 0; \
103
- else \
104
- echo "Tag '${{ env.TAG_VERSION }}' and CHANGELOG '${CHANGELOG_VERSION}' versions mismatch!"; \
105
- exit 1; \
106
- fi
107
-
108
- - name: Publish Python package on pypi.org
109
- if: success() && github.event_name == 'push'
110
- run: python -m twine upload dist/*
111
- env:
112
- TWINE_USERNAME: __token__
113
- TWINE_PASSWORD: ${{ secrets.PYPI_PUBLIC_API_TOKEN }}
114
- TWINE_NON_INTERACTIVE: 1
115
-
116
- - name: Login to Ledger Artifactory
117
- if: success() && github.event_name == 'push'
118
- timeout-minutes: 10
119
- id: jfrog-login
120
- uses: LedgerHQ/actions-security/actions/jfrog-login@actions/jfrog-login-1
121
-
122
- - name: Publish Python package on Ledger Artifactory
123
- if: success() && github.event_name == 'push'
124
- run: python -m twine upload dist/*
125
- env:
126
- TWINE_REPOSITORY_URL: https://jfrog.ledgerlabs.net/artifactory/api/pypi/embedded-apps-pypi-prod-green
127
- TWINE_USERNAME: ${{ steps.jfrog-login.outputs.oidc-user }}
128
- TWINE_PASSWORD: ${{ steps.jfrog-login.outputs.oidc-token }}
129
- TWINE_NON_INTERACTIVE: 1
130
-
131
- - name: Generate library build attestations
132
- if: success() && github.event_name == 'push'
133
- timeout-minutes: 10
134
- uses: LedgerHQ/actions-security/actions/attest@actions/attest-1
135
- with:
136
- subject-path: dist/*
137
-
138
- - name: Sign library artifacts
139
- if: success() && github.event_name == 'push'
140
- timeout-minutes: 10
141
- uses: LedgerHQ/actions-security/actions/sign-blob@actions/sign-blob-1
142
- with:
143
- path: dist
144
-
145
- - name: Publish a release on the repo
146
- if: success() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
147
- uses: "marvinpinto/action-automatic-releases@latest"
148
- with:
149
- automatic_release_tag: "v${{ env.TAG_VERSION }}"
150
- repo_token: "${{ secrets.GITHUB_TOKEN }}"
151
- prerelease: false
152
- files: |
153
- LICENSE
154
- dist/
@@ -1,6 +0,0 @@
1
- from .app import AppConfig
2
- from .constants import EXISTING_DEVICES, MANIFEST_FILE_NAME
3
- from .manifest import Manifest
4
- from .tests import TestsConfig
5
-
6
- __all__ = ["AppConfig", "EXISTING_DEVICES", "Manifest", "MANIFEST_FILE_NAME", "TestsConfig"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes