Single-label for suggestions

Type
Enhancement
addressed https://github.com/Codium-ai/pr-agent/issues/536

Description
This PR introduces several enhancements to the PR code suggestions handling and configuration:

Refactored the code suggestion handling in pr_code_suggestions.py for consistency and improved functionality.
Updated the YAML parsing in _prepare_pr_code_suggestions method to include keys_fix_yaml parameter.
Added functionality to remove invalid suggestions where existing code is equal to improved code.
Updated the inline comment creation in various git providers to include absolute_position parameter.
Enhanced the find_line_number_of_relevant_line_in_file function to handle absolute position.
Added include_improved_code configuration option in configuration.toml and updated the documentation accordingly.

PR changes walkthrough
Relevant files                                                                                Enhancement7 files

pr_code_suggestions.py

        pr_agent/tools/pr_code_suggestions.py
The file has been updated to improve the handling of code suggestions. Key names have been updated to use snake_case for consistency. The method for preparing PR code suggestions has been updated to include a parameter for fixing YAML keys. The method for pushing inline code suggestions has been refactored to use the updated key names. The method for preparing extended predictions has been updated to use the new key names. The method for ranking suggestions has been updated to remove the redundant removal of invalid suggestions.

 +58/-35

pr_processing.py

        pr_agent/algo/pr_processing.py
The function `find_line_number_of_relevant_line_in_file` has been enhanced to handle absolute position. The function now has an additional parameter `absolute_position` which is used to match the absolute position to the relative position in the file.

 +46/-38

github_provider.py

        pr_agent/git_providers/github_provider.py
The `create_inline_comment` method has been updated to include the `absolute_position` parameter. This allows for more precise placement of inline comments in the GitHub provider.

 +6/-2

bitbucket_provider.py

        pr_agent/git_providers/bitbucket_provider.py
The `create_inline_comment` method in the Bitbucket provider has been updated to include the `absolute_position` parameter. This allows for more precise placement of inline comments.

 +4/-2

gitlab_provider.py

        pr_agent/git_providers/gitlab_provider.py
The `create_inline_comment` method in the GitLab provider has been updated to include the `absolute_position` parameter. However, the method raises a `NotImplementedError` as GitLab provider does not support creating inline comments yet.

 +1/-1

bitbucket_server_provider.py

        pr_agent/git_providers/bitbucket_server_provider.py
The `create_inline_comment` method in the Bitbucket Server provider has been updated to include the `absolute_position` parameter. This allows for more precise placement of inline comments.

 +5/-2

git_provider.py

        pr_agent/git_providers/git_provider.py
The `create_inline_comment` method in the base Git provider class has been updated to include the `absolute_position` parameter. However, the method raises a `NotImplementedError` as the base Git provider does not support creating inline comments yet.

 +3/-3

Documentation2 files

pr_code_suggestions_prompts.toml

        pr_agent/settings/pr_code_suggestions_prompts.toml
The instructions and YAML schema in `pr_code_suggestions_prompts.toml` have been updated to reflect the changes in `pr_code_suggestions.py`.

 +24/-48

IMPROVE.md

        docs/IMPROVE.md
The documentation for the 'pr_code_suggestions' section in `IMPROVE.md` has been updated to include the `include_improved_code` configuration option.

 +1/-0

Configuration changes1 files

configuration.toml

        pr_agent/settings/configuration.toml
The `include_improved_code` configuration option has been added to the 'pr_code_suggestions' section in `configuration.toml`.

 +1/-0

Preparing suggestions...

Preparing suggestions...

PR Code Suggestions
💡 [best practice]
Use the get method with a default value instead of checking if a key exists in a dictionary and then accessing it. This will make the code more concise and pythonic.
File: pr_agent/tools/pr_code_suggestions.py (68-70)
  Example code:

Existing code:
if (not data) or (not 'code_suggestions' in data):
    get_logger().info('No code suggestions found for PR.')
    return

Improved code:
if not data.get('code_suggestions', None):
    get_logger().info('No code suggestions found for PR.')
    return

💡 [performance]
Use list comprehension to make the code more readable and efficient.
File: pr_agent/tools/pr_code_suggestions.py (125-132)
  Example code:

Existing code:
suggestion_list = []
for i, suggestion in enumerate(data['code_suggestions']):
    if suggestion['existing_code'] != suggestion['improved_code']:
        suggestion_list.append(suggestion)
    else:
        get_logger().debug(
            f"Skipping suggestion {i + 1}, because existing code is equal to improved code {suggestion['existing_code']}")
data['code_suggestions'] = suggestion_list

Improved code:
data['code_suggestions'] = [suggestion for suggestion in data['code_suggestions'] if suggestion['existing_code'] != suggestion['improved_code']]

💡 [readability]
Use a guard clause to reduce the level of indentation and improve the readability of the code.
File: pr_agent/tools/pr_code_suggestions.py (139-141)
  Example code:

Existing code:
if not data['code_suggestions']:
    get_logger().info('No suggestions found to improve this PR.')
    return self.git_provider.publish_comment('No suggestions found to improve this PR.')

Improved code:
if data.get('code_suggestions', None):
    return self.git_provider.publish_comment('No suggestions found to improve this PR.')
get_logger().info('No suggestions found to improve this PR.')

💡 [best practice]
Use the get method with a default value instead of checking if a key exists in a dictionary and then accessing it. This will make the code more concise and pythonic.
File: pr_agent/algo/pr_processing.py (227-230)
  Example code:

Existing code:
if "code_suggestions" in data:
    data["code_suggestions"].extend(data_per_chunk["code_suggestions"])
else:
    data.update(data_per_chunk)

Improved code:
data.get("code_suggestions", []).extend(data_per_chunk.get("code_suggestions", []))
data.update(data_per_chunk)

Preparing suggestions...

PR Code Suggestions
💡 [possible issue]
It seems like the rank_suggestions function is no longer removing invalid suggestions where the existing code is equal to the improved code. This functionality has been moved to the _prepare_pr_code_suggestions function. If the rank_suggestions function is still being used elsewhere in the codebase where this functionality is needed, it might be a good idea to add it back.
File: pr_agent/tools/pr_code_suggestions.py (243-248)
  Example code:

Existing code:
def rank_suggestions(self, data: List) -> List:
    """
    Rank the code suggestions based on their importance.
    """
    suggestion_list = []
    data_sorted = [[]] * len(suggestion_list)
    try:
        ...

Improved code:
def rank_suggestions(self, data: List) -> List:
    """
    Rank the code suggestions based on their importance.
    """
    suggestion_list = []
    # remove invalid suggestions
    for i, suggestion in enumerate(data):
        if suggestion['existing_code'] != suggestion['improved_code']:
            suggestion_list.append(suggestion)
    data_sorted = [[]] * len(suggestion_list)
    try:
        ...

💡 [enhancement]
The publish_summarizes_suggestions function has been updated to include the label in the markdown. However, it seems like the label is being stripped before being added to the markdown. If the label is expected to have leading or trailing whitespace, this could potentially remove meaningful information. Consider removing the strip() call if the whitespace is meaningful.
File: pr_agent/tools/pr_code_suggestions.py (291-298)
  Example code:

Existing code:
for s in data['code_suggestions']:
    try:
        extension_s = s['relevant_file'].rsplit('.')[-1]
        code_snippet_link = self.git_provider.get_line_link(s['relevant_file'], s['relevant_lines_start'],
                                                            s['relevant_lines_end'])
        label = s['label'].strip()
        data_markdown += f"\n💡 [{label}]\n\n**{s['suggestion_content'].rstrip().rstrip()}**\n\n"
        ...

Improved code:
for s in data['code_suggestions']:
    try:
        extension_s = s['relevant_file'].rsplit('.')[-1]
        code_snippet_link = self.git_provider.get_line_link(s['relevant_file'], s['relevant_lines_start'],
                                                            s['relevant_lines_end'])
        label = s['label']
        data_markdown += f"\n💡 [{label}]\n\n**{s['suggestion_content'].rstrip().rstrip()}**\n\n"
        ...

💡 [enhancement]
The include_improved_code configuration option has been added. It might be a good idea to add a comment explaining what this configuration option does for future reference.
File: pr_agent/settings/configuration.toml (62-68)
  Example code:

Existing code:
[pr_code_suggestions] # /improve #
num_code_suggestions=4
summarize = false
include_improved_code = true
extra_instructions = ""
rank_suggestions = false
# params for '/improve --extended' mode

Improved code:
[pr_code_suggestions] # /improve #
num_code_suggestions=4
summarize = false
# If set to true, the improved code will be included in the suggestions
include_improved_code = true
extra_instructions = ""
rank_suggestions = false
# params for '/improve --extended' mode

Preparing suggestions...

PR Code Suggestions
💡 [enhancement]
Consider using a list comprehension to simplify the creation of suggestion_list.
File: pr_agent/tools/pr_code_suggestions.py (125-132)
  Example code:

Existing code:
suggestion_list = []
for i, suggestion in enumerate(data['code_suggestions']):
    if suggestion['existing_code'] != suggestion['improved_code']:
        suggestion_list.append(suggestion)
    else:
        get_logger().debug(
            f"Skipping suggestion {i + 1}, because existing code is equal to improved code {suggestion['existing_code']}")
data['code_suggestions'] = suggestion_list

Improved code:
data['code_suggestions'] = [suggestion for suggestion in data['code_suggestions']
                            if suggestion['existing_code'] != suggestion['improved_code']]

💡 [enhancement]
Consider using a guard clause to reduce code nesting in the push_inline_code_suggestions method.
File: pr_agent/tools/pr_code_suggestions.py (139-141)
  Example code:

Existing code:
if not data['code_suggestions']:
    get_logger().info('No suggestions found to improve this PR.')
    return self.git_provider.publish_comment('No suggestions found to improve this PR.')

Improved code:
if data['code_suggestions']:
    return
get_logger().info('No suggestions found to improve this PR.')
self.git_provider.publish_comment('No suggestions found to improve this PR.')

💡 [enhancement]
Consider using a guard clause to reduce code nesting in the find_line_number_of_relevant_line_in_file function.
File: pr_agent/algo/pr_processing.py (281-294)
  Example code:

Existing code:
if absolute_position != -1: # matching absolute to relative
    for i, line in enumerate(patch_lines):
        # new hunk
        if line.startswith('@@'):
            delta = 0
            match = re_hunk_header.match(line)
            start1, size1, start2, size2 = map(int, match.groups()[:4])
        elif not line.startswith('-'):
            delta += 1
#
absolute_position_curr = start2 + delta - 1
if absolute_position_curr == absolute_position:
    position = i
    break

Improved code:
if absolute_position == -1:
    return
for i, line in enumerate(patch_lines):
    # new hunk
    if line.startswith('@@'):
        delta = 0
        match = re_hunk_header.match(line)
        start1, size1, start2, size2 = map(int, match.groups()[:4])
    elif not line.startswith('-'):
        delta += 1
#
absolute_position_curr = start2 + delta - 1
if absolute_position_curr == absolute_position:
    position = i
    break

💡 [performance]
Consider using f-string formatting for better readability and performance.
File: pr_agent/tools/pr_code_suggestions.py (158-158)
  Example code:

Existing code:
body = f"**Suggestion:** {content} [{label}]\n```suggestion\n" + new_code_snippet + "\n```"

Improved code:
body = f"**Suggestion:** {content} [{label}]\n```suggestion\n{new_code_snippet}\n```"

Preparing suggestions...

PR Code Suggestions

/improve --extended --pr_code_suggestions.extra_instructions="""\

add a joke after each suggestion
mention the name "Tal Ridnik" after each suggestions
"""

/improve --extended --pr_code_suggestions.extra_instructions="add a small joke to each suggestion"

Preparing suggestions...

PR Code Suggestions
💡 [possible issue]
The create_inline_comment method does not handle the case when position is -1. This could lead to unexpected behavior. Consider adding error handling for this case.
File: pr_agent/git_providers/bitbucket_provider.py (204-210)
  Example code:

Existing code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None):
    position, absolute_position = find_line_number_of_relevant_line_in_file(self.get_diff_files(),
                                                                            relevant_file.strip('`'),
                                                                            relevant_line_in_file, absolute_position)
    if position == -1:
        if get_settings().config.verbosity_level >= 2:
            get_logger().info(f"Could not find position for {relevant_file} {relevant_line_in_file}")

Improved code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None):
    position, absolute_position = find_line_number_of_relevant_line_in_file(self.get_diff_files(),
                                                                            relevant_file.strip('`'),
                                                                            relevant_line_in_file, absolute_position)
    if position == -1:
        if get_settings().config.verbosity_level >= 2:
            get_logger().info(f"Could not find position for {relevant_file} {relevant_line_in_file}")
        raise ValueError(f"Could not find position for {relevant_file} {relevant_line_in_file}")

💡 [possible issue]
The create_inline_comment method in the git_provider class raises a NotImplementedError. This could lead to runtime errors if the method is called. Consider providing a default implementation or making the method abstract.
File: pr_agent/git_providers/git_provider.py (109-111)
  Example code:

Existing code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None):
    raise NotImplementedError("This git provider does not support creating inline comments yet")

Improved code:
@abstractmethod
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None):
    pass

💡 [possible issue]
The create_inline_comment method in the gitlab_provider class has a different signature than the same method in other classes (it accepts position instead of absolute_position). This could lead to confusion and bugs. Consider aligning the method signatures across different classes.
File: pr_agent/git_providers/gitlab_provider.py (186-187)
  Example code:

Existing code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, position: int = None):
    raise NotImplementedError("Gitlab provider does not support creating inline comments yet")

Improved code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None):
    raise NotImplementedError("Gitlab provider does not support creating inline comments yet")

💡 [maintainability]
The create_inline_comment method is almost identical across multiple classes (bitbucket_provider, bitbucket_server_provider, github_provider). Consider moving this method to a common base class to reduce code duplication.
File: pr_agent/git_providers/github_provider.py (209-217)
  Example code:

Existing code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None):
    position, absolute_position = find_line_number_of_relevant_line_in_file(self.diff_files,
                                                                            relevant_file.strip('`'),
                                                                            relevant_line_in_file,
                                                                            absolute_position)
    if position == -1:
        if get_settings().config.verbosity_level >= 2:
            get_logger().info(f"Could not find position for {relevant_file} {relevant_line_in_file}")

Improved code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None):
    super().create_inline_comment(body, relevant_file, relevant_line_in_file, absolute_position)

💡 [maintainability]
The function find_line_number_of_relevant_line_in_file has grown quite large and complex. Consider breaking it down into smaller, more manageable functions. This will improve readability and maintainability.
File: pr_agent/algo/pr_processing.py (265-334)
  Example code:

Existing code:
def find_line_number_of_relevant_line_in_file(diff_files: List[FilePatchInfo],
                                              relevant_file: str,
                                              relevant_line_in_file: str,
                                              absolute_position: int = None) -> Tuple[int, int]:
    position = -1
    if absolute_position is None:
        absolute_position = -1
    re_hunk_header = re.compile(
        r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")
    for file in diff_files:
        if file.filename and (file.filename.strip() == relevant_file):
            patch = file.patch
            patch_lines = patch.splitlines()
            delta = 0
            start1, size1, start2, size2 = 0, 0, 0, 0
            if absolute_position != -1: # matching absolute to relative
                for i, line in enumerate(patch_lines):
                    # new hunk
                    if line.startswith('@@'):
                        delta = 0
                        match = re_hunk_header.match(line)
                        start1, size1, start2, size2 = map(int, match.groups()[:4])
                    elif not line.startswith('-'):
                        delta += 1
                    #
                    absolute_position_curr = start2 + delta - 1
                    if absolute_position_curr == absolute_position:
                        position = i
                        break
            else:
                # try to find the line in the patch using difflib, with some margin of error
                matches_difflib: list[str | Any] = difflib.get_close_matches(relevant_line_in_file,
                                                                             patch_lines, n=3, cutoff=0.93)
                if len(matches_difflib) == 1 and matches_difflib[0].startswith('+'):
                    relevant_line_in_file = matches_difflib[0]
                for i, line in enumerate(patch_lines):
                    if line.startswith('@@'):
                        delta = 0
                        match = re_hunk_header.match(line)
                        start1, size1, start2, size2 = map(int, match.groups()[:4])
                    elif not line.startswith('-'):
                        delta += 1
                    if relevant_line_in_file in line and line[0] != '-':
                        position = i
                        absolute_position = start2 + delta - 1
                        break
                if position == -1 and relevant_line_in_file[0] == '+':
                    no_plus_line = relevant_line_in_file[1:].lstrip()
                    for i, line in enumerate(patch_lines):
                        if line.startswith('@@'):
                            delta = 0
                            match = re_hunk_header.match(line)
                            start1, size1, start2, size2 = map(int, match.groups()[:4])
                        elif not line.startswith('-'):
                            delta += 1
                        if no_plus_line in line and line[0] != '-':
                            # The model might add a '+' to the beginning of the relevant_line_in_file even if originally
                            # it's a context line
                            position = i
                            absolute_position = start2 + delta - 1
                            break
    return position, absolute_position

Improved code:
def find_line_number_of_relevant_line_in_file(diff_files: List[FilePatchInfo],
                                              relevant_file: str,
                                              relevant_line_in_file: str,
                                              absolute_position: int = None) -> Tuple[int, int]:
    position = -1
    if absolute_position is None:
        absolute_position = -1
    re_hunk_header = re.compile(
        r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")
    for file in diff_files:
        if file.filename and (file.filename.strip() == relevant_file):
            patch = file.patch
            patch_lines = patch.splitlines()
            delta = 0
            start1, size1, start2, size2 = 0, 0, 0, 0
            if absolute_position != -1: # matching absolute to relative
                position = find_position_absolute(patch_lines, re_hunk_header, start2, delta, absolute_position)
            else:
                position, absolute_position = find_position_relative(patch_lines, re_hunk_header, start2, delta, relevant_line_in_file)
    return position, absolute_position

def find_position_absolute(patch_lines: List[str], re_hunk_header: Pattern[str], start2: int, delta: int, absolute_position: int) -> int:
    for i, line in enumerate(patch_lines):
        # new hunk
        if line.startswith('@@'):
            delta = 0
            match = re_hunk_header.match(line)
            start2, _, _, _ = map(int, match.groups()[:4])
        elif not line.startswith('-'):
            delta += 1
        #
        absolute_position_curr = start2 + delta - 1
        if absolute_position_curr == absolute_position:
            return i
    return -1

def find_position_relative(patch_lines: List[str], re_hunk_header: Pattern[str], start2: int, delta: int, relevant_line_in_file: str) -> Tuple[int, int]:
    # try to find the line in the patch using difflib, with some margin of error
    matches_difflib: list[str | Any] = difflib.get_close_matches(relevant_line_in_file,
                                                                 patch_lines, n=3, cutoff=0.93)
    if len(matches_difflib) == 1 and matches_difflib[0].startswith('+'):
        relevant_line_in_file = matches_difflib[0]
    for i, line in enumerate(patch_lines):
        if line.startswith('@@'):
            delta = 0
            match = re_hunk_header.match(line)
            start2, _, _, _ = map(int, match.groups()[:4])
        elif not line.startswith('-'):
            delta += 1
        if relevant_line_in_file in line and line[0] != '-':
            absolute_position = start2 + delta - 1
            return i, absolute_position
    if relevant_line_in_file[0] == '+':
        no_plus_line = relevant_line_in_file[1:].lstrip()
        return find_position_no_plus(patch_lines, re_hunk_header, start2, delta, no_plus_line)
    return -1, -1

def find_position_no_plus(patch_lines: List[str], re_hunk_header: Pattern[str], start2: int, delta: int, no_plus_line: str) -> Tuple[int, int]:
    for i, line in enumerate(patch_lines):
        if line.startswith('@@'):
            delta = 0
            match = re_hunk_header.match(line)
            start2, _, _, _ = map(int, match.groups()[:4])
        elif not line.startswith('-'):
            delta += 1
        if no_plus_line in line and line[0] != '-':
            # The model might add a '+' to the beginning of the relevant_line_in_file even if originally
            # it's a context line
            absolute_position = start2 + delta - 1
            return i, absolute_position
    return -1, -1

💡 [performance]
The regular expression re_hunk_header is compiled every time the function find_line_number_of_relevant_line_in_file is called. Since the regular expression does not change, consider moving it to a global constant to improve performance.
File: pr_agent/algo/pr_processing.py (272-273)
  Example code:

Existing code:
re_hunk_header = re.compile(
    r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")

Improved code:
RE_HUNK_HEADER = re.compile(
    r"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@[ ]?(.*)")

💡 [enhancement]
The create_inline_comment method does not return any value. This could be confusing for the users of this method. Consider returning a meaningful value.
File: pr_agent/git_providers/github_provider.py (209-217)
  Example code:

Existing code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None):
    position, absolute_position = find_line_number_of_relevant_line_in_file(self.diff_files,
                                                                            relevant_file.strip('`'),
                                                                            relevant_line_in_file,
                                                                            absolute_position)
    if position == -1:
        if get_settings().config.verbosity_level >= 2:
            get_logger().info(f"Could not find position for {relevant_file} {relevant_line_in_file}")

Improved code:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None) -> Tuple[int, int]:
    position, absolute_position = find_line_number_of_relevant_line_in_file(self.diff_files,
                                                                            relevant_file.strip('`'),
                                                                            relevant_line_in_file,
                                                                            absolute_position)
    if position == -1:
        if get_settings().config.verbosity_level >= 2:
            get_logger().info(f"Could not find position for {relevant_file} {relevant_line_in_file}")
    return position, absolute_position

💡 [enhancement]
Consider using list comprehension to simplify the creation of the suggestion_list.
File: pr_agent/tools/pr_code_suggestions.py (125-128)
  Example code:

Existing code:
suggestion_list = []
for i, suggestion in enumerate(data['code_suggestions']):
    if suggestion['existing_code'] != suggestion['improved_code']:
        suggestion_list.append(suggestion)

Improved code:
suggestion_list = [suggestion for suggestion in data['code_suggestions'] if suggestion['existing_code'] != suggestion['improved_code']]

💡 [maintainability]
Consider using a guard clause to reduce code nesting.
File: pr_agent/tools/pr_code_suggestions.py (139-141)
  Example code:

Existing code:
if not data['code_suggestions']:
    get_logger().info('No suggestions found to improve this PR.')
    return self.git_provider.publish_comment('No suggestions found to improve this PR.')

Improved code:
if data.get('code_suggestions'):
    return
get_logger().info('No suggestions found to improve this PR.')
return self.git_provider.publish_comment('No suggestions found to improve this PR.')

💡 [maintainability]
Consider using a guard clause to reduce code nesting.
File: pr_agent/tools/pr_code_suggestions.py (157-170)
  Example code:

Existing code:
if get_settings().pr_code_suggestions.include_improved_code:
    body = f"**Suggestion:** {content} [{label}]\n```suggestion\n" + new_code_snippet + "\n```"
    code_suggestions.append({'body': body, 'relevant_file': relevant_file,
                             'relevant_lines_start': relevant_lines_start,
                             'relevant_lines_end': relevant_lines_end})
else:
    if self.git_provider.is_supported("create_inline_comment"):
        body = f"**Suggestion:** {content} [{label}]"
        comment = self.git_provider.create_inline_comment(body, relevant_file, "",
                                                          absolute_position=relevant_lines_end)
        if comment:
            code_suggestions.append(comment)
    else:
        get_logger().error("Inline comments are not supported by the git provider")

Improved code:
if not get_settings().pr_code_suggestions.include_improved_code:
    if not self.git_provider.is_supported("create_inline_comment"):
        get_logger().error("Inline comments are not supported by the git provider")
        return
    body = f"**Suggestion:** {content} [{label}]"
    comment = self.git_provider.create_inline_comment(body, relevant_file, "",
                                                      absolute_position=relevant_lines_end)
    if comment:
        code_suggestions.append(comment)
    return
body = f"**Suggestion:** {content} [{label}]\n```suggestion\n" + new_code_snippet + "\n```"
code_suggestions.append({'body': body, 'relevant_file': relevant_file,
                         'relevant_lines_start': relevant_lines_start,
                         'relevant_lines_end': relevant_lines_end})

/improve

/improve --extended

PR Documentation
Here is a list of the files that were modified in the PR, with docstring for each altered code component:
pr_processing.py

find_line_number_of_relevant_line_in_file (function)  [+44/-36]

Component signature:
def find_line_number_of_relevant_line_in_file(diff_files: List[FilePatchInfo], relevant_file: str, relevant_line_in_file: str, absolute_position: int = None) -> Tuple[int, int]

Docstring:
"""
Find the line number of the relevant line in a file within a list of diff files.

Args:
    diff_files (List[FilePatchInfo]): A list of FilePatchInfo objects representing the diff files.
    relevant_file (str): The name of the relevant file.
    relevant_line_in_file (str): The relevant line in the file.
    absolute_position (int, optional): The absolute position of the relevant line. Defaults to None.

Returns:
    Tuple[int, int]: A tuple containing the position of the relevant line and its absolute position.
"""

bitbucket_provider.py

create_inline_comment (method)  [+4/-2]

Component signature:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None)

Docstring:
"""
Create an inline comment for a specific line or file.

Args:
    body (str): The content of the comment.
    relevant_file (str): The path of the relevant file.
    relevant_line_in_file (str): The line number or identifier of the relevant line in the file.
    absolute_position (int, optional): The absolute position of the comment. Defaults to None.

Returns:
    dict: A dictionary containing the comment body, path, and position if subject_type is "LINE", otherwise an empty dictionary.
"""

bitbucket_server_provider.py

create_inline_comment (method)  [+5/-2]

Component signature:
create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                      absolute_position: int = None)

Docstring:
"""
Create an inline comment for a given body of text.

Args:
    body (str): The content of the comment.
    relevant_file (str): The path of the relevant file.
    relevant_line_in_file (str): The line number of the relevant line in the file.
    absolute_position (int, optional): The absolute position of the comment. Defaults to None.

Returns:
    dict: A dictionary containing the comment body, file path, and position if subject_type is "LINE",
          otherwise an empty dictionary.

Raises:
    None
"""

git_provider.py

create_inline_comment (method)  [+3/-2]

Component signature:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None)

Docstring:
"""
This method is used to create an inline comment in a relevant file at a specific line or position.

:param body: The content of the comment.
:type body: str
:param relevant_file: The path of the relevant file.
:type relevant_file: str
:param relevant_line_in_file: The line number or position in the relevant file.
:type relevant_line_in_file: str
:param absolute_position: The absolute position in the relevant file (optional).
:type absolute_position: int, optional

:raises NotImplementedError: This git provider does not support creating inline comments yet
"""

github_provider.py

create_inline_comment (method)  [+6/-2]

Component signature:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str,
                          absolute_position: int = None)

Docstring:
"""
Create an inline comment for a specific line in a file or for the entire file.

Args:
    body (str): The content of the comment.
    relevant_file (str): The path of the relevant file.
    relevant_line_in_file (str): The line number or identifier of the relevant line in the file.
    absolute_position (int, optional): The absolute position of the relevant line in the file. Defaults to None.

Returns:
    dict: A dictionary containing the comment body, file path, and line position if subject_type is "LINE",
          otherwise an empty dictionary.

Raises:
    None
"""

gitlab_provider.py

create_inline_comment (method)  [+1/-1]

Component signature:
def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None)

Docstring:
"""
Create an inline comment in a relevant file at a specific line.

Args:
    body (str): The content of the comment.
    relevant_file (str): The path of the relevant file.
    relevant_line_in_file (str): The line number in the relevant file.
    absolute_position (int, optional): The absolute position in the file. Defaults to None.

Raises:
    NotImplementedError: Gitlab provider does not support creating inline comments yet
"""

pr_code_suggestions.py

run (method)  [+2/-2]

Component signature:
async def run(self)

Docstring:
"""
Run the code suggestion generation process for a PR.

This method generates code suggestions for a PR by performing the following steps:
1. Log a message indicating that code suggestions are being generated.
2. If the `publish_output` configuration is enabled, publish a temporary comment indicating that suggestions are being prepared.
3. Log a message indicating that PR code suggestions are being prepared.
4. If the `is_extended` flag is False, call the `_prepare_prediction` method wrapped in a retry mechanism with fallback models.
5. Call the `_prepare_pr_code_suggestions` method to prepare the PR code suggestions data.
6. If the `is_extended` flag is True, call the `_prepare_prediction_extended` method wrapped in a retry mechanism with fallback models.
7. If the `data` variable is empty or does not contain the key 'code_suggestions', log a message indicating that no code suggestions were found and return.
8. If the `rank_suggestions` configuration is enabled (for non-extended suggestions) or the `rank_extended_suggestions` configuration is enabled (for extended suggestions), log a message indicating that suggestions are being ranked and call the `rank_suggestions` method.
9. If the `publish_output` configuration is enabled, log a message indicating that PR code suggestions are being pushed.
10. Remove the initial comment (if any) from the git provider.
11. If the `summarize` configuration is enabled, log a message indicating that summarize code suggestions are being pushed and call the `publish_summarizes_suggestions` method.
12. Otherwise, log a message indicating that inline code suggestions are being pushed and call the `push_inline_code_suggestions` method.
13. If an exception occurs during the process, log an error message indicating the failure.

:raises Exception: If an error occurs during the code suggestion generation process.
"""

_prepare_pr_code_suggestions (method)  [+14/-2]

Component signature:
def _prepare_pr_code_suggestions(self) -> Dict

Docstring:
"""
Prepare the code suggestions for a pull request.

Returns:
    Dict: The prepared code suggestions.

"""

push_inline_code_suggestions (method)  [+30/-13]

Component signature:
def push_inline_code_suggestions(self, data):

Docstring:
"""
Pushes inline code suggestions to the git provider.

:param data: The data containing code suggestions.
:type data: dict
:return: None
"""

_prepare_prediction_extended (method)  [+2/-2]

Component signature:
async def _prepare_prediction_extended(self, model: str) -> dict:

Docstring:
"""
Prepare extended prediction for a given model.

:param model: The name of the model.
:type model: str
:return: A dictionary containing the prepared prediction data.
:rtype: dict
"""

rank_suggestions (method)  [+2/-5]

Component signature:
async def rank_suggestions(self, data: List) -> List

Docstring:
"""
Call a model to rank (sort) code suggestions based on their importance order.

Args:
    data (List): A list of code suggestions to be ranked.

Returns:
    List: The ranked list of code suggestions.
"""

publish_summarizes_suggestions (method)  [+10/-9]

Component signature:
def publish_summarizes_suggestions(self, data: Dict)

Docstring:
"""
Publishes summarized code suggestions.

Args:
    data (Dict): The data containing code suggestions.

Raises:
    Exception: If there is an error while publishing the suggestions.

Returns:
    None
"""

/add_docs

PR Analysis
Here is a components analysis of the PR, as well as a change summary for each component:
Relevant filesComponents                                                                                pr_processing.py1 components changed

find_line_number_of_relevant_line_in_file (function)

        Changes summary:
The find_line_number_of_relevant_line_in_file function in the PR underwent several changes. The function now accepts an additional parameter absolute_position with a default value of None. The logic for matching the absolute position to the relative position has been modified. The code for finding the line in the patch using difflib has been moved inside an else block. Some variable names have been changed for clarity.

 +44/-36

bitbucket_provider.py1 components changed

create_inline_comment (method of BitbucketProvider)

        Changes summary:
The create_inline_comment method in the PR has been modified to include an additional parameter absolute_position. This parameter is used in the find_line_number_of_relevant_line_in_file function to determine the position of the relevant line in the file. If the position is not found, a log message is generated. The path variable is now stripped of backticks before being assigned.

 +4/-2

bitbucket_server_provider.py1 components changed

create_inline_comment (method of BitbucketServerProvider)

        Changes summary:
The create_inline_comment method in the PR now accepts an additional argument absolute_position. This argument is used in the find_line_number_of_relevant_line_in_file function call. The function call has been updated to pass the absolute_position argument as well.

 +5/-2

git_provider.py1 components changed

create_inline_comment (method of GitProvider)

        Changes summary:
The create_inline_comment method in the PR has been modified to include an additional parameter absolute_position of type int. The method now raises a NotImplementedError with a message indicating that the git provider does not support creating inline comments yet.

 +3/-2

github_provider.py1 components changed

create_inline_comment (method of GithubProvider)

        Changes summary:
The create_inline_comment method in the PR has been modified to include an additional parameter absolute_position. The find_line_number_of_relevant_line_in_file function is now called with the updated parameters. If the position is -1, a log message is printed. The subject_type is determined based on the value of position. The path, position, and body are returned in a dictionary if subject_type is "LINE", otherwise an empty dictionary is returned.

 +6/-2

gitlab_provider.py1 components changed

create_inline_comment (method of GitLabProvider)

        Changes summary:
The create_inline_comment method in the PR was modified to include an additional parameter absolute_position of type int with a default value of None. This change allows for more flexibility when creating inline comments.

 +1/-1

pr_code_suggestions.py6 components changed

run (method of PRCodeSuggestions)

        Changes summary:
The PR made changes to the run method. It modified the variable names in the if conditions to check for the presence of code_suggestions in the data dictionary. Additionally, it updated the variable names in the if condition to rank the suggestions based on the settings.

 +2/-2

_prepare_pr_code_suggestions (method of PRCodeSuggestions)

        Changes summary:
The PR made changes to the _prepare_pr_code_suggestions method. It added additional keys to the load_yaml function call, including "relevant_file", "suggestion_content", "existing_code", and "improved_code". It also added code to remove invalid suggestions from the data[code_suggestions] list based on the condition that the existing code is not equal to the improved code.

 +14/-2

push_inline_code_suggestions (method of PRCodeSuggestions)

        Changes summary:
The PR made several changes to the push_inline_code_suggestions method. It modified the condition for checking if there are code suggestions, changed the variable names in the loop, added a label variable, and adjusted the body of the code suggestions based on the settings. It also added an error message if inline comments are not supported by the git provider. Finally, it added a check for successful code suggestion publishing and a fallback for publishing each suggestion separately if it fails.

 +30/-13

_prepare_prediction_extended (method of PRCodeSuggestions)

        Changes summary:
The changes in the _prepare_prediction_extended method include modifying the key name from "Code suggestions" to "code_suggestions" in the data dictionary. This change ensures consistency and aligns with the naming convention. The modification allows the code suggestions to be properly appended to the existing list in the data dictionary.

 +2/-2

rank_suggestions (method of PRCodeSuggestions)

        Changes summary:
The changes in the rank_suggestions method include removing the code that filtered out invalid suggestions and simplifying the loop that appends suggestions to the suggestion_list.

 +2/-5

publish_summarizes_suggestions (method of PRCodeSuggestions)

        Changes summary:
The PR modifies the publish_summarizes_suggestions method in the following ways:

Renames the Code suggestions key in the data dictionary to code_suggestions.
Adds a label to each suggestion in the data_markdown string.
Updates the variable names in the code snippet generation logic.
Replaces the existing code and improved code keys in the s dictionary with existing_code and improved_code respectively.

 +10/-9

/add_docs

/improve --extended

/describe

/describe

/describe

/improve --extended


Removing _testing mock modules.

No longer needed since gRPC works (mostly?) everywhere.

@tseaver I stopped short of combining REQUIREMENTS and GRPC_EXTRAS in setup.py but it seems like that is do-able now. WDYT?

Also think we can remove the bigtable warning and the scary warnings in the docs

LGTM. Push the button, Max!.

2:09 is the result ;)

Here's hoping it doesn't break AppVeyor: https://ci.appveyor.com/project/dhermes/gcloud-python/build/1.0.574.master

W00t!  All green!


Fix direct use of internal BoundField api, with call to form[field].

This is for two reasons:

BoundField is an internal api of forms, the normal way to get a hand on one it to ask it to the form.
manual instanciation of BoundField breaks forms that override their __getattr__ for advanced uses, such as proxying fields to other forms.

I found this issue while building a proxy form, allowing me to apply a single layout to several forms.
The tests pass once #310 is applied. I'll happily rebase when it is, if you so wish, just tell.

Just in case, I rebased that on the latest commit.

@spectras Fancy updating this one more time?

Alright, though maybe not before a couple of days. I'll post here again when I do it.


Document how transaction service index from blockchain

What is needed?
We would like to add documentation explaining how indexer works.
This documentation should includes:

how indexer works on L1
how indexer works on L2
document the safe status history and the safe last status
how we manage the block reorgs.

Working on https://github.com/safe-global/safe-docs/pull/236


chore(bindings/nodejs): update license in package.json

I hereby agree to the terms of the CLA available at: https://databend.rs/dev/policies/cla/
Summary
update license in package.json

Nice catch


Make IDs optional

I'm working on that right now, and will implement it if it doesn't kill performance.

This works, I'll merge it to master soon

Merged to master! You now don't specify an id on the closing helper tag, and you don't have to have closing block tags either.


scat2gridgauss functions algorithm doesn't match documentation.

Reported by @AnsleyManke on 5 Feb 2009 22:41 UTC
The documentation indicates the use of the cutoff parameter to cut down on computation uses computation of distance based up (dx2 + dy2). Instead simply looks at MAX(dx, dy).
Here's the piece from the docs:
Wn(xn,yn) = exp{-[(xn-x0)2/(X)2 + (yn-y0)2/(Y)2]}

X and Y in the denominators on the right hand side are the
mapping scales, arguments XSCALE and YSCALE.
The weight function has a nonzero value everywhere, so all of
the scattered points in theory could be part of the sum for
each grid point. To cut computation, the parameter CUTOFF is
employed. If a cutoff of 2 is used (e.g. CUTOFF* XSCALE=2),
then the weight function is set to zerowhen Wn< e-4. This occurs
where distances from the grid point are less than 2 times the
mapping scales X or Y.

But in fact the code just skips a point if dx > cutoff or dy > cutoff.
Talking with Billy who wrote the gausswt2 code, this is in fact the case - the code does the simpler cutoff. The size of the weights below which the calculation is cut off is of the right magnitude, but the points included in the calculations lie in a box rather than a circular or elliptical shape indicated in the documentation.
We will fix this family of functions, document the change, and make the earlier functions available in case folks don't want the behavior of the function to change.
Migrated-From: http://dunkel.pmel.noaa.gov/trac/ferret/ticket/1631

This was done,
c V62 *ACM* 2/2009 Change the use of cutoff to exclude points from
c            calculation based on weights so that the exclusing
c            is an ellipse not a box.


Python language is not detected on repo with python modules marked executable

Preliminary Steps
Please confirm you have...

[x] reviewed How Linguist Works,
[x] reviewed the Troubleshooting docs,
[x] considered implementing an override,
[x] verified an issue has not already been logged for your issue (linguist issues).

Problem Description
https://github.com/Th3Hurrican3/PEpper

Python does not show up at all in the languages, even though there are multiple modules

The python modules are marked "executable file"
URL of the affected repository: https://github.com/Th3Hurrican3/PEpper
Last modified on:

2019-07-15
Expected language:

Python (included)
Detected language:

YARA, Other

Python does not show up at all in the languages, even though there are multiple modules

Well, it technically does... but first an import bit of info from the README:

The percentages are calculated based on the bytes of code for each language as reported by the List Languages API.

So that means your Python is going to be part of the "Other 0.9%" because all files that aren't identified as YARA total less than 1% of the entire repo content:
YARA 5.46 MB
Python 53 KB
Shell 2.01 KB
As you can see those YARA files are clearly the predominant force in your repo.
If you want Python to show, you're gonna need to write a lot more Python 😉 or use an override to ignore the YARA files when calculating the language stats. As those appear to all be under rules and appear to be from a third party, you probably want to mark them as vendored.

The percentages are calculated based on the bytes of code for each language as reported by the List Languages API.

So that means your Python is going to be part of the "Other 0.9%" because all files that aren't identified as YARA total less than 1% of the entire repo content:
YARA 5.46 MB
Python 53 KB
Shell 2.01 KB

ok, that makes sense


widget not formatted on 4th widget

"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0",
"tcg/voyager": "^1.1"
Description:
I want to add 4 widgets to the dashboard. I can successfully get the third widget to show in format, but when I add another widget after that it is placed far right, under the third widget instead of being pushed to the left. In addition, If I add more widgets or even just copy and paste the same two new widgets, they show up formatted from left to right as expected.
The first 2 widgets are the ones generated by the --with-dummy data tag. In addition the widgets I made are stored in my App directory in a folder labeled widgets and then referenced as App\Widgets\somefilename.
Steps To Reproduce:

create a folder labeled widgets
create php file for widget
copy and paste widget code from the dummy generated in the vendor/tcg/src/widgets section and modify for whatever the widget is showing
php artisan config:cache and refresh

I am also having the same problem!!
New Widgets doent get formed ,nor removed while modifying voyager.php

@hemantachhami19 I opted to build my own partially for that reason.

I have had the same problem with my layout, and I know the reason for this behavior.
The blade template dimmers.blade.php is used to output all of the Dimmers i.e. Widgets, in voyager context, to HTML. If you look at the template, you can see that it is quite specifically made to only support up to three different widgets (if the count sees two widgets, we will output different classnames to our widgets than if there are three)
This is done by calling the Voyager::dimmers() function, shown below
    /**
     * Get a collection of the dashboard widgets.
     *
     * @return \Arrilot\Widgets\WidgetGroup
     */
    public function dimmers()
    {
        $widgetClasses = config('voyager.dashboard.widgets');
        $dimmers = Widget::group('voyager::dimmers');

        foreach ($widgetClasses as $widgetClass) {
            $widget = app($widgetClass);

            if ($widget->shouldBeDisplayed()) {
                $dimmers->addWidget($widgetClass);
            }
        }

        return $dimmers;
    }

As you can see, we return an instance of \Arrilot\Widgets\WidgetGroup, which is a package used to simplify widget creation. Unfortunately, a WidgetGroup does not give developers an iterative process of going through these widgets.
We are presented with a problem based on how this dimmers() function was created as well. There is almost no way to override this behavior without including a vast amount of voyager source within developer's projects and playing with app configs.
Possible solution

Update the Voyager::dimmers() function to return an array of WidgetGroups, each of which contains up to a max of three widgets. As an example, if we have 2 Widgets, we will return an array containing only 1 WidgetGroup. If we have 5 Widgets we will return an array containing 2 WidgetGroups, and follow this pattern ad infinitum.

Update dimmers.blade.php to handle the changes that are to come from the changes to the Voyager::dimmers() function.

I'm working on this and should be presenting a pull request soon.


"Upgrade Available" flag is still present when the service is already upgraded to the latest version and is in "upgraded"/"active" state until the page is refreshed manually.

Server version - v0.44.0-rc2
Created a stack from catalog using the older version of "Elastic Search" template.
"Upgrade Available" option is presented to user.
Upgrade this service.
When service is in "Upgraded" state , "Upgrade Available" option is still presented to user.

"Finish Upgrade" and wait for service state to get to "Active" state. "Upgrade Available" option is still presented to user.

Once refresh , the "Upgrade Available" option is not present anymore.

Changed to show 'Upgrade in progress' during upgrade.

Version - Master with latest reskin UI
Verified fixed


Correction for Publication Information of "Meddiffusion"

I just want to say that the literature you compiled has been incredibly helpful for my research. Thank you for your hard work!
I noticed a small error regarding the publication information for the paper titled "Meddiffusion: Boosting Health Risk Prediction via Diffusion-Based Data Augmentation." It should be published in SIAM 2024 instead of MICCAI 2023. Thank you for your attention to this detail!

Hi @0606zt,
Thank you so much for your interest in our repository. I'm glad it was helpful for your research.
The issue has been fixed now. Thanks for letting us know. Have a great holiday! 😊


Unable to use hooks inside ItemRenderer

I implemented a simple customized react functional component for itemRenderer. Within this component I would like to define a state with the React.useState. When I do I get an error saying: "Invalid hook call. Hooks can only be called inside of the body of a function component..."
Important to note that I don't encounter this issue when using hooks within my customized groupRenderer.
I dug into the code and changed the return statement of Item.js from
return this.props.itemRenderer({
      item: this.props.item,
      timelineContext,
      itemContext,
      getItemProps: this.getItemProps,
      getResizeProps: this.getResizeProps,
    });

to
return React.createElement(this.props.itemRenderer, {
    item: this.props.item,
    timelineContext,
    itemContext,
    getItemProps: this.getItemProps,
    getResizeProps: this.getResizeProps,
});

This solved my issue, however I am not certain why and if it is the correct way. I'd be happy to help on the matter. Any thoughts?

I have the same issue, however @idannn98's solution doesn't work for me....

@idannn98's solution worked for me.

@idannn98's solution worked as well, but we don't need to edit the module's source code...

I found a solution. I made a class based wrapper (HOC) for the item renderer, in the HOC I manage the hook, in my case a useState, but using the constructor and pass the information to the children (the itemRenderer). Here is a snippet of my code.
In the Timeline:

The HOC:

Receiving the props in the itemRenderer:


Replace class iterator and const_iterator by using a single template class to reduce code.

Class iterator and const_iterator can be merged by a single template class.
Currently the classes differ by aliases. This can be handled by the template parameter.
Const_iterator can be created using an iterator. Iterator cannot be created from a const_iterator.
This can be achieved by a conversion function in the template class.

Coverage remained the same at 100.0% when pulling 92e28c31530a2a2411fe6711691aa8e2757c79b0 on Bosswestfalen:develop into 2f94c30baddaa6267961b3d61a86c438c3e9ac2c on nlohmann:develop.

Thanks!


Add Gnocchi calorimetry for PDDP reco

Approved.  But in general, it is confusing to use "./" in an #include line in fcl.  I tested this and it has no impact for fcl files that are included from fcl file path.  "." should already be at the front of your fhicl file path and if it's not, "./" in the #include statement won't make art look in the current wd.  It doesn't hurt, it just doesn't help.


Rambo vomits when there is no method description

Currently, under each method listed for a given route, Rambo relies on there being a method description to generate the case description. When there is no method description given, the following error appears:
    ____   ___     __  ___ ____   ____
   / __ \ /   |   /  |/  // __ ) / __ \
  / /_/ // /| |  / /|_/ // __  |/ / / /
 / _, _// ___ | / /  / // /_/ // /_/ /
/_/ |_|/_/  |_|/_/  /_//_____/ \____/

Generating contract tests...
Error: undefined method `downcase' for nil:NilClass

The source of this is /lib/rspec/templates/example_group_template.erb:9, where downcase is called on method.description.

The PR resolving this issue is not being merged yet because of #20 (JSON Test Data 0.7 breaks tests).

Resolved


Phantom marks left after delete

I have the following document:
  line 1
a line 2
  line 3
b line 4
  line 5

If I issue :'a,'bdelete I'm left with some phantom markers that I cannot get rid of. It looks like this:
  line 1
a line 5

The a mark is not set in vim since I get E20: mark not set when I try to jump to it. :SignatureRefresh doesn't help. If I set the a mark somewhere else in the document the mark shows up correctly at the new place but does not get removed from the old place. It could look like this:
  line 1
a line 5
  <more lines>
a line 99

I hope the issue is resolved. If not, please feel free to reopen it.

I'm seeing this issue pretty frequently now. To repro here's what I do.
ma to clear the phantom mark. Close nvim. Reopen the same file, and the mark is back. Any suggestions?
In general are normal vim marks supposed to disappear when you close vim?

@jamischarles I'm not able to reproduce this error with vim. If I run :'a,'bd, there are no phantom marks left behind.
I'll go home and try it out with nvim.

I did see this when I tried to clear a mark just right now Signature: Unable to read/write .viminfo

I had to sudo to even see the contents of the file

That doesn't sound like an issue with the plugin itself but incorrect permissions on the .viminfo file itself. Vim uses .viminfo to save information such as command line history, search history, marks etc. Signature just reads and writes to the file to ensure that global marks are correctly removed.
Could you run ls -l ~/.viminfo and post the output?

→ ls -l ~/.viminfo
-rw-------  1 root  110187567  1023 Sep 12 10:46 /Users/jacharles/.viminfo

I'm going to wipe it and recreate it with touch and see what effect that has. What are the expected permissions for .viminfo?

This might explain it. Looks like neovim doesn't use .viminfo anymore: https://www.reddit.com/r/neovim/comments/5con51/where_is_neovims_viminfo_located/

I tried wiping my .viminfo, then symlinking my main.shada file to the .viminfo file, but the issue still persists even with that.

Related I think https://github.com/neovim/neovim/issues/4288

tl;dr: Sounds like the hacky workaround is for meto call :wshada! before I exit the file, or after I change marks to persist those mark deletions.

Those threads imply that this behavior was present with viminfo files as well. Wonder if we can apply your same workaround here and call :wshada! in the same place?

I see in this file https://github.com/kshenoy/vim-signature/blob/master/autoload/signature/mark.vim#L324 that you're manually adjusting the .viminfo file. I'd be happy to issue a PR to fix this for neovim. Here's what I'm thinking:

Check if you're in neovim.
On global / local mark remove, run :wsh command (or we could manually remove entry from shada file (neovim equivalent of viminfo)

Thoughts?
:wsh[ada][!] [file]	Write to ShaDa file [file] (default: see above).
			The information in the file is first read in to make
			a merge between old and new info.  When [!] is used,
			the old information is not read first, only the
			internal info is written (also disables safety checks
			described in |shada-error-handling|).  If 'shada' is
			empty, marks for up to 100 files will be written.
			When you get error "E929: All .tmp.X files exist,
			cannot write ShaDa file!" check that no old temp files
			were left behind (e.g.
			~/.local/share/nvim/shada/main.shada.tmp*).

			Note: Executing :wshada will reset all |'quote| marks.

Check if you're in neovim.

Ah nevermind, that's the problem. For some reason I assumed you were using both vim and neovim (even though you didn't mention anything about using vim) and the mention of .viminfo caused me to lead you on a wild goose chase. My apologies for that and thanks for the debug.
I updated that function s:ForceGlobalMarkRemoval to work with neovim. However, note that the methodology to remove the global mark is different than earlier and may have much bigger side-effects so it's been disabled by default. Set g:ForceRemoveGlobalMark to 1 if you want to use this.


Added Kafka 3.1.0 to integration tests and changed misc error handling

Integration Tests

Added Kafka 3.1.0
Updated readme to reflect versions tested
Simplified Dockerfile
Added set -e to potentially catch other errors

Dependencies

Switched logs to use 'tracing' crate instead
Removed 'log' and 'env_logger' dependencies
Added 'tracing-subscriber' dependency to replace 'env_logger'

Core

Made offset storage optional
Error during commit if offset storage or group id is empty

Examples (esp. console-consumer)

Added --follow option
Changed '--no-commit' to '--commit'
Default to 'GroupOffsetStorage=None'
etc.

@johnward, this is my first PR for a Rust project. Some of the changes are pretty minor, but the logging change in particular was handy for my testing, so I hope you like it also. I'm happy to discuss the PR and/or the kafka-rust project in chat if you're on Slack/Discord somewhere. This project seems very promising, not only as a great Kafka client library but also as a decent kafka CLI.
Cheers!

I will review this PR over the weekend, thank you so much for your efforts on this.
John


Allow configuration of LDAP connection authentication mechanism

Refer to: https://github.com/rroemhild/flask-ldapconn/blob/master/flask_ldapconn.py#L116
This line forces the connection to use the simple authentication method. Why not allow the user to specify the type of authentication they want?
Personally I want to use the anonymous authentication method.

Thank you for this hint, anonymous auth works now on version 0.3.3. I will look into SASL auth another time.
Regards


Add a simple HTTP resolver

This adds a simple HTTP resolver that can fetch a file from a remote HTTP(S) URL.
Only fetch timeout configuration for now is supported.
This is kept simple for now, and does not support any kind of HTTP authentication, custom TLS or any other features. Something we can improve on later.
Fixes #6920

Changes

Submitter Checklist
As the author of this PR, please check off the items in this checklist:

[X] Has Docs if any changes are user facing, including updates to minimum requirements e.g. Kubernetes version bumps
[X] Has Tests included if any functionality added or changed
[X] Follows the commit message standard
[X] Meets the Tekton contributor standards (including functionality, content, code)
[X] Has a kind label. You can add one by adding a comment on this PR that contains /kind <type>. Valid types are bug, cleanup, design, documentation, feature, flake, misc, question, tep
[ ] Release notes block below has been updated with any user facing changes (API changes, bug fixes, changes requiring upgrade notices or deprecation warnings). See some examples of good release notes.
[ ] Release notes contains the string "action required" if the change requires additional action from users switching to the new release

Release Notes
A new HTTP resolver is now available, it will let you resolve a http(s) URL to fetch a task or pipeline from.

/kind feature

/kind feature
/retest

/test pull-tekton-pipeline-beta-integration-tests

/retest

Shall we create an issue to track potential future work as you mentioned in the pr description?

thanks for the review, yes i am planning to fill/tackle those issues when this is merged !

Is it possible that we add an example as @jerop suggested?

@Yongxuanzhang I didn't see @jerop comment, thanks!

@Yongxuanzhang I didn't see @jerop comment, thanks!
I just pushed it!

Thanks!
/lgtm

The CI issue was some yaml whitespace errors 🍤

/lgtm


Dark mode to Light mode

The site would have a better appearance if the transition from dark mode to light mode and vice-versa was smoother.

Can you be more specific? What's not smooth?

Switching from dark mode to light mode and light mode to dark mode seems abrupt.

A gif/video would would be worth a thousand words here

https://www.youtube.com/watch?v=_f036OpnuWo
I think this video explains it all.
On Fri, 26 Jun 2020 at 13:45, Ayush Shukla<EMAIL_ADDRESS>wrote:

A gif/video would would be worth a thousand words here
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/covid19india/covid19india-react/issues/2185#issuecomment-650048817,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AMWCIZZRC352QE43PVQC7R3RYRKLDANCNFSM4OGVIUYA
.

Previously there was a lag while switching to dark mode to light mode, sorry I couldn't record a gif or video back then, but now the problem seems to be fixed, I tried using responsive as well and desktop view while testing it, you can check it here @tarunkishore2303
Chrome Version : Version 83.0.4103.116 (Official Build) (64-bit)

I am trying to make it smoother dude. You can refer to the YouTube video shared above.

I guess he is trying to say that there is no animation between light to dark and dark to light which might affect people's eyes when changed immediately/especially using in dark,   so some smooth transition animation of 1sec would help to solve this issue.

Yeah ! Exactly !!

I think it just needs a transition element added to dark mode toggling CSS. I have ran this locally, and have this following transition, is this what you want @tarunkishore2303?

If this is okay, and the status is made available, I can claim and publish a PR.

I think it just needs a transition element added to dark mode toggling CSS. I have ran this locally, and have this following transition, is this what you want @tarunkishore2303?

If this is okay, and the status is made available, I can claim and publish a PR.

Yeah it's good

Not exactly but a little bit smoother

Closing due to inactivity


docs: error plugin

Version
@nuxtjs/strapi:  v1.7.1
nuxt: v3.1.2
Hello,
In the error reporting section where the docs show an example of adding a plugin, it currently is this:
import type { Strapi4Error } from '@nuxtjs/strapi'
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin((nuxt) => {
  nuxt.hooks.hook('strapi:error' as any, (e: Strapi4Error) => {
    nuxt.$toast.error({ title: e.error.name, description: e.error.message })
  })
})

However, the type Strapi4Error is not available on that path. This import path works however: @nuxtjs/strapi/dist/runtime/types
Also, importing defineNuxtPlugin is not necessary.
So, this could perhaps be rewritten to this:
import type { Strapi4Error } from "@nuxtjs/strapi/dist/runtime/types";

export default defineNuxtPlugin((nuxt) => {
  nuxt.hooks.hook("strapi:error" as any, (e: Strapi4Error) => {
    nuxt.$toast.error({ title: e.error.name, description: e.error.message })
  });
});

P.S. The same goes for the v3 example I guess

P.S. nuxt.hooks.hook(...) is not necessary. nuxt.hook(...) is enough.
From Nuxt documentation.

Thanks for spotting this, documentation has been updated! 😊


Add silverstripe/login-forms as direct dependency of silverstripe/mfa

We are testing our designs based on their output with the login-forms module installed. This will be the preferred approach to using the MFA module.
Resolves #95.

@robbieaverill It's automatic - we should document the best way to disable it, though 🤔


registering SRV DNS record gives error

Confirmation

[X] My issue isn't already found on the issue tracker.
[X] I have replicated my issue using the latest version of the provider and it is still present.

Terraform and Cloudflare provider version
terraform-provider-cloudflare_v3.1.0
Affected resource(s)
cloudflare_record
Terraform configuration files
resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7" {
  allow_overwrite = false
  name = "_sipfederationtls._tcp"
  proxied = false
  ttl = 3600
  type = "SRV"
  zone_id = "b6fa9f7048d914ac79ad7ce3d9975182"
  data {
    name = "iute.ee"
    port = 5061
    priority = 100
    proto = "_tcp"
    service = "_sipfederationtls"
    target = "sipfed.online.lync.com"
    weight = 1
  }
}

Debug output
{
"result": {
"id": "32a84f5fec535ab2199f8cc8f2b61ba7",
"zone_id": "b6fa9f7048d914ac79ad7ce3d9975182",
"zone_name": "iute.ee",
"name": "_sipfederationtls._tcp.iute.ee",
"type": "SRV",
"content": "1\t5061\tsipfed.online.lync.com",
"priority": 100,
"proxiable": false,
"proxied": false,
"ttl": 3600,
"locked": false,
"data": {
"name": "iute.ee",
"port": 5061,
"priority": 100,
"proto": "_tcp",
"service": "_sipfederationtls",
"target": "sipfed.online.lync.com",
"weight": 1
},
"meta": {
"auto_added": false,
"managed_by_apps": false,
"managed_by_argo_tunnel": false,
"source": "primary"
},
"created_on": "2021-08-16T07:07:28.805236Z",
"modified_on": "2021-08-16T07:07:28.805236Z"
},
"success": true,
"errors": [],
"messages": []
}
debug.log
Panic output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
cloudflare_record.terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7 will be updated in-place
~ resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7" {
+ allow_overwrite = false
id              = "32a84f5fec535ab2199f8cc8f2b61ba7"
name            = "_sipfederationtls._tcp"
# (11 unchanged attributes hidden)
  + data {
      + name     = "iute.ee"
      + port     = 5061
      + priority = 100
      + proto    = "_tcp"
      + service  = "_sipfederationtls"
      + target   = "sipfed.online.lync.com"
      + weight   = 1
    }

    # (1 unchanged block hidden)
}

Plan: 0 to add, 1 to change, 0 to destroy.
╷
│ Warning: Resource targeting is in effect
│
│ You are creating a plan with the -target option, which means that the result of this plan may not represent all of the changes requested by the current configuration.
│
│ The -target option is not for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use it as part of an error message.
╵
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
cloudflare_record.terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7: Modifying... [id=32a84f5fec535ab2199f8cc8f2b61ba7]
╷
│ Warning: Applied changes may be incomplete
│
│ The plan was created with the -target option in effect, so some changes requested in the configuration may have been ignored and the output values may not be fully updated. Run the following command to verify that
│ no other changes are pending:
│     terraform plan
│
│ Note that the -target option is not suitable for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use it as part
│ of an error message.
╵
╷
│ Error: Plugin did not respond
│
│   with cloudflare_record.terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7,
│   on iute.ee.tf line 110, in resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7":
│  110: resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7" {
│
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange call. The plugin logs may contain more details.
╵
Releasing state lock. This may take a few moments...
Stack trace from the terraform-provider-cloudflare_v3.1.0 plugin:
panic: interface conversion: interface {} is []interface {}, not map[string]interface {}
goroutine 71 [running]:
github.com/cloudflare/terraform-provider-cloudflare/cloudflare.resourceCloudflareRecordUpdate(0xc00066cd00, {0x1bd9840, 0xc000826180})
github.com/cloudflare/terraform-provider-cloudflare/cloudflare/resource_cloudflare_record.go:510 +0xa39
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).update(0xc0002d8750, {0x1e04248, 0xc00010fdc0}, 0x24, {0x1bd9840, 0xc000826180})
github.com/hashicorp/terraform-plugin-sdk/v2@v2.7.1/helper/schema/resource.go:352 +0x178
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0001ee380, {0x1e04248, 0xc00010fdc0}, 0xc000918380, 0xc0003739c0, {0x1bd9840, 0xc000826180})
github.com/hashicorp/terraform-plugin-sdk/v2@v2.7.1/helper/schema/resource.go:464 +0x6ba
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0000ac1e0, {0x1e04248, 0xc00010fdc0}, 0xc00088c320)
github.com/hashicorp/terraform-plugin-sdk/v2@v2.7.1/helper/schema/grpc_provider.go:955 +0x9aa
github.com/hashicorp/terraform-plugin-go/tfprotov5/server.(*server).ApplyResourceChange(0xc00007d8e0, {0x1e042f0, 0xc00079e060}, 0xc0005abc00)
github.com/hashicorp/terraform-plugin-go@v0.3.1/tfprotov5/server/server.go:332 +0x6c
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0x1b9c120, 0xc00007d8e0}, {0x1e042f0, 0xc00079e060}, 0xc00036c0c0, 0x0)
github.com/hashicorp/terraform-plugin-go@v0.3.1/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:380 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0003d8fc0, {0x1e15c28, 0xc0005c6000}, 0xc0000cd440, 0xc00024e660, 0x24b2f80, 0x0)
google.golang.org/grpc@v1.40.0/server.go:1297 +0xccf
google.golang.org/grpc.(*Server).handleStream(0xc0003d8fc0, {0x1e15c28, 0xc0005c6000}, 0xc0000cd440, 0x0)
google.golang.org/grpc@v1.40.0/server.go:1626 +0xa2a
google.golang.org/grpc.(*Server).serveStreams.func1.2()
google.golang.org/grpc@v1.40.0/server.go:941 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
google.golang.org/grpc@v1.40.0/server.go:939 +0x294
Error: The terraform-provider-cloudflare_v3.1.0 plugin crashed!
Expected output
applied succesfully
Actual output
│ Error: Plugin did not respond
│
│   with cloudflare_record.terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7,
│   on iute.ee.tf line 110, in resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7":
│  110: resource "cloudflare_record" "terraform_managed_resource_32a84f5fec535ab2199f8cc8f2b61ba7" {
│
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange call. The plugin logs may contain more details.
╵
Steps to reproduce
register SRV DNS
Additional factoids
No response
References
No response

This looks like a duplicate of #1227. Can you please confirm you've tried the PR attached to it as a solution and it still doesn't work?


.output/server/index.mjs cannot run standalone

Environment

Operating System: Linux
Node Version:     v18.12.0
Nuxt Version:     3.6.1
Nitro Version:    2.5.2
Package Manager<EMAIL_ADDRESS>Builder:          vite
User Config:      mode, editor, runtimeConfig, head, loading, css, modules, devServer, build, devtools
Runtime Modules<EMAIL_ADDRESS>Build Modules:    -

Reproduction

run yarn build on dev system
copy .output folder to server with same architecture & same node version
run node .output/server/index.mjs

Expected: nuxt3 app starts and listens for requests
Actual: Several errors during startup due to missing libraries
Describe the bug
I assumed the .output blob from nuxt build is standalone and able to run on the deployment server.
However it seems I need to run yarn install && yarn build also on the server.
From security perspective, I would like to fully build/bundle the production nuxt3 webapp on my dev system and just ship the trusted .output folder to the server.
Additional context
Building docker container is a solution for this problem of shipping a "known-good", running app to the server for deployment.
However, I feel it is overkill.
It'd be great if nuxt3 build result in .output folder could run on a machine with same operating system and architecture and nodejs version without a problem.
Is this kind of deployment a goal for nuxt3 or do you always recommend to yarn install && yarn build on the deployment server?
Logs
No response

It is meant to be standalone. If it is not working then there's an upstream bug in nitro we need to investigate.
Would you provide a reproduction? 🙏

Will create repro. The error messages were mentioning node-fetch-native and pg-native. I saw there are some issues open with regards to node-fetch-native and a bug that it sometimes multiple node-fetch-native versions are installed. I also have this case in my project<EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS>

Try refreshing your lockfile and see if that makes a difference. This is likely an issue with nitro's hoisting algorithm.


Support for TensorRT 6

With the newly released pytorch:19.09-py3 container, will there be support or an update for TensorRT 6?

Thank you for your suggestion. We are working on upgrading to the latest version of TensorRT, meanwhile having backward compatibility, and hope to release a new version of this code soon.

@FamousDirector can you please try out the 19.09 branch?

I'm not currently setup for training a new model but I have tested exporting a pre-existing .pth. The exported model works fine and is equivalent in terms of processing time and accuracy.
You may also want to consider making the exporting process less verbose, or print to a file. There is A LOT of output. Also please note the misspelled Docker repo path (I'm assuming the nvidian is an internal pointer vs the external nvidia).

@FamousDirector thanks for pointing that out. The verbosity occurring from export is resulting from the changes in TensorRT 6 which is default. We have pushed the changes to suppress verbosity to false by default.

Closing this, changes have been pushed to master.


[StackOverflow Question] Seperating css preprocess watch from js

Is there a convention for avoiding a wasteful update to unaltered files of another extension ie less, sass? Or am I right in thinking a separation of concerns by isolating your styles from the file watchers concerns would be the most efficient strategy for avoiding the issue?
I'v had to dance around this for years, please provide clarity on the best means of going about this in anyones opinions. This would make a good referable but if you disagree I apologize for cluttering your issues. I have no doubt many of us are just ignorant of the api to do this.
Ref. StackOverflow https://stackoverflow.com/questions/56202810/how-to-make-webpack-4-compile-sass-only-if-a-sass-file-has-changed-and-js-only/56202847?noredirect=1#comment99028339_56202847

It looks like you just deleted/ignored our lovely crafted issue template. It was there for good reasons. Please help us solving your issue by answering the questions asked in this template. I'm closing this. Please open a new issue with filled issue template. Also make sure your issue is not a question. Questions should be posted on Stack Overflow.


Using the EntryPoint metadata property, updating logic in the resolver to use provided named method and match Node's implementation

Resolves #481

Thanks. :ship:


Can't set datastore key/value pairs in 0.50.0

I ran into a problem trying to set a key/value pair in the latest version. I get the following error iwht 0.50.0:
% st2 key set foo boo
ERROR: 400 Client Error: Bad Request
MESSAGE: Extra data: line 1 column 5 - line 2 column 1 (char 4 - 19) for url: http://stackstorm-st2api:9101/keys/foo

The st2api logs show this exception:
2021-01-04 19:22:15,825 INFO [-] abc5b97e-6ae8-4bf1-8303-50da40b79cfd - PUT /keys/foo with query={} (method=‘PUT’,path=’/keys/foo’,remote_addr=‘<IP_ADDRESS>’,query={},request_id=‘abc5b97e-6ae8-4bf1-8303-50da40b79cfd’)
2021-01-04 19:22:15,832 ERROR [-] Failed to call controller function “put” for operation “st2api.controllers.v1.keyvalue:key_value_pair_controller.put”: Extra data: line 1 column 5 - line 2 column 1 (char 4 - 19)
Traceback (most recent call last):
File “/opt/stackstorm/st2/lib/python3.6/site-packages/st2common/router.py”, line 516, in call
resp = func(**kw)
File “/opt/stackstorm/st2/lib/python3.6/site-packages/st2api/controllers/v1/keyvalue.py”, line 292, in put
with self._coordinator.get_lock(lock_name):
File “/opt/stackstorm/st2/lib/python3.6/site-packages/tooz/locking.py”, line 52, in enter
acquired = self.acquire(*args, **kwargs)
File “/opt/stackstorm/st2/lib/python3.6/site-packages/tooz/drivers/etcd.py”, line 132, in acquire
“prevExist”: “false”})
File “/opt/stackstorm/st2/lib/python3.6/site-packages/tooz/drivers/etcd.py”, line 75, in put
return self.session.put(url, **kwargs).json()
File “/opt/stackstorm/st2/lib/python3.6/site-packages/requests/models.py”, line 898, in json
return complexjson.loads(self.text, **kwargs)
File “/opt/stackstorm/st2/lib/python3.6/site-packages/simplejson/init.py”, line 525, in loads
return _default_decoder.decode(s)
File “/opt/stackstorm/st2/lib/python3.6/site-packages/simplejson/decoder.py”, line 373, in decode
raise JSONDecodeError(“Extra data”, s, end, len(s))
simplejson.errors.JSONDecodeError: Extra data: line 1 column 5 - line 2 column 1 (char 4 - 19)
2021-01-04 19:22:15,833 INFO [-] abc5b97e-6ae8-4bf1-8303-50da40b79cfd - 400 84 8.372ms (method=‘PUT’,path=’/keys/foo’,remote_addr=‘<IP_ADDRESS>’,status=400,runtime=8.372,content_length=84,request_id=‘abc5b97e-6ae8-4bf1-8303-50da40b79cfd’)

Reverting the chart to 0.41.0 makes the problem go away.

Could reproduce it. Confirming, it's a bug.
Based on /tooz/drivers/etcd.py occurence in the error log, wondering if switching to other etcd versin via Helm charts in recent upgrade (https://github.com/StackStorm/stackstorm-ha/pull/163) is an issue here or not.

https://github.com/helm/charts/tree/master/stable/etcd-operator - previous etcd-operator chart
https://github.com/bitnami/charts/blob/master/bitnami/etcd/ - new etcd-operator chart

Could reproduce it. Confirming, it's a bug.
Based on /tooz/drivers/etcd.py occurence in the error log, wondering if switching to other etcd versin via Helm charts in recent upgrade (https://github.com/StackStorm/stackstorm-ha/pull/163) is an issue here or not.

https://github.com/helm/charts/tree/master/stable/etcd-operator - previous etcd-operator chart
https://github.com/bitnami/charts/blob/master/bitnami/etcd/ - new etcd-operator chart

Indeed new coordination backend is an issue.
Installing chart with coordination disabled:
helm upgrade --set etcd.enabled=false test stackstorm/stackstorm-ha

st2api:
2021-01-04 23:53:41,218 INFO [-] Creating st2api: StackStorm v3.4dev as OpenAPI app.
2021-01-04 23:53:47,298 WARNING [-] Coordination backend is not configured. Code paths which use coordination service will use best effort approach and race conditions are possible.

st2client:
root@test-st2client-69bcb768b-5wts4:/opt/stackstorm# st2 key set foo bar
+------------------+--------------+
| Property         | Value        |
+------------------+--------------+
| name             | foo          |
| value            | bar          |
| scope            | st2kv.system |
| expire_timestamp |              |
+------------------+--------------+

We'll need to find another etcd version or use another coordination backend like Redis per https://github.com/StackStorm/stackstorm-ha/issues/94#issuecomment-608394681

For everyone affected, temporary workaround is disabling the etcd coordination backend in helm values and provide your own external coordination backend URL via st2.conf section of stackstorm-ha Helm chart values.
See https://github.com/StackStorm/stackstorm-ha/blob/e373c7280ffbd720502a45eb97bdf9ccd5391ba5/values.yaml#L517-L520

Indeed new coordination backend is an issue.
Installing chart with coordination disabled:
helm upgrade --set etcd.enabled=false test stackstorm/stackstorm-ha

st2api:
2021-01-04 23:53:41,218 INFO [-] Creating st2api: StackStorm v3.4dev as OpenAPI app.
2021-01-04 23:53:47,298 WARNING [-] Coordination backend is not configured. Code paths which use coordination service will use best effort approach and race conditions are possible.

st2client:
root@test-st2client-69bcb768b-5wts4:/opt/stackstorm# st2 key set foo bar
+------------------+--------------+
| Property         | Value        |
+------------------+--------------+
| name             | foo          |
| value            | bar          |
| scope            | st2kv.system |
| expire_timestamp |              |
+------------------+--------------+

We'll need to find another etcd version or use another coordination backend like Redis per https://github.com/StackStorm/stackstorm-ha/issues/94#issuecomment-608394681

For everyone affected, temporary workaround is disabling the etcd coordination backend in helm values and provide your own external coordination backend URL via st2.conf section of stackstorm-ha Helm chart values.
See https://github.com/StackStorm/stackstorm-ha/blob/e373c7280ffbd720502a45eb97bdf9ccd5391ba5/values.yaml#L517-L520

I'm having time constraints on fixing it really quick, but if anyone wants to help with this ASAP, we'll need to switch to using
https://github.com/bitnami/charts/tree/master/bitnami/redis instead of etcd for external dependency Chart.
2 places will need an update:

Helm Values and Dependencies
st2.conf connection string for [coordination]
https://github.com/StackStorm/stackstorm-ha/blob/e373c7280ffbd720502a45eb97bdf9ccd5391ba5/templates/configmaps_st2-conf.yaml#L23-L26

I'm having time constraints on fixing it really quick, but if anyone wants to help with this ASAP, we'll need to switch to using
https://github.com/bitnami/charts/tree/master/bitnami/redis instead of etcd for external dependency Chart.
2 places will need an update:

Helm Values and Dependencies
st2.conf connection string for [coordination]
https://github.com/StackStorm/stackstorm-ha/blob/e373c7280ffbd720502a45eb97bdf9ccd5391ba5/templates/configmaps_st2-conf.yaml#L23-L26

In the recent past I had limited success in using Redis helm chart based deployment from bitnami when i did it outside of the ST2 chart. Limited because I was not able to make it work with Sentinel which is recommended for HA. This could very well be an issue on my side, though. will be curious to play with it and see if this time it behaves properly now.

In the recent past I had limited success in using Redis helm chart based deployment from bitnami when i did it outside of the ST2 chart. Limited because I was not able to make it work with Sentinel which is recommended for HA. This could very well be an issue on my side, though. will be curious to play with it and see if this time it behaves properly now.

This example https://github.com/openstack/tooz/blob/master/tooz/drivers/redis.py#L147-L155
might give some hints about proper Sentinel/Redis connection string.

This example https://github.com/openstack/tooz/blob/master/tooz/drivers/redis.py#L147-L155
might give some hints about proper Sentinel/Redis connection string.

@arms11 I'm using this and it works well:

redis://:@<sentinel1_fqdn>:26379?sentinel=<master_name>&sentinel_fallback=<sentinel2_fqdn>:26379&sentinel_fallback=<sentinel3_fqdn>:26379

@arms11 I'm using this and it works well:

redis://:@<sentinel1_fqdn>:26379?sentinel=<master_name>&sentinel_fallback=<sentinel2_fqdn>:26379&sentinel_fallback=<sentinel3_fqdn>:26379

got it. Thanks @armab . will follow that.

got it. Thanks @armab . will follow that.

I have a bit of bad news on this front. Over the weekend I tried to connect ST2 with in-place redis cluster with sentinel enabled. Following this link https://docs.bitnami.com/tutorials/deploy-redis-sentinel-production-cluster/ (somewhat obsolete after a year!!) I continuously keep getting No master found for <master-name> no matter what I give in the format described above for connection string. I tried redis, mymaster, master0, even <master pod name> and <master pod IP>. But no avail.
I have a dilemma:

Sentinel is recommended but for some reason setup is not helping for tooz.
Without Sentinel, explicit master/slave arch does not have necessary documentation on how to form connection string. In this arch, we have to rely on Kubernetes Controller Manager to spin off the master pod. Single master can be used but then it does not give HA.

Found this on-line. https://github.com/andymccurdy/redis-py/issues/1388 but even this does not seem to help.

I have a bit of bad news on this front. Over the weekend I tried to connect ST2 with in-place redis cluster with sentinel enabled. Following this link https://docs.bitnami.com/tutorials/deploy-redis-sentinel-production-cluster/ (somewhat obsolete after a year!!) I continuously keep getting No master found for <master-name> no matter what I give in the format described above for connection string. I tried redis, mymaster, master0, even <master pod name> and <master pod IP>. But no avail.
I have a dilemma:

Sentinel is recommended but for some reason setup is not helping for tooz.
Without Sentinel, explicit master/slave arch does not have necessary documentation on how to form connection string. In this arch, we have to rely on Kubernetes Controller Manager to spin off the master pod. Single master can be used but then it does not give HA.

Found this on-line. https://github.com/andymccurdy/redis-py/issues/1388 but even this does not seem to help.

@arms11 If you could compose a draft PR to add the new Redis chart dependency, - we'll help further. I guess @wantdrink had a working setup with Redis + Sentinel.

@arms11 If you could compose a draft PR to add the new Redis chart dependency, - we'll help further. I guess @wantdrink had a working setup with Redis + Sentinel.

@armab Yes I'm using stable/redis-ha 4.9.3 with sentinel and the coordinator URL is posted above.
@arms11 The bitnami chart you are using are set as non-cluster with sentinel right? Could you provide your redis URL configured in stackstorm?

@armab Yes I'm using stable/redis-ha 4.9.3 with sentinel and the coordinator URL is posted above.
@arms11 The bitnami chart you are using are set as non-cluster with sentinel right? Could you provide your redis URL configured in stackstorm?

@wantdrink @armab  I have the draft PR: https://github.com/StackStorm/stackstorm-ha/pull/169
Connection String:
url = redis://st2ha-redis-node-0.st2ha-redis-headless:26379?sentinel=mymaster&sentinel_fallback=st2ha-redis-node-1.st2ha-redis-headless:26379&sentinel_fallback=st2ha-redis-node-2.st2ha-redis-headless:26379
Yes, i am using https://github.com/bitnami/charts/tree/master/bitnami/redis overriding their values-production.yaml
I do see lot of issues (on-hold) in the chart repo, but I am not an expert of redis nor i have used stable repo chart to say otherwise.
Please provide guidance on how to proceed.

@wantdrink @armab  I have the draft PR: https://github.com/StackStorm/stackstorm-ha/pull/169
Connection String:
url = redis://st2ha-redis-node-0.st2ha-redis-headless:26379?sentinel=mymaster&sentinel_fallback=st2ha-redis-node-1.st2ha-redis-headless:26379&sentinel_fallback=st2ha-redis-node-2.st2ha-redis-headless:26379
Yes, i am using https://github.com/bitnami/charts/tree/master/bitnami/redis overriding their values-production.yaml
I do see lot of issues (on-hold) in the chart repo, but I am not an expert of redis nor i have used stable repo chart to say otherwise.
Please provide guidance on how to proceed.

@wantdrink - I did not understand non-cluster with sentinel part. If you check the helm chart url, the Values.cluster.enabled and Values.sentinel .enabled both are true in my deployment.

@wantdrink - I did not understand non-cluster with sentinel part. If you check the helm chart url, the Values.cluster.enabled and Values.sentinel .enabled both are true in my deployment.

Understood.
I guess you can try cluster=false but sentinel = true.
That's a redis HA with sentinel but it's not a cluster.

Understood.
I guess you can try cluster=false but sentinel = true.
That's a redis HA with sentinel but it's not a cluster.

Just FYI, I was able to fix the issue without changing the coordination engine from etcd to redis by adding ETCD_ENABLE_V2="true" env variable on etcd helm.

Just FYI, I was able to fix the issue without changing the coordination engine from etcd to redis by adding ETCD_ENABLE_V2="true" env variable on etcd helm.

@tarcusx - that's nice to know. Good to have options!
Any documentation around what the envt variable was introduced for? was there an actual bug on ETCD side?

@tarcusx - that's nice to know. Good to have options!
Any documentation around what the envt variable was introduced for? was there an actual bug on ETCD side?

@arms11 Note that I'm using my own etcd helm, not the one specified by this stackstorm-ha chart.yaml. But I think the issue I hit is same as this one. It's because of the etcd version updated to v3.4.
etcd3 doc says
–enable-v2
Accept etcd V2 client requests
default: false
env variable: ETCD_ENABLE_V2

https://etcd.io/docs/v3.4.0/op-guide/configuration/
The default value for v2 protocol support is changed to false in version 3.4.
https://etcd.io/docs/v3.3.13/op-guide/configuration/ says default was true.
To use etcd protocol v2, we have to set ETCD_ENABLE_V2=true env variable on etcd pods.
Another option would be to use v3 protocol. tooz seems to have etcd3 v3 driver.
https://github.com/openstack/tooz/blob/master/tooz/drivers/etcd3.py#L118
A simple etcd URI config would solve the issue. But I haven't tested this.

@arms11 Note that I'm using my own etcd helm, not the one specified by this stackstorm-ha chart.yaml. But I think the issue I hit is same as this one. It's because of the etcd version updated to v3.4.
etcd3 doc says
–enable-v2
Accept etcd V2 client requests
default: false
env variable: ETCD_ENABLE_V2

https://etcd.io/docs/v3.4.0/op-guide/configuration/
The default value for v2 protocol support is changed to false in version 3.4.
https://etcd.io/docs/v3.3.13/op-guide/configuration/ says default was true.
To use etcd protocol v2, we have to set ETCD_ENABLE_V2=true env variable on etcd pods.
Another option would be to use v3 protocol. tooz seems to have etcd3 v3 driver.
https://github.com/openstack/tooz/blob/master/tooz/drivers/etcd3.py#L118
A simple etcd URI config would solve the issue. But I haven't tested this.


can not import name:eval_nmt_checkpoint

when i run your code,i meet the above error.Can you help me to solve it?Thanks a lot.

Traceback (most recent call last):
File "nmt_prior.py", line 9, in
from models.nmt_prior_callbacks import EvalCallback, SamplesCallback,
File "./models/nmt_prior_callbacks.py", line 12, in
from models.translate import seq2seq_translate_ids,
File "./models/translate.py", line 18, in
from models.nmt_prior_helpers import prior_model_from_checkpoint
File "./models/nmt_prior_helpers.py", line 24, in
from models.translate import eval_nmt_checkpoint, seq2seq_translate
ImportError: cannot import name 'eval_nmt_checkpoint'
this is my complete error output!

Please give more details. First of all, what is the command that you are running?

Reopen the issue, if you are still facing problems.


Templating with JSX

We currently allow customized templates via the template option, but it's not great because the user must use strings instead of JSX. This plugin is to help when building with React, so it would make sense to allow templating with JSX instead of string values.

Along the same lines, it'd be nice to add support for using something like react-document-meta for the title/meta tags, instead of setting properties on the route object.

Oooh nice, thanks for the suggestion @petebrowne. I'll check out that lib next time I work on this issue

Note to self: Might be able to accomplish JSX templating using babel-core directly for string transpilation: https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/user-handbook.md#babel-core

You could use ejs. Have a look at https://github.com/scherler/react-es6-webpack-boilerplate/blob/master/webpack.config.production.js where I am using the static-render-webpack-plugin (from there you can see how they doing it).

Thanks for the suggestion @scherler. EJS would certainly be a more rich templating experience than simple string interpolation. The reasoning for using JSX is that since JSX already provides a rich tempalting experience and it will already be known by most people using this plugin.

Added support for this in v1 (diff bae92d1).

I like the changes a lot, thanks for the update!