From 54947573bf3289719662e303f3cd7aaa94949cc4 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Fri, 12 Jul 2024 16:58:34 +0300 Subject: [PATCH] example best practice --- docs/docs/installation/github.md | 5 +- docs/docs/overview/pr_agent_pro.md | 39 ++-- docs/docs/tools/improve.md | 22 +- .../docs/usage-guide/EXAMPLE_BEST_PRACTICE.md | 188 ++++++++++++++++++ 4 files changed, 224 insertions(+), 30 deletions(-) create mode 100644 docs/docs/usage-guide/EXAMPLE_BEST_PRACTICE.md diff --git a/docs/docs/installation/github.md b/docs/docs/installation/github.md index 4f7be99a..0a8bcda3 100644 --- a/docs/docs/installation/github.md +++ b/docs/docs/installation/github.md @@ -26,7 +26,9 @@ jobs: OPENAI_KEY: ${{ secrets.OPENAI_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` -** if you want to pin your action to a specific release (v2.0 for example) for stability reasons, use: + + +if you want to pin your action to a specific release (v2.0 for example) for stability reasons, use: ```yaml ... steps: @@ -35,6 +37,7 @@ jobs: uses: Codium-ai/pr-agent@v2.0 ... ``` + 2) Add the following secret to your repository under `Settings > Secrets and variables > Actions > New repository secret > Add secret`: ``` diff --git a/docs/docs/overview/pr_agent_pro.md b/docs/docs/overview/pr_agent_pro.md index cbb9496b..4fa69817 100644 --- a/docs/docs/overview/pr_agent_pro.md +++ b/docs/docs/overview/pr_agent_pro.md @@ -1,21 +1,28 @@ [PR-Agent Pro](https://www.codium.ai/pricing/) is a hosted version of PR-Agent, provided by CodiumAI. It is available for a monthly fee, and provides the following benefits: 1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the PR-Agent app to your GitHub\GitLab\BitBucket repo. + 2. **Improved privacy** - No data will be stored or used to train models. PR-Agent Pro will employ zero data retention, and will use an OpenAI account with zero data retention. + 3. **Improved support** - PR-Agent Pro users will receive priority support, and will be able to request new features and capabilities. -4. **Extra features** -In addition to the benefits listed above, PR-Agent Pro will emphasize more customization, and the usage of static code analysis, in addition to LLM logic, to improve results. It has the following additional tools and features: - - (Tool): [**Analyze PR components**](./tools/analyze.md/) - - (Tool): [**Custom Prompt Suggestions**](./tools/custom_prompt.md/) - - (Tool): [**Tests**](./tools/test.md/) - - (Tool): [**PR documentation**](./tools/documentation.md/) - - (Tool): [**Improve Component**](https://pr-agent-docs.codium.ai/tools/improve_component/) - - (Tool): [**Similar code search**](https://pr-agent-docs.codium.ai/tools/similar_code/) - - (Tool): [**CI feedback**](./tools/ci_feedback.md/) - - (Feature): [**Interactive triggering**](./usage-guide/automations_and_usage.md/#interactive-triggering) - - (Feature): [**SOC2 compliance check**](./tools/review.md/#soc2-ticket-compliance) - - (Feature): [**Custom labels**](./tools/describe.md/#handle-custom-labels-from-the-repos-labels-page) - - (Feature): [**Global and wiki configuration**](./usage-guide/configuration_options.md/#wiki-configuration-file) - - (Feature): [**Inline file summary**](https://pr-agent-docs.codium.ai/tools/describe/#inline-file-summary) - - (Feature): [**Apply suggestions**](https://pr-agent-docs.codium.ai/tools/improve/#example-usage) - - (Feature): [**Advanced usage statistics**](https://www.codium.ai/contact/#/) -5. **Support self-hosted git servers** - PR-Agent Pro can be installed on GitHub Enterprise Server, GitLab, and BitBucket. For more information, see the [installation guide](https://pr-agent-docs.codium.ai/installation/pr_agent_pro/). \ No newline at end of file + +4. **Additional tools** +- [**Analyze PR components**](./tools/analyze.md/) +- [**Custom Prompt Suggestions**](./tools/custom_prompt.md/) +- [**Tests**](./tools/test.md/) +- [**PR documentation**](./tools/documentation.md/) +- [**Improve Component**](https://pr-agent-docs.codium.ai/tools/improve_component/) +- [**Similar code search**](https://pr-agent-docs.codium.ai/tools/similar_code/) +- [**CI feedback**](./tools/ci_feedback.md/) + +5. **Additional features** +- [**Global and wiki configuration**](./usage-guide/configuration_options.md/#wiki-configuration-file) +- [**Interactive triggering**](./usage-guide/automations_and_usage.md/#interactive-triggering) +- [**Apply suggestions**](https://pr-agent-docs.codium.ai/tools/improve/#example-usage) +- [**Advanced usage statistics**](https://www.codium.ai/contact/#/) +- [**SOC2 compliance check**](./tools/review.md/#soc2-ticket-compliance) +- [**Custom labels**](./tools/describe.md/#handle-custom-labels-from-the-repos-labels-page) +- [**Inline file summary**](https://pr-agent-docs.codium.ai/tools/describe/#inline-file-summary) +- More ... + +6. **Supporting self-hosted git servers** - PR-Agent Pro can be installed on GitHub Enterprise Server, GitLab, and BitBucket. For more information, see the [installation guide](https://pr-agent-docs.codium.ai/installation/pr_agent_pro/). \ No newline at end of file diff --git a/docs/docs/tools/improve.md b/docs/docs/tools/improve.md index 95edff51..809c1890 100644 --- a/docs/docs/tools/improve.md +++ b/docs/docs/tools/improve.md @@ -97,22 +97,18 @@ Use triple quotes to write multi-line instructions. Use bullet points or numbers #### Best practices 💎 Another option to give additional guidance to the AI model is by creating a dedicated [**wiki page**](https://github.com/Codium-ai/pr-agent/wiki) called `best_practices.md`. -This page can contain a list of best practices, coding standards, and guidelines that are specific to your repo/organization (up to 800 lines are allowed) +This page can contain a list of best practices, coding standards, and guidelines that are specific to your repo/organization -The AI model will use this page as a reference, and in case the PR code violates any of the guidelines, it will suggest improvements accordingly. -Examples for possible best practices: -``` -## Here are the organization's best practices for writing code: -- avoid nested loops -- avoid typos -- use meaningful variable names -- follow the DRY principle -- keep functions short and simple, typically within 10-30 lines of code. -... -``` -When a PR code violates any of the guidelines, the AI model will suggest improvements accordingly, with a dedicated label: `Organization +The AI model will use this page as a reference, and in case the PR code violates any of the guidelines, it will suggest improvements accordingly, with a dedicated label: `Organization best practice`. +Example for a `best_practices.md` content can be found [here](https://pr-agent-docs.codium.ai/usage-guide/EXAMPLE_BEST_PRACTICE.md) (adapted from Google's [pyguide](https://google.github.io/styleguide/pyguide.html)). +This file is only an example. Since it is used as a prompt for an AI model, we want to emphasize the following: +- It should be written in a clear and concise manner +- If needed, it should give short relevant code snippets as examples +- Up to 800 lines are allowed + + Example results: ![best_practice](https://codium.ai/images/pr_agent/org_best_practice.png){width=512} diff --git a/docs/docs/usage-guide/EXAMPLE_BEST_PRACTICE.md b/docs/docs/usage-guide/EXAMPLE_BEST_PRACTICE.md new file mode 100644 index 00000000..ebff9d49 --- /dev/null +++ b/docs/docs/usage-guide/EXAMPLE_BEST_PRACTICE.md @@ -0,0 +1,188 @@ +## Recommend Python best practices + +### Imports + +Use `import` statements for packages and modules only, not for individual types, classes, or functions. + +#### Definition + +Reusability mechanism for sharing code from one module to another. + +#### Decision + +- Use `import x` for importing packages and modules. +- Use `from x import y` where `x` is the package prefix and `y` is the module name with no prefix. +- Use `from x import y as z` in any of the following circumstances: + - Two modules named `y` are to be imported. + - `y` conflicts with a top-level name defined in the current module. + - `y` conflicts with a common parameter name that is part of the public API (e.g., `features`). + - `y` is an inconveniently long name, or too generic in the context of your code +- Use `import y as z` only when `z` is a standard abbreviation (e.g., `import numpy as np`). + +For example the module `sound.effects.echo` may be imported as follows: + +``` +from sound.effects import echo +... +echo.EchoFilter(input, output, delay=0.7, atten=4) + +``` + +Do not use relative names in imports. Even if the module is in the same package, use the full package name. This helps prevent unintentionally importing a package twice. + +##### Exemptions + +Exemptions from this rule: + +- Symbols from the following modules are used to support static analysis and type checking: + - [`typing` module](https://google.github.io/styleguide/pyguide.html#typing-imports) + - [`collections.abc` module](https://google.github.io/styleguide/pyguide.html#typing-imports) + - [`typing_extensions` module](https://github.com/python/typing_extensions/blob/main/README.md) +- Redirects from the [six.moves module](https://six.readthedocs.io/#module-six.moves). + +### Packages + +Import each module using the full pathname location of the module. + +#### Decision + +All new code should import each module by its full package name. + +Imports should be as follows: + +``` +Yes: + # Reference absl.flags in code with the complete name (verbose). + import absl.flags + from doctor.who import jodie + + _FOO = absl.flags.DEFINE_string(...) + +``` + +``` +Yes: + # Reference flags in code with just the module name (common). + from absl import flags + from doctor.who import jodie + + _FOO = flags.DEFINE_string(...) + +``` + +_(assume this file lives in `doctor/who/` where `jodie.py` also exists)_ + +``` +No: + # Unclear what module the author wanted and what will be imported. The actual + # import behavior depends on external factors controlling sys.path. + # Which possible jodie module did the author intend to import? + import jodie + +``` + +The directory the main binary is located in should not be assumed to be in `sys.path` despite that happening in some environments. This being the case, code should assume that `import jodie` refers to a third-party or top-level package named `jodie`, not a local `jodie.py`. + +### Default Iterators and Operators +Use default iterators and operators for types that support them, like lists, dictionaries, and files. + +#### Definition + +Container types, like dictionaries and lists, define default iterators and membership test operators (“in” and “not in”). + +#### Decision + +Use default iterators and operators for types that support them, like lists, dictionaries, and files. The built-in types define iterator methods, too. Prefer these methods to methods that return lists, except that you should not mutate a container while iterating over it. + +``` +Yes: for key in adict: ... + if obj in alist: ... + for line in afile: ... + for k, v in adict.items(): ... +``` + +``` +No: for key in adict.keys(): ... + for line in afile.readlines(): ... +``` + +### Lambda Functions + +Okay for one-liners. Prefer generator expressions over `map()` or `filter()` with a `lambda`. + +#### Decision + +Lambdas are allowed. If the code inside the lambda function spans multiple lines or is longer than 60-80 chars, it might be better to define it as a regular [nested function](https://google.github.io/styleguide/pyguide.html#lexical-scoping). + +For common operations like multiplication, use the functions from the `operator` module instead of lambda functions. For example, prefer `operator.mul` to `lambda x, y: x * y`. + +### Default Argument Values + +Okay in most cases. + +#### Definition + +You can specify values for variables at the end of a function’s parameter list, e.g., `def foo(a, b=0):`. If `foo` is called with only one argument, `b` is set to 0. If it is called with two arguments, `b` has the value of the second argument. + +#### Decision + +Okay to use with the following caveat: + +Do not use mutable objects as default values in the function or method definition. + +``` +Yes: def foo(a, b=None): + if b is None: + b = [] +Yes: def foo(a, b: Sequence | None = None): + if b is None: + b = [] +Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable. + ... +``` + +``` +from absl import flags +_FOO = flags.DEFINE_string(...) + +No: def foo(a, b=[]): + ... +No: def foo(a, b=time.time()): # Is `b` supposed to represent when this module was loaded? + ... +No: def foo(a, b=_FOO.value): # sys.argv has not yet been parsed... + ... +No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code. + ... +``` + +### True/False Evaluations + + +Use the “implicit” false if possible, e.g., `if foo:` rather than `if foo != []:` + +### Lexical Scoping + +Okay to use. + +An example of the use of this feature is: + +``` +def get_adder(summand1: float) -> Callable[[float], float]: + """Returns a function that adds numbers to a given number.""" + def adder(summand2: float) -> float: + return summand1 + summand2 + + return adder +``` +#### Decision + +Okay to use. + + +### Threading + +Do not rely on the atomicity of built-in types. + +While Python’s built-in data types such as dictionaries appear to have atomic operations, there are corner cases where they aren’t atomic (e.g. if `__hash__` or `__eq__` are implemented as Python methods) and their atomicity should not be relied upon. Neither should you rely on atomic variable assignment (since this in turn depends on dictionaries). + +Use the `queue` module’s `Queue` data type as the preferred way to communicate data between threads. Otherwise, use the `threading` module and its locking primitives. Prefer condition variables and `threading.Condition` instead of using lower-level locks. \ No newline at end of file