Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit e6b8205

Browse files
Merge pull request #57 from codecov/thiago/f/static-label-analysis-commands
Adding Static Analysis and Label analysis Commands
2 parents 84833af + 8def867 commit e6b8205

28 files changed

+1827
-5
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ jobs:
1818
pip install black==22.3.0 isort==5.10.1
1919
- name: Check linting with black
2020
run: |
21-
black --check .
21+
black --check codecov_cli
2222
- name: Check imports order with isort
2323
run: |
24-
isort --check --profile=black .
24+
isort --check --profile=black codecov_cli
2525
2626
2727
build:
@@ -38,6 +38,9 @@ jobs:
3838
uses: actions/setup-python@v3
3939
with:
4040
python-version: "3.10"
41+
- name: Git Sumbodule Update
42+
run: |
43+
git pull --recurse-submodules
4144
- name: Install dependencies
4245
run: |
4346
python -m pip install --upgrade pip

.github/workflows/python-package.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v3
17+
with:
18+
submodules: true
1719
- name: Install dependencies
1820
run: |
1921
python -m pip install --upgrade pip
2022
pip install black==22.3.0 isort==5.10.1
2123
- name: Check linting with black
2224
run: |
23-
black --check .
25+
black --check codecov_cli
2426
- name: Check imports order with isort
2527
run: |
26-
isort --check --profile=black .
28+
isort --check --profile=black codecov_cli -p staticcodecov_languages
2729
2830
2931
build:
@@ -35,6 +37,7 @@ jobs:
3537
steps:
3638
- uses: actions/checkout@v3
3739
with:
40+
submodules: true
3841
fetch-depth: 2
3942
- name: Set up Python 3.10
4043
uses: actions/setup-python@v3

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "languages/treesitterpython"]
2+
path = languages/treesitterpython
3+
url = [email protected]:tree-sitter/tree-sitter-python.git
4+
[submodule "languages/treesitterjavascript"]
5+
path = languages/treesitterjavascript
6+
url = [email protected]:tree-sitter/tree-sitter-javascript.git

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ WIP
4444

4545
# Development
4646

47+
## Requirements
48+
49+
To start, most of this package is a normal Python package. The main different thing is the static analysis tool that uses both git submodules and c code
50+
51+
Before installing, one should pull the submodules with
52+
53+
```
54+
git submodule update --init
55+
```
56+
57+
The c code shouldn't require anything on most places, but it might ask you to install compilers and stuff. Most of the times you can find the instructions online given the error messsage
58+
59+
## Guidelines
60+
4761
There are a few guidelines when developing in this systems. We have a few notable folders:
4862

4963
1. `commands` - It's the folder that interacts with the caller. This is where the commands themselves should live. They are not meant to do heavy lifting. They only do wiring, which is mostly parsing the input parameters
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import logging
2+
import pprint
3+
import subprocess
4+
import time
5+
6+
import click
7+
import requests
8+
9+
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
10+
11+
logger = logging.getLogger("codecovcli")
12+
13+
14+
@click.command()
15+
@click.option("--token", required=True)
16+
@click.option(
17+
"--head-sha",
18+
"head_commit_sha",
19+
help="Commit SHA (with 40 chars)",
20+
cls=CodecovOption,
21+
fallback_field=FallbackFieldEnum.commit_sha,
22+
required=True,
23+
)
24+
@click.option(
25+
"--base-sha",
26+
"base_commit_sha",
27+
help="Commit SHA (with 40 chars)",
28+
cls=CodecovOption,
29+
required=True,
30+
)
31+
def label_analysis(token, head_commit_sha, base_commit_sha):
32+
url = "https://api.codecov.io/labels/labels-analysis"
33+
token_header = f"Repotoken {token}"
34+
# this needs to be more flexible to support multiple elements
35+
runner = ThisRunner()
36+
requested_labels = runner.collect_tests()
37+
payload = {
38+
"base_commit": base_commit_sha,
39+
"head_commit": head_commit_sha,
40+
"requested_labels": requested_labels,
41+
}
42+
try:
43+
response = requests.post(
44+
url, json=payload, headers={"Authorization": token_header}
45+
)
46+
if response.status_code >= 500:
47+
raise click.ClickException("Sorry. Codecov is having problems")
48+
if response.status_code >= 400:
49+
logger.warning(
50+
"Got a 4XX status code back from Codecov",
51+
extra=dict(
52+
extra_log_attributes=dict(
53+
status_code=response.status_code, response_json=response.json()
54+
)
55+
),
56+
)
57+
raise click.ClickException(
58+
"There is some problem with the submitted information"
59+
)
60+
except requests.RequestException:
61+
raise click.ClickException(click.style("Unable to reach Codecov", fg="red"))
62+
eid = response.json()["external_id"]
63+
has_result = False
64+
logger.info("Label request sent")
65+
time.sleep(2)
66+
while not has_result:
67+
resp_data = requests.get(
68+
f"https://api.codecov.io/labels/labels-analysis/{eid}",
69+
headers={"Authorization": token_header},
70+
)
71+
resp_json = resp_data.json()
72+
if resp_json["state"] == "finished":
73+
runner.do_something_with_result(resp_data.json()["result"])
74+
return
75+
if resp_json["state"] == "error":
76+
logger.error(
77+
"Request had problems calculating",
78+
extra=dict(extra_log_attributes=dict(resp_json=resp_json)),
79+
)
80+
return
81+
logger.info("Waiting more time for result")
82+
time.sleep(5)
83+
84+
85+
class ThisRunner(object):
86+
def collect_tests(self):
87+
return [
88+
x
89+
for x in subprocess.run(
90+
["python", "-m", "pytest", "-q", "--collect-only"], capture_output=True
91+
)
92+
.stdout.decode()
93+
.split()
94+
if "::" in x
95+
]
96+
97+
def do_something_with_result(self, result):
98+
command_array = ["python", "-m", "pytest"]
99+
all_labels = (
100+
result["absent_labels"]
101+
+ result["present_diff_labels"]
102+
+ result["global_level_labels"]
103+
)
104+
all_labels = set(all_labels)
105+
all_labels = [x.rsplit("[", 1)[0] if "[" in x else x for x in all_labels]
106+
pprint.pprint(all_labels)
107+
# Not safe from the customer perspective, in general, probably.
108+
# This is just to check it working
109+
command_array.extend(all_labels)
110+
print(command_array)
111+
subprocess.run(command_array)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import asyncio
2+
import pathlib
3+
4+
import click
5+
6+
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
7+
from codecov_cli.services.staticanalysis import run_analysis_entrypoint
8+
9+
10+
@click.command()
11+
@click.option(
12+
"--foldertosearch",
13+
default=".",
14+
help="Folder to search",
15+
type=click.Path(path_type=pathlib.Path),
16+
)
17+
@click.option(
18+
"--numberprocesses", type=click.INT, default=None, help="number of processes to use"
19+
)
20+
@click.option("--pattern", default="*", help="file pattern to search for")
21+
@click.option("--force/--no-force", default=False)
22+
@click.option(
23+
"--commit-sha",
24+
"commit",
25+
help="Commit SHA (with 40 chars)",
26+
cls=CodecovOption,
27+
fallback_field=FallbackFieldEnum.commit_sha,
28+
required=True,
29+
)
30+
@click.option("--token")
31+
@click.pass_context
32+
def static_analysis(
33+
ctx, foldertosearch, numberprocesses, pattern, commit, token, force
34+
):
35+
return asyncio.run(
36+
run_analysis_entrypoint(
37+
ctx.obj["codecov_yaml"],
38+
foldertosearch,
39+
numberprocesses,
40+
pattern,
41+
commit,
42+
token,
43+
force,
44+
)
45+
)

codecov_cli/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from codecov_cli.commands.commit import create_commit
99
from codecov_cli.commands.create_report_result import create_report_results
1010
from codecov_cli.commands.get_report_results import get_report_results
11+
from codecov_cli.commands.labelanalysis import label_analysis
1112
from codecov_cli.commands.report import create_report
13+
from codecov_cli.commands.staticanalysis import static_analysis
1214
from codecov_cli.commands.upload import do_upload
1315
from codecov_cli.helpers.ci_adapters import get_ci_adapter, get_ci_providers_list
1416
from codecov_cli.helpers.logging_utils import configure_logger
@@ -58,6 +60,8 @@ def cli(
5860
cli.add_command(create_report)
5961
cli.add_command(create_report_results)
6062
cli.add_command(get_report_results)
63+
cli.add_command(label_analysis)
64+
cli.add_command(static_analysis)
6165

6266

6367
def run():

0 commit comments

Comments
 (0)