primitive 0.1.2__py3-none-any.whl → 0.1.5__py3-none-any.whl

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.
primitive/__about__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Dylan Stein <dylan@steins.studio>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.1.2"
4
+ __version__ = "0.1.5"
primitive/lint/actions.py CHANGED
@@ -1,6 +1,67 @@
1
+ from pathlib import Path
1
2
  from primitive.utils.actions import BaseAction
3
+ import subprocess
4
+ from typing import Tuple
5
+ from loguru import logger
6
+ from ..utils.files import find_files_for_extension
7
+ from ..utils.verible import install_verible
2
8
 
3
9
 
4
10
  class Lint(BaseAction):
5
- def run_lint(self):
6
- print("lint 100%")
11
+ def execute(self, source: Path = Path.cwd()) -> Tuple[bool, str]:
12
+ logger.debug("Starting linter...")
13
+ files = find_files_for_extension(source, ".sv")
14
+ if not files:
15
+ message = "No files found to lint."
16
+ logger.warning(message)
17
+ return False, message
18
+
19
+ logger.debug("Checking if verible is installed")
20
+ try:
21
+ subprocess.run(["verible-verilog-lint", "--version"], capture_output=True)
22
+ except FileNotFoundError:
23
+ logger.debug("Did not find verible. Installing...")
24
+ try:
25
+ system_info = self.primitive.hardware.get_system_info()
26
+ install_verible(system_info=system_info)
27
+ except Exception as exception:
28
+ message = f"Failed to install verible. {exception}"
29
+ logger.error(message)
30
+ return False, message
31
+
32
+ try:
33
+ subprocess.run(["verible-verilog-lint", "--version"], capture_output=True)
34
+ except FileNotFoundError:
35
+ message = "Verible is not installed. Please install it to run lint."
36
+ logger.error(message)
37
+ return False, message
38
+
39
+ # TODO:
40
+ # run is great for now! we will need to switch to Popen if we want to stream the output
41
+ logger.debug("Running linter...")
42
+ result = subprocess.run(
43
+ ["verible-verilog-lint", *files],
44
+ capture_output=True,
45
+ text=True,
46
+ )
47
+
48
+ logger.debug("Linting complete.")
49
+
50
+ message = ""
51
+ if self.primitive.DEBUG:
52
+ if result.stderr:
53
+ logger.error("\n" + result.stderr)
54
+ if result.stdout:
55
+ logger.info("\n" + result.stdout)
56
+ message = "See above logs for linter output."
57
+ else:
58
+ message = result.stderr
59
+
60
+ if result.returncode != 0:
61
+ if not self.primitive.DEBUG:
62
+ message = result.stderr
63
+ return (False, message)
64
+ else:
65
+ message = "Linting successful."
66
+
67
+ return True, message
@@ -1,7 +1,7 @@
1
1
  import click
2
-
3
-
2
+ from pathlib import Path
4
3
  import typing
4
+ from ..utils.printer import print_result
5
5
 
6
6
  if typing.TYPE_CHECKING:
7
7
  from ..client import Primitive
@@ -9,7 +9,9 @@ if typing.TYPE_CHECKING:
9
9
 
10
10
  @click.command("lint")
11
11
  @click.pass_context
12
- def cli(context):
12
+ @click.argument("source", type=click.Path(exists=True), default=".")
13
+ def cli(context, source: str):
13
14
  """Lint"""
14
15
  primitive: Primitive = context.obj.get("PRIMITIVE")
15
- primitive.lint.run_lint()
16
+ result, message = primitive.lint.execute(source=Path(source))
17
+ print_result(message=message, context=context)
@@ -0,0 +1,16 @@
1
+ from typing import List, Tuple
2
+ from pathlib import Path
3
+ from loguru import logger
4
+
5
+
6
+ def find_files_for_extension(source: Path, extensions: Tuple[str]) -> List[Path]:
7
+ matching_files = []
8
+ logger.debug(f"Looking for files at {source} with extensions {extensions}")
9
+ for dirpath, dirnames, filenames in source.walk():
10
+ for filename in filenames:
11
+ if filename.endswith(extensions):
12
+ matching_files.append(dirpath.joinpath(filename))
13
+ logger.debug(
14
+ f"Found {len(matching_files)} following files that match: {matching_files}"
15
+ )
16
+ return matching_files
@@ -7,7 +7,7 @@ from loguru import logger
7
7
  def print_result(message: str, context: click.Context, fg: str = None):
8
8
  """Print message to stdout or stderr"""
9
9
  if context.obj["DEBUG"]:
10
- logger.debug(json.dumps(message))
10
+ logger.info(json.dumps(message))
11
11
  else:
12
12
  if context.obj["JSON"]:
13
13
  message = json.dumps(message, indent=2)
@@ -0,0 +1,33 @@
1
+ from pathlib import Path
2
+ import subprocess
3
+
4
+
5
+ def add_path_to_shell(path: Path):
6
+ if not path.exists():
7
+ raise Exception(f"{path} does not exist.")
8
+
9
+ try:
10
+ subprocess.run(["fish_add_path", path], capture_output=True)
11
+ return True
12
+ except FileNotFoundError:
13
+ pass
14
+
15
+ profile_path = None
16
+
17
+ if Path.home().joinpath(".bash_profile").exists():
18
+ profile_path = Path.home().joinpath(".bash_profile")
19
+ elif Path.home().joinpath(".bashrc").exists():
20
+ profile_path = Path.home().joinpath(".bashrc")
21
+ elif Path.home().joinpath(".zshrc").exists():
22
+ profile_path = Path.home().joinpath(".zshrc")
23
+ elif Path.home().joinpath(".profile").exists():
24
+ profile_path = Path.home().joinpath(".profile")
25
+ elif Path.home().joinpath(".bash_login").exists():
26
+ profile_path = Path.home().joinpath(".bash_login")
27
+ else:
28
+ raise Exception(f"Failed to add {path} to PATH")
29
+
30
+ with open(profile_path, "a") as file:
31
+ file.write(f"export PATH={path}:$PATH\n")
32
+
33
+ return True
@@ -0,0 +1,55 @@
1
+ import tarfile
2
+ import requests
3
+ from .shell import add_path_to_shell
4
+ from pathlib import Path
5
+
6
+ from loguru import logger
7
+
8
+
9
+ VERIBLE_MAC_OS_LINK = "https://github.com/chipsalliance/verible/releases/download/v0.0-3752-g8b64887e/verible-v0.0-3752-g8b64887e-macOS.tar.gz"
10
+ VERIBLE_WINDOWS_64_OS_LINK = "https://github.com/chipsalliance/verible/releases/download/v0.0-3752-g8b64887e/verible-v0.0-3752-g8b64887e-win64.zip"
11
+ VERIBLE_LINUX_X86_64_OS_LINK = "https://github.com/chipsalliance/verible/releases/download/v0.0-3752-g8b64887e/verible-v0.0-3752-g8b64887e-linux-static-x86_64.tar.gz"
12
+ VERIBLE_LINUX_ARM64_LINK = "https://github.com/chipsalliance/verible/releases/download/v0.0-3752-g8b64887e/verible-v0.0-3752-g8b64887e-linux-static-arm64.tar.gz"
13
+
14
+
15
+ def install_verible(system_info: dict) -> bool:
16
+ url = None
17
+ if system_info.get("os_family") == "Darwin":
18
+ url = VERIBLE_MAC_OS_LINK
19
+ elif system_info.get("os_family") == "Windows":
20
+ url = VERIBLE_WINDOWS_64_OS_LINK
21
+ elif system_info.get("processor") == "x86_64":
22
+ url = VERIBLE_LINUX_X86_64_OS_LINK
23
+ elif system_info.get("processor") == "arm":
24
+ url = VERIBLE_LINUX_X86_64_OS_LINK
25
+
26
+ verible_dir_name = url.split("/")[-1].split(".tar.gz")[0]
27
+ file_download_path = Path.home() / f"{verible_dir_name}.tar.gz"
28
+
29
+ logger.debug("Downloading verible")
30
+ response = requests.get(url, stream=True)
31
+ if response.status_code == 200:
32
+ with open(file_download_path, "wb") as file:
33
+ file.write(response.raw.read())
34
+ else:
35
+ raise Exception(
36
+ f"Failed to download verible. {response.status_code}. {response.text}"
37
+ )
38
+
39
+ logger.debug("Untaring verible")
40
+ with tarfile.open(file_download_path) as tar:
41
+ tar.extractall(Path.home())
42
+
43
+ logger.debug("Deleting tar.gz artifact")
44
+ file_download_path.unlink()
45
+
46
+ unpacked_verible_dir_name = verible_dir_name
47
+ if "linux" in unpacked_verible_dir_name:
48
+ unpacked_verible_dir_name = unpacked_verible_dir_name.split("-linux")[0]
49
+
50
+ verible_bin = Path.home().joinpath(unpacked_verible_dir_name).joinpath("bin")
51
+
52
+ logger.debug("Adding verible to PATH")
53
+ add_path_to_shell(verible_bin)
54
+
55
+ return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: primitive
3
- Version: 0.1.2
3
+ Version: 0.1.5
4
4
  Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
5
5
  Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
6
6
  Project-URL: Source, https://github.com//primitivecorp/primitive-cli
@@ -36,6 +36,7 @@ Description-Content-Type: text/markdown
36
36
  **Table of Contents**
37
37
 
38
38
  - [Installation](#installation)
39
+ - [Configuration](#configuration)
39
40
  - [License](#license)
40
41
 
41
42
  ## Installation
@@ -44,6 +45,20 @@ Description-Content-Type: text/markdown
44
45
  pip install primitive
45
46
  ```
46
47
 
48
+ ## Configuration
49
+
50
+ ### Authenticate
51
+
52
+ ```console
53
+ primitive config
54
+ ```
55
+
56
+ ### Register your Hardware
57
+
58
+ ```console
59
+ primitive hardware register
60
+ ```
61
+
47
62
  ## License
48
63
 
49
64
  `primitive` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -1,4 +1,4 @@
1
- primitive/__about__.py,sha256=-cDaoH25zZk42p51RdJ-K5fLmfLdYLlAzU6Svg3Twtw,128
1
+ primitive/__about__.py,sha256=eiRjGM6WtdYyj1eyR-jQ63lTpMSkzch2LxAzdXLwqzU,128
2
2
  primitive/__init__.py,sha256=bwKdgggKNVssJFVPfKSxqFMz4IxSr54WWbmiZqTMPNI,106
3
3
  primitive/cli.py,sha256=QC4jbu8s0uhNxFmaTO2B-X1o1gpyFX3xJVHU-j5CvQE,1705
4
4
  primitive/client.py,sha256=cZiJjzZ4HkCtYViDNOIoNuf7mcp772eSCSztsqh381E,2010
@@ -11,19 +11,22 @@ primitive/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
11
11
  primitive/graphql/sdk.py,sha256=BhCGmDtc4sNnH8CxbQSJyFwOZ-ZSqMtjsxMB3JRBhPw,1456
12
12
  primitive/hardware/actions.py,sha256=BbFz17NKVDiI-9SiV1R1GPqsXRZwUm9oNj-Dc_bBFJ8,17133
13
13
  primitive/hardware/commands.py,sha256=QE7LLeFdfOqlvz3JwdwJJRZAY3fHI1zB9kYmmDajpq0,1477
14
- primitive/lint/actions.py,sha256=O6XfKA9cgl0nj-BxcWfH2GTTuCND5A_tjwjYOj3zljE,124
15
- primitive/lint/commands.py,sha256=BXCp5CW2ibsk-dLe0FQ1xH3pga-Agzai0QmdNH1vaHo,254
14
+ primitive/lint/actions.py,sha256=FVigksFrADPDD3zHS0g0riyVrge7eEtwWk5PG2aZv9A,2352
15
+ primitive/lint/commands.py,sha256=3CZvkOEMpJspJWmaQzA5bpPKx0_VCijQIXA9l-eTnZE,487
16
16
  primitive/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  primitive/projects/actions.py,sha256=Zi0uFCUG5KU7w7HNE8eGlhUPdsJyjVrakcdU1PR8-MQ,1481
18
18
  primitive/simulations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  primitive/simulations/actions.py,sha256=YR0oxxd7_kuUIH77BWZLUs9rLRiSJztPPhpgDJU2PbY,1267
20
20
  primitive/utils/actions.py,sha256=HOFrmM3-0A_A3NS84MqrZ6JmQEiiPSoDqEeuu6b_qfQ,196
21
21
  primitive/utils/config.py,sha256=DlFM5Nglo22WPtbpZSVtH7NX-PTMaKYlcrUE7GPRG4c,1058
22
+ primitive/utils/files.py,sha256=Ug5UqrS9eZoTd08EFtgyyp8flsJTfsG9CwXBWmI-yFA,606
22
23
  primitive/utils/git.py,sha256=1qNOu8X-33CavmrD580BmrFhD_WVO9PGWHUUboXJR_g,663
23
24
  primitive/utils/memory_size.py,sha256=4xfha21kW82nFvOTtDFx9Jk2ZQoEhkfXii-PGNTpIUk,3058
24
- primitive/utils/printer.py,sha256=EXJnWWyFDrACnxHa7jtT_fXrSQoJUu1ZXOF05Y1hCaA,371
25
- primitive-0.1.2.dist-info/METADATA,sha256=ngX3kaLW5fY6Ze_ThcZ5SExZcDtaezbpS4zC-_KvyDo,1642
26
- primitive-0.1.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
27
- primitive-0.1.2.dist-info/entry_points.txt,sha256=p1K8DMCWka5FqLlqP1sPek5Uovy9jq8u51gUsP-z334,48
28
- primitive-0.1.2.dist-info/licenses/LICENSE.txt,sha256=B8kmQMJ2sxYygjCLBk770uacaMci4mPSoJJ8WoDBY_c,1098
29
- primitive-0.1.2.dist-info/RECORD,,
25
+ primitive/utils/printer.py,sha256=f1XUpqi5dkTL3GWvYRUGlSwtj2IxU1q745T4Fxo7Tn4,370
26
+ primitive/utils/shell.py,sha256=-7UjQaBqSGHzEEyX8pNjeYFFP0P3lVnDV0OkgPz1qHU,1050
27
+ primitive/utils/verible.py,sha256=QYczN1IvxODfj4jeq0nqjFuF0Oi0Zdx-Q32ySOJgcw8,2205
28
+ primitive-0.1.5.dist-info/METADATA,sha256=30UnO3-byVnVwOjKRro-Agt53Q8Nae137DUfcZF5A1Y,1817
29
+ primitive-0.1.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
30
+ primitive-0.1.5.dist-info/entry_points.txt,sha256=p1K8DMCWka5FqLlqP1sPek5Uovy9jq8u51gUsP-z334,48
31
+ primitive-0.1.5.dist-info/licenses/LICENSE.txt,sha256=B8kmQMJ2sxYygjCLBk770uacaMci4mPSoJJ8WoDBY_c,1098
32
+ primitive-0.1.5.dist-info/RECORD,,