Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for http based repositories #42

Merged
merged 10 commits into from
Oct 14, 2024

Conversation

GRMrGecko
Copy link
Contributor

@GRMrGecko GRMrGecko commented Oct 12, 2024

Hello,

I had a need to add http repository support to this project for a project I was working on. As this is open source, I am contributing back. Hope this gets added, as I believe it is useful.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced support for HTTP-based repositories, enabling software updates from custom HTTP sources.
    • Added a new section in the documentation detailing the HttpSource functionality and providing usage examples.
  • Bug Fixes

    • Improved clarity and flow of the README documentation.
  • Tests

    • Implemented a comprehensive suite of unit tests for HTTP source functionalities to ensure reliability and correct behavior.
  • Chores

    • Added a new YAML configuration file for testing release information, including multiple release entries and associated assets.

Copy link

coderabbitai bot commented Oct 12, 2024

Walkthrough

This pull request introduces updates to the selfupdate package, specifically enhancing the documentation and testing for HTTP-based repositories. A new section titled "Http Based Repository" is added to the README.md, detailing the HttpSource functionality. Additionally, a new test file, http_source_test.go, is created to implement unit tests for HTTP source functionalities, including server setup and various test cases for handling URLs and downloading assets.

Changes

File Change Summary
README.md Added new section "Http Based Repository" and example for HttpSource.
http_source_test.go Created tests for HTTP source functionalities, including test server setup and multiple test functions.

Poem

🐇 In the meadow, changes bloom,
HttpSource brings updates soon!
With assets ready, releases in sight,
Our software hops to new heights!
A README fresh, a test so bright,
Let’s celebrate this coding delight! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (8)
testdata/http_repo/manifest.yaml (1)

1-45: Well-structured manifest for HTTP-based repositories

The overall structure of the manifest is well-organized and consistent, making it suitable for managing HTTP-based repository releases. This aligns well with the PR objective of adding support for HTTP-based repositories. The use of unique IDs for releases and assets is a good practice that will facilitate future updates and maintenance.

Some suggestions for improvement:

  1. Consider adding a version field for the manifest itself to allow for future schema changes.
  2. You might want to include a base_url field at the root level if all assets share a common base URL.

Would you like assistance in implementing these suggestions or creating documentation for this new manifest structure?

http_source_test.go (6)

38-45: LGTM: Well-defined constant and struct for test server.

The httpRepoTestPort constant and HttpRepoTestServer struct are well-defined for the test server implementation.

Consider adding a comment explaining why the specific port number (8831) was chosen, or use a more descriptive constant name like httpRepoTestUnusedPort to clarify its purpose.


48-64: LGTM: Well-implemented test server setup.

The NewHttpRepoTestServer function correctly sets up an HTTP server for testing purposes, including appropriate handlers and configuration.

Consider enhancing the function's flexibility:

  1. Allow the port to be configurable, perhaps as an optional parameter with a default value.
  2. Make the test data directory path configurable to improve test isolation and reusability.

Example implementation:

func NewHttpRepoTestServer(port int, testDataDir string) *HttpRepoTestServer {
    if port == 0 {
        port = httpRepoTestPort
    }
    if testDataDir == "" {
        testDataDir = "./testdata/http_repo"
    }
    // ... rest of the function
}

67-95: LGTM: Well-implemented server control methods.

The Run, Stop, and Start methods of HttpRepoTestServer are well-implemented, providing proper control over the test server lifecycle.

Consider the following improvements:

  1. In the Stop method, handle the error returned by Shutdown:
    func (s *HttpRepoTestServer) Stop() error {
        return s.server.Shutdown(context.Background())
    }
  2. In the Start method, use a more idiomatic error handling approach:
    if err != nil && err != http.ErrServerClosed {
        return fmt.Errorf("server error: %w", err)
    }
  3. Add a timeout to the Run method to prevent indefinite blocking:
    select {
    case <-isListening:
        // Server is listening
    case <-time.After(5 * time.Second):
        return fmt.Errorf("timeout waiting for server to start")
    }

98-111: LGTM: Basic URL validation tests implemented.

The TestHttpClientInvalidURL and TestHttpClientValidURL functions provide basic tests for URL validation in the NewHttpSource function.

Consider enhancing these tests:

  1. Use assert or require functions from the testify package for more descriptive assertions:
    func TestHttpClientInvalidURL(t *testing.T) {
        _, err := NewHttpSource(HttpConfig{BaseURL: ":this is not a URL"})
        assert.Error(t, err, "Invalid URL should raise an error")
    }
    
    func TestHttpClientValidURL(t *testing.T) {
        source, err := NewHttpSource(HttpConfig{BaseURL: "http://localhost"})
        assert.NoError(t, err, "Failed to initialize HTTP source with valid URL")
        assert.NotNil(t, source, "HTTP source should not be nil")
    }
  2. Add more test cases with different types of invalid and valid URLs to ensure comprehensive coverage.

114-144: LGTM: Context cancellation tests are well-implemented.

The TestHttpListReleasesContextCancelled and TestHttpDownloadReleaseAssetContextCancelled functions effectively test the behavior of cancelling contexts in list and download operations.

To improve these tests, consider adding a small delay before cancelling the context to ensure that the operations have a chance to start:

func TestHttpListReleasesContextCancelled(t *testing.T) {
    // ... existing setup code ...

    ctx, cancelFn := context.WithCancel(context.Background())
    go func() {
        time.Sleep(10 * time.Millisecond)
        cancelFn()
    }()

    // ... rest of the test ...
}

Apply a similar change to TestHttpDownloadReleaseAssetContextCancelled. This modification will make the tests more robust by ensuring that the cancellation occurs during the operation rather than before it starts.


147-219: LGTM: Comprehensive tests for nil release and end-to-end functionality.

The TestHttpDownloadReleaseAssetWithNilRelease and TestHttpListAndDownloadReleaseAsset functions provide good coverage for error handling and end-to-end functionality.

Consider the following improvements:

  1. In TestHttpListAndDownloadReleaseAsset:

    • Use defer server.Stop() right after server.Run() to ensure the server is always stopped, even if the test fails.
    • Replace magic numbers and strings with constants or variables, e.g., expectedReleaseCount := 2 instead of hardcoding 2 in the condition.
    • Use assert.Equal for comparisons instead of if statements with t.Fatal.
  2. Add more specific test cases:

    • Test for various error conditions, such as network failures or invalid responses.
    • Test with different release configurations to ensure robust parsing.

Example refactoring for a section of TestHttpListAndDownloadReleaseAsset:

func TestHttpListAndDownloadReleaseAsset(t *testing.T) {
    server := NewHttpRepoTestServer()
    server.Run()
    defer server.Stop()

    source, err := NewHttpSource(HttpConfig{BaseURL: server.repoURL})
    require.NoError(t, err)

    releases, err := source.ListReleases(context.Background(), ParseSlug("creativeprojects/resticprofile"))
    require.NoError(t, err)

    expectedReleaseCount := 2
    assert.Len(t, releases, expectedReleaseCount, "Incorrect number of releases")

    assert.Equal(t, "v0.1.1", releases[0].GetTagName(), "Unexpected release tag name")

    // ... rest of the test ...
}
README.md (1)

384-389: LGTM! Consider adding a comma for better readability.

The new section "Http Based Repository" provides clear and concise information about the new feature. It effectively explains the purpose and requirements of the HttpSource.

Consider adding a comma after "project" in the following sentence for improved readability:

-If your repository is at https://example.com/repo/project then you'd use the following example.
+If your repository is at https://example.com/repo/project, then you'd use the following example.
🧰 Tools
🪛 Markdownlint

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 85a4d70 and 38ba702.

⛔ Files ignored due to path filters (1)
  • testdata/http_repo/v0.1.2/example_linux_amd64.tar.gz is excluded by !**/*.gz
📒 Files selected for processing (5)
  • README.md (2 hunks)
  • http_release.go (1 hunks)
  • http_source.go (1 hunks)
  • http_source_test.go (1 hunks)
  • testdata/http_repo/manifest.yaml (1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[typographical] ~392-~392: Consider adding a comma.
Context: ...y is at https://example.com/repo/project then you'd use the following example. ```go...

(IF_THEN_COMMA)

🪛 Markdownlint
README.md

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


390-390: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


390-390: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


392-392: null
Bare URL used

(MD034, no-bare-urls)

🪛 golangci-lint
http_source.go

131-131: undefined: yaml

(typecheck)

🔇 Additional comments (10)
testdata/http_repo/manifest.yaml (3)

1-2: LGTM: Global counters are accurate

The last_release_id and last_asset_id correctly reflect the number of releases and total assets in the manifest. This is crucial for maintaining data integrity and ensuring unique IDs for future additions.


3-24: Verify release date and consider adding release notes

The release structure for v0.1.1 is well-organized and includes all necessary information. However, there are two points to consider:

  1. The published_at date (2024-09-30) is in the future. While this might be intentional for testing purposes, it could cause issues in a production environment.
  2. The release_notes field is empty. Consider adding release notes to improve documentation and provide users with information about the release.

Please confirm if the future date is intentional and consider adding release notes.


25-45: Consistent structure, but verify release date and consider adding release notes

The release structure for v0.1.2 is consistent with v0.1.1, which is excellent for maintainability. However, the same concerns apply:

  1. The published_at date (2024-10-07) is in the future. Please confirm if this is intentional.
  2. The release_notes field is empty. Consider adding release notes to provide users with valuable information about the release.

Please confirm if the future dates for both releases are intentional and consider adding release notes to improve documentation.

http_source_test.go (2)

1-36: LGTM: File header and imports are well-structured.

The copyright notice, package declaration, and import statements are correctly formatted and include all necessary dependencies for the test file.


1-219: Overall, well-implemented test suite for HTTP-based update functionality.

The http_source_test.go file provides a comprehensive set of tests for the HTTP-based update functionality. It includes a custom test server implementation and covers various scenarios such as URL validation, context cancellation, and end-to-end functionality.

Main strengths:

  1. Good coverage of different aspects of the HTTP source functionality.
  2. Use of test server for controlled testing environment.
  3. Proper use of testing libraries for assertions.

Areas for improvement:

  1. Enhance error handling in some methods, particularly in the test server implementation.
  2. Increase the variety of test cases to cover more edge cases and error conditions.
  3. Improve code structure by extracting common setup code and using more constants for magic numbers and strings.
  4. Consistently use assert and require functions from the testify package for all verifications.

Overall, this is a solid foundation for testing the HTTP source functionality. Implementing the suggested improvements will further enhance the robustness and maintainability of the test suite.

http_release.go (4)

50-50: Good practice with interface implementation assertions

Including compile-time assertions like var _ SourceAsset = &HttpAsset{} and var _ SourceRelease = &HttpRelease{} ensures that your structs satisfy the required interfaces. This is a good practice to catch implementation issues at compile time.

Also applies to: 104-104


96-102: Efficient conversion in GetAssets method

The GetAssets method correctly converts the slice of *HttpAsset to a slice of SourceAsset interfaces. This is necessary because Go does not support direct type conversion between slices of different types. The implementation is appropriate and efficient.


34-49: Accessor methods are properly implemented

All accessor methods for both HttpAsset and HttpRelease structs are correctly implemented. They correctly return the respective fields, ensuring that the structs fulfill the SourceAsset and SourceRelease interfaces as expected.

Also applies to: 64-95


1-20: License inclusion is appropriate

Including the MIT License at the top of the file ensures that the code is properly licensed. This is important for legal clarity and for users who will interact with or distribute your code.

http_source.go (1)

33-37: Verify if HttpRelease struct is defined in the codebase.

The HttpManifest struct references HttpRelease, but it is not defined in the provided code. Ensure that HttpRelease is defined elsewhere in the codebase.

Run the following script to check if HttpRelease is defined:

✅ Verification successful

HttpRelease struct is defined in the codebase.

  • Defined in: http_release.go
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for the definition of 'HttpRelease' in the codebase.

# Test: Find all occurrences where 'HttpRelease' is defined.
# Expect: At least one match indicating 'type HttpRelease struct {...}'
rg --type go '^type HttpRelease struct' -A 5

Length of output: 383

README.md Outdated Show resolved Hide resolved
http_release.go Show resolved Hide resolved
http_release.go Outdated Show resolved Hide resolved
http_source.go Outdated Show resolved Hide resolved
http_source.go Outdated Show resolved Hide resolved
http_source.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
README.md (2)

384-389: LGTM: New section added with valuable information.

The new section provides clear information about the HTTP-based repository support. However, consider a minor grammatical improvement:

Consider revising this sentence for clarity:

-This is a simple way to add self update support to software that is not open source, allowing you to host your own updates.
+This provides a simple way to add self-update support to software that is not open-source, allowing you to host your own updates.
🧰 Tools
🪛 Markdownlint

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


392-392: Consider minor formatting improvements.

There are a couple of minor formatting issues that could be addressed:

  1. Consider adding a comma in the introductory sentence:

    -If your repository is at https://example.com/repo/project then you'd use the following example.
    +If your repository is at https://example.com/repo/project, then you'd use the following example.
  2. The bare URL in the text could be formatted as a proper Markdown link:

    -If your repository is at https://example.com/repo/project then you'd use the following example.
    +If your repository is at [https://example.com/repo/project](https://example.com/repo/project), then you'd use the following example.

Also applies to: 396-426

🧰 Tools
🪛 LanguageTool

[typographical] ~392-~392: Consider adding a comma.
Context: ...y is at https://example.com/repo/project then you'd use the following example. ```go...

(IF_THEN_COMMA)

🪛 Markdownlint

392-392: null
Bare URL used

(MD034, no-bare-urls)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 38ba702 and 401c00e.

📒 Files selected for processing (4)
  • README.md (2 hunks)
  • http_release.go (1 hunks)
  • http_source.go (1 hunks)
  • testdata/http_repo/manifest.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • http_source.go
  • testdata/http_repo/manifest.yaml
🧰 Additional context used
📓 Learnings (1)
http_release.go (2)
Learnt from: GRMrGecko
PR: creativeprojects/go-selfupdate#42
File: http_release.go:53-62
Timestamp: 2024-10-12T19:14:20.750Z
Learning: In the `go-selfupdate` project, field naming differences such as `ID` in `HttpAsset` and `ReleaseID` in `HttpRelease` are intentional and formatted by Go standards, and should be maintained as is.
Learnt from: GRMrGecko
PR: creativeprojects/go-selfupdate#42
File: http_release.go:27-32
Timestamp: 2024-10-12T19:09:25.833Z
Learning: In the Go struct `HttpAsset` in `http_release.go`, the `Size` field represents the file size and is appropriately declared as `int`.
🪛 LanguageTool
README.md

[typographical] ~392-~392: Consider adding a comma.
Context: ...y is at https://example.com/repo/project then you'd use the following example. ```go...

(IF_THEN_COMMA)

🪛 Markdownlint
README.md

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


390-390: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


390-390: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


392-392: null
Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (10)
http_release.go (8)

1-25: LGTM: License and package declaration

The license header, package declaration, and import statement are appropriate and well-structured.


27-32: LGTM: HttpAsset struct definition

The HttpAsset struct is well-defined with appropriate fields and YAML tags. The Size field as int is suitable for representing file sizes.


34-50: LGTM: HttpAsset methods and interface compliance

The getter methods for HttpAsset are correctly implemented, and the type assertion ensures that HttpAsset implements the SourceAsset interface.


52-62: LGTM: HttpRelease struct definition

The HttpRelease struct is well-defined with appropriate fields and YAML tags. The ID field name is consistent with other sources in the project.


64-86: LGTM: HttpRelease getter methods (part 1)

The getter methods for HttpRelease are correctly implemented, providing access to the struct's fields.


88-102: LGTM: HttpRelease getter methods (part 2) and GetAssets implementation

The getter methods for Name and URL are correctly implemented. The GetAssets method properly converts the slice of *HttpAsset to a slice of SourceAsset interfaces.


104-104: LGTM: HttpRelease interface compliance

The type assertion ensures that HttpRelease implements the SourceRelease interface, which is a good practice for compile-time interface compliance checking.


1-104: Overall: Well-implemented HTTP-based repository support

This file successfully implements the HttpAsset and HttpRelease structs along with their methods to support HTTP-based repositories. The code is well-structured, follows Go conventions, and ensures interface compliance. No significant issues or improvements were identified during the review.

README.md (2)

33-34: LGTM: Table of contents updated correctly.

The table of contents has been properly updated to include the new "Http Based Repository" section and its example subsection.


392-428: ⚠️ Potential issue

Fix configuration type in the example code.

The example effectively demonstrates how to use the HttpSource. However, there's an inconsistency that needs to be addressed:

Please apply the following change:

-	source, err := selfupdate.NewHttpSource(selfupdate.GitLabConfig{
+	source, err := selfupdate.NewHttpSource(selfupdate.HttpConfig{
		BaseURL: "https://example.com/",
	})

The example is using GitLabConfig instead of HttpConfig, which is inconsistent with the HttpSource being demonstrated.

🧰 Tools
🪛 LanguageTool

[typographical] ~392-~392: Consider adding a comma.
Context: ...y is at https://example.com/repo/project then you'd use the following example. ```go...

(IF_THEN_COMMA)

🪛 Markdownlint

396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


392-392: null
Bare URL used

(MD034, no-bare-urls)

Copy link

sonarcloud bot commented Oct 12, 2024

Copy link

codecov bot commented Oct 12, 2024

Codecov Report

Attention: Patch coverage is 78.64078% with 22 lines in your changes missing coverage. Please review.

Project coverage is 77.14%. Comparing base (85a4d70) to head (bff983b).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
http_source.go 70.27% 12 Missing and 10 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #42      +/-   ##
==========================================
+ Coverage   76.95%   77.14%   +0.18%     
==========================================
  Files          26       28       +2     
  Lines        1089     1194     +105     
==========================================
+ Hits          838      921      +83     
- Misses        211      223      +12     
- Partials       40       50      +10     
Flag Coverage Δ
unittests 77.14% <78.64%> (+0.18%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
http_source_test.go (4)

38-95: Consider using a dynamic port for better test isolation.

The HttpRepoTestServer implementation is well-structured and includes proper methods for starting and stopping the server. However, using a fixed port (httpRepoTestPort = 8831) might cause issues if the port is already in use on the system running the tests.

Consider using httptest.NewServer() or listening on ":0" to let the system assign an available port dynamically. This approach would improve test isolation and reduce the risk of port conflicts.


97-111: Enhance error checking in TestHttpClientInvalidURL.

Both test functions appropriately check URL validation in NewHttpSource. However, the error checking in TestHttpClientInvalidURL could be more specific.

Consider using assert.Error or require.Error instead of a manual nil check. This would provide more informative test output if the test fails. For example:

func TestHttpClientInvalidURL(t *testing.T) {
    _, err := NewHttpSource(HttpConfig{BaseURL: ":this is not a URL"})
    require.Error(t, err, "Invalid URL should raise an error")
}

This change would make the test more robust and easier to debug if it fails.


113-144: Use a consistent URL for HTTP source creation.

The context cancellation tests are well-structured and correctly verify the behavior of cancelled contexts. However, the URL used to create the HTTP source ("http://localhost") doesn't match the actual test server URL used in other tests.

Consider using a constant or a helper function to provide a consistent URL across all tests. This would ensure that all tests are using the same base URL and would make it easier to update if needed. For example:

const testBaseURL = "http://localhost:8831"

// In each test:
source, err := NewHttpSource(HttpConfig{BaseURL: testBaseURL})

This change would improve consistency across tests and make them more maintainable.


157-221: Enhance test assertions and consider a more secure hash algorithm.

This integration test comprehensively covers the main functionality of the HTTP source implementation. However, there are a few areas for improvement:

  1. Consider adding more detailed assertions on the release and asset properties. For example, verify the version numbers, release dates, or other metadata.

  2. The use of MD5 for verifying the downloaded asset is not ideal for security purposes. While it's acceptable for testing, consider using a more secure hash algorithm like SHA-256 for better practice.

  3. The error handling could be more consistent. Some errors use require.NoError, while others use t.Fatal. Consider using require.NoError consistently for better test output.

Example of enhanced assertions:

require.Len(t, releases, 2, "Expected 2 releases")
require.Equal(t, "v0.1.1", releases[0].GetTagName(), "Unexpected tag name for first release")
require.Equal(t, "example_linux_amd64.tar.gz", assets[1].GetName(), "Unexpected asset name")

Example of using SHA-256:

hash := sha256.Sum256(data)
expectedHash := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" // replace with actual expected hash
require.Equal(t, expectedHash, hex.EncodeToString(hash[:]), "Unexpected file hash")

These changes would make the test more robust and align it with better security practices.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 401c00e and bff983b.

📒 Files selected for processing (1)
  • http_source_test.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
http_source_test.go (3)

1-36: LGTM: Appropriate license and imports.

The file header includes a proper copyright notice and MIT license. The imports are relevant for HTTP testing, including standard libraries and third-party testing libraries (stretchr/testify).


146-155: LGTM: Proper error handling test for nil release.

This test function correctly verifies that DownloadReleaseAsset returns an ErrInvalidRelease error when called with a nil release. The use of assert.ErrorIs is appropriate for checking the specific error type. This test is valuable for ensuring proper error handling for invalid input.


1-221: Overall: Well-structured tests with room for minor improvements.

The test file provides good coverage of the HTTP source functionality, including error cases, context cancellation, and integration testing. The use of a custom HTTP server for testing is a strong point, allowing for controlled testing of HTTP interactions.

Suggestions for further improvement:

  1. Consider adding more edge case tests, such as testing with empty responses, malformed JSON, or network errors.
  2. Add more granular unit tests for individual functions of the HTTP source, if not covered in other files.
  3. Consider using table-driven tests for some of the simpler test cases to improve test maintainability.
  4. Ensure consistent error handling and assertion methods throughout the tests.

Overall, the test file is well-structured and provides good coverage. Implementing these suggestions would further enhance the robustness of the test suite.

@GRMrGecko
Copy link
Contributor Author

Hopefully last commit to cover your AI requests.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (7)
http_source_test.go (4)

38-62: LGTM: Well-structured test server setup.

The HttpRepoTestServer struct and NewHttpRepoTestServer function provide a clean and reusable way to set up the test HTTP server. The file server is correctly configured to serve test data from the "./testdata/http_repo" directory.

Consider adding error handling for the unlikely scenario where httptest.NewServer() fails:

 func NewHttpRepoTestServer() *HttpRepoTestServer {
 	s := new(HttpRepoTestServer)

 	// Setup handlers.
 	mux := http.NewServeMux()
 	fs := http.FileServer(http.Dir("./testdata/http_repo"))
 	mux.Handle("/repo/creativeprojects/resticprofile/", http.StripPrefix("/repo/creativeprojects/resticprofile", fs))

 	// Setup server config.
 	s.server = httptest.NewServer(mux)
+	// In real-world scenarios, it's good practice to handle potential errors,
+	// even if they're unlikely in a testing environment.
+	if s.server == nil {
+		panic("Failed to create test server")
+	}
 	s.repoURL = s.server.URL + "/repo/"
 	return s
 }

81-111: LGTM: Proper context cancellation testing.

Both TestHttpListReleasesContextCancelled and TestHttpDownloadReleaseAssetContextCancelled effectively test the behavior of cancelled contexts. The use of assert.ErrorIs is appropriate for checking specific errors, and the context setup and teardown are handled correctly.

For consistency, consider using require.NoError instead of assert.NoError when checking for errors in the setup phase:

 func TestHttpListReleasesContextCancelled(t *testing.T) {
 	// Make a valid HTTP source.
 	source, err := NewHttpSource(HttpConfig{BaseURL: httpTestBaseURL})
-	require.NoError(t, err)
+	require.NoError(t, err, "Failed to create HTTP source")

 	// ... rest of the function
 }

 func TestHttpDownloadReleaseAssetContextCancelled(t *testing.T) {
 	// Make a valid HTTP source.
 	source, err := NewHttpSource(HttpConfig{BaseURL: httpTestBaseURL})
-	require.NoError(t, err)
+	require.NoError(t, err, "Failed to create HTTP source")

 	// ... rest of the function
 }

125-187: LGTM: Comprehensive end-to-end test with room for improvement.

The TestHttpListAndDownloadReleaseAsset function effectively tests the complete flow of listing releases and downloading an asset. The test covers important aspects such as release count, content verification, and asset integrity checking.

Consider the following improvements:

  1. Use testify's assertion functions consistently throughout the test for better error messages and test flow.
  2. Add a defer statement to ensure the test server is always stopped, even if the test fails.
  3. Use require instead of assert for critical checks that should stop the test execution if they fail.

Here's a partial example of how you could refactor the function:

 func TestHttpListAndDownloadReleaseAsset(t *testing.T) {
 	// Create test HTTP server and start it.
 	server := NewHttpRepoTestServer()
+	defer server.Stop() // Ensure server is always stopped

 	// Make HTTP source with our test server.
 	source, err := NewHttpSource(HttpConfig{BaseURL: server.repoURL})
 	require.NoError(t, err)

 	// List releases
 	releases, err := source.ListReleases(context.Background(), ParseSlug("creativeprojects/resticprofile"))
 	require.NoError(t, err)

 	// Confirm the manifest parsed the correct number of releases.
-	if len(releases) != 2 {
-		t.Fatal("releases count is not valid")
-	}
+	assert.Len(t, releases, 2, "releases count is not valid")

 	// Confirm the manifest parsed by the first release is valid.
-	if releases[0].GetTagName() != "v0.1.1" {
-		t.Fatal("release is not as expected")
-	}
+	assert.Equal(t, "v0.1.1", releases[0].GetTagName(), "release is not as expected")

 	// Confirm the release assets are parsed correctly.
 	assets := releases[1].GetAssets()
-	if assets[1].GetName() != "example_linux_amd64.tar.gz" {
-		t.Fatal("the release asset is not valid")
-	}
+	assert.Equal(t, "example_linux_amd64.tar.gz", assets[1].GetName(), "the release asset is not valid")

 	// ... rest of the function

 	// Verify data.
 	hfun := md5.New()
 	hfun.Write(data)
 	sum := hfun.Sum(nil)
 	hash := hex.EncodeToString(sum)
-	if hash != "9cffcbe826ae684db1c8a08ff9216f34" {
-		t.Errorf("hash isn't valid for test file: %s", hash)
-	}
+	assert.Equal(t, "9cffcbe826ae684db1c8a08ff9216f34", hash, "hash isn't valid for test file")

-	// Stop as we're done.
-	server.Stop()
 }

These changes will make the test more robust and easier to maintain.


1-187: Overall: Well-structured and comprehensive test suite with minor improvement opportunities.

This test file provides a robust set of unit tests for the HTTP-based repository functionality. It covers various scenarios including error handling, context cancellation, and end-to-end flows. The test server setup is clean and reusable, which is a good practice.

To further improve the test suite:

  1. Consistently use testify's assertion functions (assert and require) throughout all tests for better error messages and test flow.
  2. Consider adding more edge cases, such as testing with empty releases, malformed JSON responses, or network timeouts.
  3. Implement a helper function for creating an HTTP source to reduce code duplication across tests.
  4. Add comments explaining the purpose of each test function for better maintainability.

Example of a helper function:

func newTestHttpSource(t *testing.T, baseURL string) Source {
	source, err := NewHttpSource(HttpConfig{BaseURL: baseURL})
	require.NoError(t, err, "Failed to create HTTP source")
	return source
}

These improvements will enhance the overall quality and maintainability of the test suite.

README.md (3)

384-385: Consider using setext-style heading for consistency

The new section heading uses an atx-style heading (with # symbols), which is inconsistent with the other main section headings in the document. Consider changing it to a setext-style heading for consistency:

-# Http Based Repository
+Http Based Repository
+=======================

This change will make the new section heading consistent with other main section headings in the document.

🧰 Tools
🪛 Markdownlint

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


395-428: Use spaces for indentation in the code example

The code example uses tabs for indentation, which is inconsistent with the rest of the document that uses spaces. Consider replacing tabs with spaces to maintain consistency throughout the README.

Here's an example of how to format the first few lines:

-func update() {
-	source, err := selfupdate.NewHttpSource(selfupdate.HttpConfig{
-		BaseURL: "https://example.com/",
-	})
-	if err != nil {
-		log.Fatal(err)
-	}
+func update() {
+    source, err := selfupdate.NewHttpSource(selfupdate.HttpConfig{
+        BaseURL: "https://example.com/",
+    })
+    if err != nil {
+        log.Fatal(err)
+    }

Please apply this change throughout the entire code example.

🧰 Tools
🪛 Markdownlint

396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


390-391: Adjust subheading format for consistency

The subheading "Example:" has two minor inconsistencies:

  1. It uses a colon, which is not present in other subheadings.
  2. It uses an atx-style heading (with # symbols), while other subheadings use setext-style.

Consider changing it to:

-## Example:
+Example
+-------

This change will make the subheading consistent with the formatting of other subheadings in the document.

🧰 Tools
🪛 Markdownlint

390-390: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


390-390: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bff983b and 6810ac9.

📒 Files selected for processing (2)
  • README.md (2 hunks)
  • http_source_test.go (1 hunks)
🧰 Additional context used
🪛 Markdownlint
README.md

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


390-390: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


390-390: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

🔇 Additional comments (3)
http_source_test.go (2)

1-34: LGTM: Appropriate file header and imports.

The file header includes the necessary copyright notice and license information. The imports are comprehensive and relevant for HTTP-based testing, including standard libraries and third-party assertion packages.


114-122: LGTM: Proper nil release handling test.

The TestHttpDownloadReleaseAssetWithNilRelease function effectively tests the behavior when attempting to download a release asset with a nil release. The use of assert.ErrorIs is appropriate for checking the specific ErrInvalidRelease error.

README.md (1)

384-429: LGTM! Approve changes with minor formatting suggestions

The new section on HTTP-based repository support is a valuable addition to the README. The content is clear, informative, and provides a good example of how to use the new feature.

I've suggested a few minor formatting changes to maintain consistency with the rest of the document:

  1. Use setext-style headings for the main section and subsection.
  2. Replace tabs with spaces in the code example.

These small adjustments will improve the overall consistency of the document. Great work on implementing this new feature and documenting it!

🧰 Tools
🪛 Markdownlint

384-384: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


390-390: Expected: setext; Actual: atx
Heading style

(MD003, heading-style)


396-396: Column: 1
Hard tabs

(MD010, no-hard-tabs)


397-397: Column: 1
Hard tabs

(MD010, no-hard-tabs)


398-398: Column: 1
Hard tabs

(MD010, no-hard-tabs)


399-399: Column: 1
Hard tabs

(MD010, no-hard-tabs)


400-400: Column: 1
Hard tabs

(MD010, no-hard-tabs)


401-401: Column: 1
Hard tabs

(MD010, no-hard-tabs)


402-402: Column: 1
Hard tabs

(MD010, no-hard-tabs)


403-403: Column: 1
Hard tabs

(MD010, no-hard-tabs)


404-404: Column: 1
Hard tabs

(MD010, no-hard-tabs)


405-405: Column: 1
Hard tabs

(MD010, no-hard-tabs)


406-406: Column: 1
Hard tabs

(MD010, no-hard-tabs)


407-407: Column: 1
Hard tabs

(MD010, no-hard-tabs)


408-408: Column: 1
Hard tabs

(MD010, no-hard-tabs)


409-409: Column: 1
Hard tabs

(MD010, no-hard-tabs)


410-410: Column: 1
Hard tabs

(MD010, no-hard-tabs)


411-411: Column: 1
Hard tabs

(MD010, no-hard-tabs)


412-412: Column: 1
Hard tabs

(MD010, no-hard-tabs)


413-413: Column: 1
Hard tabs

(MD010, no-hard-tabs)


414-414: Column: 1
Hard tabs

(MD010, no-hard-tabs)


415-415: Column: 1
Hard tabs

(MD010, no-hard-tabs)


416-416: Column: 1
Hard tabs

(MD010, no-hard-tabs)


417-417: Column: 1
Hard tabs

(MD010, no-hard-tabs)


419-419: Column: 1
Hard tabs

(MD010, no-hard-tabs)


420-420: Column: 1
Hard tabs

(MD010, no-hard-tabs)


421-421: Column: 1
Hard tabs

(MD010, no-hard-tabs)


422-422: Column: 1
Hard tabs

(MD010, no-hard-tabs)


423-423: Column: 1
Hard tabs

(MD010, no-hard-tabs)


424-424: Column: 1
Hard tabs

(MD010, no-hard-tabs)


425-425: Column: 1
Hard tabs

(MD010, no-hard-tabs)


426-426: Column: 1
Hard tabs

(MD010, no-hard-tabs)


390-390: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

http_source_test.go Outdated Show resolved Hide resolved
@creativeprojects
Copy link
Owner

Well, that makes a nice addition indeed 👍🏻

I'm merging it now, then I'm going to try a few things with it before releasing a new version 😉

Thank you very much 🙇🏻

@creativeprojects creativeprojects merged commit e15540b into creativeprojects:main Oct 14, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants