Skip to content

Commit

Permalink
Merge pull request #179 from ismet55555/build-diff
Browse files Browse the repository at this point in the history
feat: `diff` info and logs for jobs and builds
  • Loading branch information
ismet55555 authored Dec 2, 2022
2 parents a1bbfd1 + b5bcc15 commit f2206a2
Show file tree
Hide file tree
Showing 14 changed files with 320 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.0.79
current_version = 0.0.80
commit = True
tag = True
allow_dirty = False
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,5 @@ config.yaml

# Documentation build files
docs/site/**

NOTES.md
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.79
0.0.80
2 changes: 1 addition & 1 deletion docs/source/cli_outline.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Below is a complete outline of the `yojenkins` CLI command structure.

!!! note
As of Version: **0.0.79**
As of Version: **0.0.80**

```text
yojenkins
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import setuptools

# Package version number (Updated via bump2version tool)
__version__ = "0.0.79"
__version__ = "0.0.80"

def check_py_version():
"""Check the python version"""
Expand Down
2 changes: 1 addition & 1 deletion yojenkins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

__title__ = 'yojenkins'
__summary__ = "A CLI tool to interface with Jenkins server"
__version__ = "0.0.79"
__version__ = "0.0.80"
__author__ = "Ismet Handzic"
__copyright__ = "Copyright 2022 %s" % __author__
22 changes: 21 additions & 1 deletion yojenkins/cli/cli_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from yojenkins.cli import cli_utility as cu
from yojenkins.cli.cli_utility import log_to_history
from yojenkins.utility.utility import wait_for_build_and_follow_logs, is_complete_build_url
from yojenkins.utility.utility import is_complete_build_url, wait_for_build_and_follow_logs
from yojenkins.yo_jenkins.status import Status

# Getting the logger reference
Expand Down Expand Up @@ -378,3 +378,23 @@ def rebuild(profile: str, token: str, job: str, number: int, url: str, latest: b
click.secho(f'success. queue number: {data}', fg='bright_green', bold=True)
return
wait_for_build_and_follow_logs(yj_obj, data)


@log_to_history
def diff(profile: str, token: str, build_url_1: str, build_url_2: str, logs: bool, char_ignore: int, no_color: bool,
diff_only: bool, diff_guide: bool) -> None:
"""Get the diff comparison for two builds
Args:
profile: The profile/account to use
token: API Token for Jenkins server
build_url_1: First build for comparison
build_url_2: Second build for comparison
logs: Compare build logs
char_ignore: Number of characters to ignore at start of each line
no_color: Output diff with no color
diff_only: Only show the lines that have changed
diff_guide: Show diff guide, showing where exactly difference is in line
"""
yj_obj = cu.config_yo_jenkins(profile, token)
yj_obj.build.diff(build_url_1, build_url_2, logs, char_ignore, no_color, diff_only, diff_guide)
17 changes: 17 additions & 0 deletions yojenkins/cli/cli_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,20 @@ def parameters(profile: str, token: str, job: str, opt_list: bool, **kwargs) ->
data, data_list = yj_obj.job.parameters(job_name=job)
data = data_list if opt_list else data
cu.standard_out(data, **kwargs)


@log_to_history
def diff(profile: str, token: str, job_1: str, job_2: str, no_color: bool, diff_only: bool, diff_guide: bool) -> None:
"""Get the diff comparison for two jobs
Args:
profile: The profile/account to use
token: API Token for Jenkins server
job_1: First job for comparison (name or url)
job_2: Second job for comparison (name or url)
no_color: Output diff with no color
diff_only: Only show the lines that have changed
diff_guide: Show diff guide, showing where exactly difference is in line
"""
yj_obj = cu.config_yo_jenkins(profile, token)
yj_obj.job.diff(job_1, job_2, no_color, diff_only, diff_guide)
9 changes: 5 additions & 4 deletions yojenkins/cli/cli_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,16 @@ def standard_out(data: Union[Dict, List],


def is_full_url(url: str) -> bool:
"""TODO Docstring
"""Check if the provided url is a full and valide URL
### DUPLICATE: See yojenkins.utility.utility
Args:
TODO
url: The URL to check
Returns:
TODO
True if full and valid, else False
"""

# TODO: Remove this function from this file
# Do url check within the class, not within the cli to not keep repeating it
# In classes use yojenkins.utility.utility.is_full_url()
Expand Down
48 changes: 48 additions & 0 deletions yojenkins/cli_sub_commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,51 @@ def rebuild(ctx, debug, **kwargs):
cli_build.rebuild(**translate_kwargs(kwargs))
else:
click.echo(ctx.get_help())


@build.command(short_help='\tFind difference between two builds')
@cli_decorators.debug
@cli_decorators.profile
@click.argument('build-url-1', nargs=1, type=str, required=True)
@click.argument('build-url-2', nargs=1, type=str, required=True)
# @click.option('--type',
# type=click.Choice(['info', 'logs'], case_sensitive=False),
# default="info",
# show_default=True,
# required=False,
# help='Type of diff comparison')
@click.option('--logs', type=bool, default=False, required=False, is_flag=True, help='Build logs diff')
@click.option('--char-ignore',
default=0,
type=click.IntRange(0),
required=False,
help='Number of characters to ignore at line start')
@click.option('--no-color', type=bool, default=False, required=False, is_flag=True, help='Show output without color')
@click.option('--diff-only',
type=bool,
default=False,
required=False,
is_flag=True,
help='Show only lines that are different')
@click.option('--diff-guide',
type=bool,
default=False,
required=False,
is_flag=True,
help='Show where the difference is in line')
# @click.option('--stats-only', type=bool, default=False, required=False, is_flag=True, help='Show diff stats only')
def diff(debug, **kwargs):
"""Get the diff comparison for two builds (info, logs)
EXAMPLES:
\b
- yojenkins build diff "myFolder/myJob/4" "myFolder/myJob/5"
- yojenkins build diff "myJob/4/console" "myJob/5" --logs --diff-guide
- yojenkins build diff "myJob/5/" "yourJob/8" --diff-only
- yojenkins build diff "myJob/2/" "youJob/2/" --logs --char-ignore 40
- yojenkins build diff "myJob/5/" "yourJob/8" --stats-only
"""
set_debug_log_level(debug)
cli_build.diff(**translate_kwargs(kwargs))
33 changes: 33 additions & 0 deletions yojenkins/cli_sub_commands/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,36 @@ def parameters(debug, **kwargs):
"""
set_debug_log_level(debug)
cli_job.parameters(**translate_kwargs(kwargs))


@job.command(short_help='\tFind difference between two jobs')
@cli_decorators.debug
@cli_decorators.profile
@click.argument('job-1', nargs=1, type=str, required=True)
@click.argument('job-2', nargs=1, type=str, required=True)
@click.option('--no-color', type=bool, default=False, required=False, is_flag=True, help='Show output without color')
@click.option('--diff-only',
type=bool,
default=False,
required=False,
is_flag=True,
help='Show only lines that are different')
@click.option('--diff-guide',
type=bool,
default=False,
required=False,
is_flag=True,
help='Show where the difference is in line')
def diff(debug, **kwargs):
"""Get the diff comparison for two jobs
EXAMPLES:
\b
- yojenkins build diff "myFolder/myJob" "myFolder/myJob"
- yojenkins build diff "myJob" "myJob" --diff-guide
- yojenkins build diff "myJob" "yourJob" --diff-only
"""
set_debug_log_level(debug)
cli_job.diff(**translate_kwargs(kwargs))
74 changes: 72 additions & 2 deletions yojenkins/utility/utility.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""General utility and tools"""

import difflib
import json
import logging
import os
Expand All @@ -17,7 +18,7 @@
import toml
import xmltodict
import yaml
from click import echo, style
from click import echo, secho, style
from urllib3.util import parse_url
from yaspin import yaspin
from yaspin.spinners import Spinners
Expand Down Expand Up @@ -375,7 +376,6 @@ def is_full_url(url: str) -> bool:
Returns:
True if valid and full URL, else False
"""

# TODO: Replace this same function in cli_utility.py usages with this one within classes

parsed_url = parse_url(url)
Expand Down Expand Up @@ -1246,3 +1246,73 @@ def wait_for_build_and_follow_logs(yj_obj: object, queue_id: int) -> None:
build_number = queue_data["executable"]["number"]
print2(f"Running with build number {build_number}. Following console logs below:")
yj_obj.build.logs(build_url=None, job_url=queue_data["jobUrl"], build_number=build_number, follow=True)


def diff_show(text_1: str, text_2: str, label_1: str, label_2: str, char_ignore: int, no_color: bool, diff_only: bool,
diff_guide: bool) -> None:
"""Display/Show line diffs between two specified texts
Args:
text_1: String text 1
text_2: String text 2 to compare to text 1
label_1: text_1 label/description
label_2: text_2 label/description
char_ignore: Number of characters to ignore for comparison at start of each line
no_color: Display with no color
diff_only: Only show lines that are different
diff_guide: Show diff specifiers/guides to show where difference is on line
"""
logger.debug('Showing the diff of two provided text strings ...')

text_1 = [line[char_ignore:] for line in text_1.splitlines()]
text_2 = [line[char_ignore:] for line in text_2.splitlines()]
# lines_diff = difflib.Differ().compare(text_1, text_2)
# lines_diff = difflib.unified_diff(text_1, text_2, fromfile="Build URL 1", tofile="Build URL 2")
lines_diff = difflib.ndiff(text_1, text_2)
diff_ratio = difflib.SequenceMatcher(None, text_1, text_2).quick_ratio() * 100

# Legend Header
print()
if no_color:
print(label_1)
print(label_2)
else:
secho(style(label_1, fg="red", bold=False))
secho(style(label_2, fg="green", bold=False))

if char_ignore > 0:
print('\n' + "-" * 51)
print(f' NOTE: Ignoring first {char_ignore} characters of each line')
print("-" * 51)
print("")

for line in lines_diff:
if line.isspace():
continue

if line.startswith('?') and not diff_guide:
continue

first_char = line[0]
if no_color:
color, bold = "reset", False
elif first_char == "+":
color, bold = "green", False
elif first_char == "-":
color, bold = "red", False
elif first_char == "?":
color, bold = "yellow", True
else:
color, bold = None, False

# Show only diff
if diff_only and first_char not in ['-', "+"]:
continue

if line.startswith("?"):
line = line.replace("?", " ", 1)

secho(style(f" {line}", fg=color, bold=bold))

print('\n' + "-" * 51)
print(f'\n Similarity: {diff_ratio:.1f}%')
Loading

0 comments on commit f2206a2

Please sign in to comment.