-
Notifications
You must be signed in to change notification settings - Fork 15
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
Add support for http based repositories #42
Conversation
WalkthroughThis pull request introduces updates to the Changes
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 repositoriesThe 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:
- Consider adding a version field for the manifest itself to allow for future schema changes.
- 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 andHttpRepoTestServer
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:
- Allow the port to be configurable, perhaps as an optional parameter with a default value.
- 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
, andStart
methods ofHttpRepoTestServer
are well-implemented, providing proper control over the test server lifecycle.Consider the following improvements:
- In the
Stop
method, handle the error returned byShutdown
:func (s *HttpRepoTestServer) Stop() error { return s.server.Shutdown(context.Background()) }- In the
Start
method, use a more idiomatic error handling approach:if err != nil && err != http.ErrServerClosed { return fmt.Errorf("server error: %w", err) }- 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
andTestHttpClientValidURL
functions provide basic tests for URL validation in theNewHttpSource
function.Consider enhancing these tests:
- Use
assert
orrequire
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") }- 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
andTestHttpDownloadReleaseAssetContextCancelled
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
andTestHttpListAndDownloadReleaseAsset
functions provide good coverage for error handling and end-to-end functionality.Consider the following improvements:
In
TestHttpListAndDownloadReleaseAsset
:
- Use
defer server.Stop()
right afterserver.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 hardcoding2
in the condition.- Use
assert.Equal
for comparisons instead ofif
statements witht.Fatal
.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
⛔ 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 accurateThe
last_release_id
andlast_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 notesThe release structure for v0.1.1 is well-organized and includes all necessary information. However, there are two points to consider:
- 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.- 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 notesThe release structure for v0.1.2 is consistent with v0.1.1, which is excellent for maintainability. However, the same concerns apply:
- The
published_at
date (2024-10-07) is in the future. Please confirm if this is intentional.- 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:
- Good coverage of different aspects of the HTTP source functionality.
- Use of test server for controlled testing environment.
- Proper use of testing libraries for assertions.
Areas for improvement:
- Enhance error handling in some methods, particularly in the test server implementation.
- Increase the variety of test cases to cover more edge cases and error conditions.
- Improve code structure by extracting common setup code and using more constants for magic numbers and strings.
- Consistently use
assert
andrequire
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 assertionsIncluding compile-time assertions like
var _ SourceAsset = &HttpAsset{}
andvar _ 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 inGetAssets
methodThe
GetAssets
method correctly converts the slice of*HttpAsset
to a slice ofSourceAsset
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 implementedAll accessor methods for both
HttpAsset
andHttpRelease
structs are correctly implemented. They correctly return the respective fields, ensuring that the structs fulfill theSourceAsset
andSourceRelease
interfaces as expected.Also applies to: 64-95
1-20
: License inclusion is appropriateIncluding 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 ifHttpRelease
struct is defined in the codebase.The
HttpManifest
struct referencesHttpRelease
, but it is not defined in the provided code. Ensure thatHttpRelease
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 5Length of output: 383
There was a problem hiding this 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:
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.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
📒 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 declarationThe license header, package declaration, and import statement are appropriate and well-structured.
27-32
: LGTM: HttpAsset struct definitionThe
HttpAsset
struct is well-defined with appropriate fields and YAML tags. TheSize
field asint
is suitable for representing file sizes.
34-50
: LGTM: HttpAsset methods and interface complianceThe getter methods for
HttpAsset
are correctly implemented, and the type assertion ensures thatHttpAsset
implements theSourceAsset
interface.
52-62
: LGTM: HttpRelease struct definitionThe
HttpRelease
struct is well-defined with appropriate fields and YAML tags. TheID
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 implementationThe getter methods for
Name
andURL
are correctly implemented. TheGetAssets
method properly converts the slice of*HttpAsset
to a slice ofSourceAsset
interfaces.
104-104
: LGTM: HttpRelease interface complianceThe type assertion ensures that
HttpRelease
implements theSourceRelease
interface, which is a good practice for compile-time interface compliance checking.
1-104
: Overall: Well-implemented HTTP-based repository supportThis file successfully implements the
HttpAsset
andHttpRelease
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 issueFix 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 ofHttpConfig
, 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)
Quality Gate passedIssues Measures |
Codecov ReportAttention: Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this 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 inTestHttpClientInvalidURL
could be more specific.Consider using
assert.Error
orrequire.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:
Consider adding more detailed assertions on the release and asset properties. For example, verify the version numbers, release dates, or other metadata.
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.
The error handling could be more consistent. Some errors use
require.NoError
, while others uset.Fatal
. Consider usingrequire.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
📒 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 anErrInvalidRelease
error when called with a nil release. The use ofassert.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:
- Consider adding more edge case tests, such as testing with empty responses, malformed JSON, or network errors.
- Add more granular unit tests for individual functions of the HTTP source, if not covered in other files.
- Consider using table-driven tests for some of the simpler test cases to improve test maintainability.
- 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.
Hopefully last commit to cover your AI requests. |
There was a problem hiding this 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 andNewHttpRepoTestServer
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
andTestHttpDownloadReleaseAssetContextCancelled
effectively test the behavior of cancelled contexts. The use ofassert.ErrorIs
is appropriate for checking specific errors, and the context setup and teardown are handled correctly.For consistency, consider using
require.NoError
instead ofassert.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:
- Use testify's assertion functions consistently throughout the test for better error messages and test flow.
- Add a defer statement to ensure the test server is always stopped, even if the test fails.
- Use
require
instead ofassert
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:
- Consistently use testify's assertion functions (
assert
andrequire
) throughout all tests for better error messages and test flow.- Consider adding more edge cases, such as testing with empty releases, malformed JSON responses, or network timeouts.
- Implement a helper function for creating an HTTP source to reduce code duplication across tests.
- 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 consistencyThe 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 exampleThe 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 consistencyThe subheading "Example:" has two minor inconsistencies:
- It uses a colon, which is not present in other subheadings.
- 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
📒 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 ofassert.ErrorIs
is appropriate for checking the specificErrInvalidRelease
error.README.md (1)
384-429
: LGTM! Approve changes with minor formatting suggestionsThe 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:
- Use setext-style headings for the main section and subsection.
- 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)
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 🙇🏻 |
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
HttpSource
functionality and providing usage examples.Bug Fixes
Tests
Chores