-
Notifications
You must be signed in to change notification settings - Fork 13
Adding python script to easily obtain key customer info #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sarahraza007
wants to merge
27
commits into
main
Choose a base branch
from
sarah/understand-customer-script
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
05c549c
Adding python script to easily obtain key customer info
3ca9d79
added file writing capability
5aaa42e
Merge branch 'main' into sarah/understand-customer-script
d31f707
Merge remote-tracking branch 'origin/main' into sarah/understand-cust…
4d16539
changed directory
21e9ed6
removed comments, added command
9f2fa21
added new folder
cd2988c
added cquery
cad6ce9
Added flag functionality and readme file
93a3a3e
added in comments, removed unecessary import
8687ab4
Fixed aquery formatting, added in target as arg, added execute functi…
08bfd12
removed unecessary comment
0253986
Merge remote-tracking branch 'origin/main' into sarah/understand-cust…
677f3fd
fixed formatting, added error messages, added progress messages
fb015a2
added support for repo paths but data is unorganized, no option for s…
9a34d4c
Added in target organization for action info
e1e7a35
Merge remote-tracking branch 'origin/main' into sarah/understand-cust…
850d543
Merge remote-tracking branch 'origin/main' into sarah/understand-cust…
d48b5ad
added docstrings
9869462
added action summing
7bd919c
increased time out time
e9c4c2a
added support for user options, reorganized bazel targets to be more …
bdf4edd
remvoed TODOs
2941e96
Update scripts/customer-info/README.md
sarahraza007 4af3a40
Update scripts/customer-info/README.md
sarahraza007 8781a33
Update scripts/customer-info/README.md
sarahraza007 6fdd011
changed flags to more relevant ones
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Summary | ||
On a high level, our goal is to improve the customer experience by allowing us to obtain | ||
the introduction customer information faster. Through running this script, we will recieve | ||
a yaml file that contains the targets, relevant information about actions (number of total | ||
actions, set of mnemonics, set of configurations, set of platforms, and set of aspects), the | ||
bazel version being used, and the values of the relevant bazel flags. | ||
|
||
## Running and iterating the script | ||
To run the script, | ||
1. Navigate to the ```scripts``` folder and then the ```customer-info``` folder | ||
2. run command | ||
``` | ||
python customer_info.py PATH_TO_REPO | ||
``` | ||
where ```PATH_TO_REPO``` = | ||
absolute path to repo | ||
``` | ||
python customer_info.py "/Users/sarahraza/example" | ||
``` | ||
3. if you want cquery to run with a user option add it to the command | ||
``` | ||
python customer_info.py PATH_TO_REPO USER_OPTION | ||
``` | ||
where ```PATH_TO_REPO``` = | ||
absolute path to repo | ||
where ```USER_OPTION``` = | ||
user option flag to run cquery with | ||
``` | ||
python customer_info.py "/Users/sarahraza/example" "--compilation_mode=dbg" | ||
``` | ||
|
||
To customize the script, | ||
- Change the list of relevant flags by editing the ```relevant_flags``` variable | ||
|
||
## Detailed summary | ||
Within the script, the following commands are called: | ||
``` | ||
bazel --version | ||
bazel cquery //TARGET | ||
bazel aquery //TARGET | ||
bazel config IDENTIFIER | ||
``` | ||
|
||
The ```TARGET``` for each command is passed in as the second argument. | ||
|
||
The ```IDENTIFIER``` is the unique identifier from each target outputted by the bazel cquery command. | ||
|
||
The output after running the script is a yaml file in the customer-info folder. The yaml | ||
file contains 3 main blocks of information: | ||
- bazel aquery information which contains 5 sub-blocks of information | ||
1. Total number of actions | ||
2. Mnemonics | ||
3. Configurations | ||
4. Execution Platform | ||
5. Aspects | ||
- Example: | ||
``` | ||
bazel aquery information: | ||
- 47 total actions. | ||
- 'Mnemonics: GenProto: 1 TestRunner: 1 GenProtoDescriptorSet: 1 Action: 3 Middleman: | ||
3 FileWrite: 3 TemplateExpand: 3 SymlinkTree: 3 SourceSymlinkManifest: 3 | ||
JavaDeployJar: 3 Turbine: 5 Javac: 8 JavaSourceJar: 10' | ||
- 'Configurations: darwin-fastbuild: 47' | ||
- 'Execution Platforms: @local_config_platform//:host: 47' | ||
- 'Aspects: BazelJavaProtoAspect: 3' | ||
``` | ||
- bazel cquery targets under which there is a list of targets each of which has a unique | ||
identifier at the end between parenthesis | ||
- Example: | ||
``` | ||
bazel cquery targets: | ||
- //java/com/engflow/example:ExampleTest (8a8f93d) | ||
``` | ||
- bazel flag information in which there is the relevant flag information for each identifier | ||
- Example: | ||
``` | ||
bazel flag information: | ||
8a8f93d: | ||
experimental_allow_runtime_deps_on_neverlink: 'true' | ||
experimental_limit_android_lint_to_android_constrained_java: 'false' | ||
test_timeout: '{short=PT1M, moderate=PT5M, long=PT15M, eternal=PT1H}' | ||
94fc984: | ||
experimental_allow_runtime_deps_on_neverlink: 'true' | ||
experimental_limit_android_lint_to_android_constrained_java: 'false' | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import os | ||
import sys | ||
import re | ||
import subprocess | ||
|
||
import yaml | ||
|
||
# download pylint and add config file from engflow | ||
|
||
# adding links for the mnemonics using sourcegraph | ||
## collect important repos | ||
# estimating action sizes based on input or output | ||
# key words for relevant flags: remote, experimental, incompatible, BES, mnemonic | ||
|
||
if len(sys.argv) < 2: | ||
print("Please provide the following arguments: file path to repo." | ||
"Check README for further information.") | ||
quit() | ||
|
||
# add the names of wanted flag values | ||
# use regular expression instead | ||
relevant_flags = ['enable_platform_specific_config', 'experimental_announce_profile_path', 'explicit_java_test_deps', 'nostamp', 'incompatible_strict_action_env', 'verbose_failures', 'experimental_merged_skyframe_analysis_execution', 'experimental_skymeld_ui', 'experimental_remote_mark_tool_inputs', 'compilation_mode', 'compilation_mode', 'compilation_mode', 'incompatible_enable_cc_toolchain_resolution', '-supports_dynamic_linker', 'config', 'config', 'config', 'java_language_version', 'java_runtime_version', 'tool_java_language_version', 'tool_java_runtime_version', 'experimental_one_version_enforcement', '@io_bazel_rules_go//go/config:pure', 'cxxopt', 'host_cxxopt', 'cxxopt', 'host_cxxopt', 'cxxopt', 'host_cxxopt', 'cxxopt', 'host_cxxopt', 'cxxopt', 'host_cxxopt', 'cxxopt', 'host_cxxopt', 'workspace_status_command', 'workspace_status_command', 'workspace_status_command', 'build_tag_filters', 'test_tag_filters', 'experimental_action_listener', 'aspects', 'aspects', 'experimental_action_listener', 'nouse_ijars', 'aspects', 'config', 'keep_going', 'build_tag_filters', 'test_tag_filters', 'config', 'config', 'config', 'test_summary', 'test_output', 'instrumentation_filter', 'combined_report', 'experimental_one_version_enforcement', 'config', 'color', 'curses', 'show_timestamps', 'announce_rc', 'test_output', 'show_progress_rate_limit', 'build_tag_filters', 'test_tag_filters', 'test_env', 'test_env', 'test_env', 'test_env', 'test_env'] | ||
|
||
def execute(args): | ||
""" Executes an os command """ | ||
try: | ||
the_process = subprocess.run( | ||
args, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
text=True, | ||
check=True, | ||
timeout=30 | ||
) | ||
except subprocess.TimeoutExpired as error: | ||
print("The command '{}' timed out after {} seconds".format(error.cmd, error.timeout), file=sys.stderr) | ||
sys.exit(1) | ||
except subprocess.CalledProcessError as error: | ||
print("Could not execute os command ", error.returncode, " - ", error, file=sys.stderr) | ||
sys.exit(1) | ||
except subprocess.SubprocessError as error: | ||
print("Could not execute os command ", error.returncode, " - ", error, file=sys.stderr) | ||
sys.exit(1) | ||
return the_process.stdout, the_process.stderr | ||
|
||
def writeToFile(dict_file, path_to_customer_info): | ||
'''Takes in dictionary mapping category of data to value and writes to yaml file''' | ||
path_to_yaml = path_to_customer_info + "/customer_info.yaml" | ||
with open(path_to_yaml, 'w') as file: | ||
yaml.dump(dict_file, file) | ||
|
||
def extractFlags(bazel_target): | ||
sarahraza007 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'''Takes in list of targets from cquery and returns flags for the targets''' | ||
|
||
# creates array of all unique identifiers | ||
ids = set(re.findall(r'\(.*?\)', bazel_target)) | ||
|
||
# creates dictionary mapping unique identifiers to fragments containing all flag information | ||
print("Extracting all flags...") | ||
config_to_flag = {} | ||
for id in ids: | ||
config = id[1:-1] # removes parenthesis | ||
bazel_specific_config_command = ["bazel", "config", config] | ||
config_output, stderr_flag = execute(bazel_specific_config_command) | ||
config_to_flag[config] = config_output | ||
|
||
# changes dictionary to map from unique identifiers to dictionary containing strings with relevant flag information | ||
print("Shortening to relevant flags and saving to file...") | ||
new_config_to_flag = {} | ||
for config, config_output in config_to_flag.items(): | ||
flag_to_val = {} | ||
for flag in relevant_flags: | ||
start_index = config_output.find(flag) | ||
end_index = config_output.find("\n", start_index) | ||
flag_output = config_output[start_index:end_index] | ||
if len(flag_output) != 0: | ||
colon_index = flag_output.find(":") | ||
flag_to_val[flag_output[:colon_index]] = flag_output[colon_index+2:] | ||
new_config_to_flag[config] = flag_to_val | ||
|
||
return new_config_to_flag | ||
|
||
def getPotentialCommandFilePaths(): | ||
'''Returns potential file paths as targets to execute bazel commands''' | ||
os.chdir(sys.argv[1]) | ||
bazel_query_command = ["bazel", "query", "..."] | ||
stdout_version, stderr_version = execute(bazel_query_command) | ||
all_targets = stdout_version.split('\n') | ||
potential_targets = set() | ||
for target in all_targets: | ||
third_slash_index = target.find("/", 2) | ||
colon_index = target.find(":") | ||
if third_slash_index > 0: | ||
potential_targets.add(target[:third_slash_index] + "/...") | ||
elif colon_index > 0: | ||
potential_targets.add(target[:colon_index] + "/...") | ||
return potential_targets | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
'''Executes bazel commands for each file path, saving targets, action information, and flags to yaml file''' | ||
potential_targets = getPotentialCommandFilePaths() | ||
|
||
# dictionary with all information to put in yaml file | ||
dict_file = {} | ||
# dictionary with all bazel action information | ||
dict_bazel_actions = {} | ||
# dictionary with all config to flag information | ||
dict_flag_information = [] | ||
# dictionary with bazel target information | ||
targets_dict = {} | ||
|
||
# path to customer-info directory | ||
path_to_customer_info = sys.argv[1] + "/scripts/customer-info" | ||
|
||
# if user option passed in save | ||
user_option = "" | ||
if len(sys.argv) == 3: | ||
user_option = sys.argv[2] | ||
|
||
# move to customer project | ||
os.chdir(path_to_customer_info) | ||
|
||
# get bazel version | ||
print("Extracting bazel version information...") | ||
bazel_version_arr = ["bazel", "--version"] | ||
stdout_version, stderr_version = execute(bazel_version_arr) | ||
print("Saving in file...") | ||
dict_file["bazel version"] = str(stdout_version.strip()) | ||
|
||
for target in potential_targets: | ||
|
||
# get targets | ||
# NOTE: these targets will be used to obtain the flags | ||
bazel_cquery_target_command = ["bazel", "cquery", target] | ||
if user_option: | ||
bazel_cquery_target_command = ["bazel", "cquery", target, user_option] | ||
print("Extracting bazel targets...") | ||
try: | ||
stdout_target, stderr_target = execute(bazel_cquery_target_command) | ||
processed_stdout_target = stdout_target.split("\n")[:-1] | ||
for s in processed_stdout_target: | ||
parts = s.split(' ') | ||
key = parts[-1][1:-1] | ||
value = parts[0] | ||
targets_dict.setdefault(key, []).append(value) | ||
except SystemExit: | ||
continue | ||
|
||
# get action information | ||
bazel_action_summary_command = ["bazel", "aquery", target, "--output=summary"] | ||
print("Extracting bazel action information based on targets...") | ||
try: | ||
stdout_action_summary, stderr_action_summary = execute(bazel_action_summary_command) | ||
bazel_action_summary = stdout_action_summary.split("\n\n") | ||
formatted_bazel_action_summary = [] | ||
for info in bazel_action_summary: | ||
formatted_bazel_action_summary.append(info.split("\n")) | ||
|
||
# setting or updating action count to dict | ||
num_actions = re.findall(r'\d+', formatted_bazel_action_summary[0][0]) | ||
dict_bazel_actions.setdefault("total_actions", []).append(int(num_actions[0])) | ||
|
||
# adding other information to dictionary | ||
for info in formatted_bazel_action_summary[1:]: | ||
if info[0] in dict_bazel_actions: | ||
dict_bazel_actions[info[0]][target] = info[1:] | ||
else: | ||
dict_bazel_actions[info[0]] = {} | ||
dict_bazel_actions[info[0]][target] = info[1:] | ||
|
||
except SystemExit: | ||
continue | ||
|
||
# get flags | ||
print("Extracting relevant flag information...") | ||
new_dict = extractFlags(stdout_target) | ||
dict_flag_information.append(new_dict) | ||
|
||
# write targets, action, and flag to main dictionary | ||
print("Saving targets in file...") | ||
dict_file.setdefault("bazel_targets", []).append(targets_dict) | ||
print("Saving action information in file...") | ||
dict_file.setdefault("bazel_action_information", []).append(dict_bazel_actions) | ||
print("Saving flag information in file...") | ||
dict_file.setdefault("relevant bazel flags and values", []).append(dict_flag_information) | ||
|
||
# sums all the individual action count and saves that value | ||
sum_total_actions = sum(dict_file['bazel_action_information'][0]['total_actions']) | ||
dict_file['bazel_action_information'][0]['total_actions'] = sum_total_actions | ||
|
||
# write everything to the yaml file | ||
writeToFile(dict_file, path_to_customer_info) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.