Skip to content

Conversation

youshibin
Copy link
Contributor

@youshibin youshibin commented Jan 30, 2025

What does this PR do?

Exports the DockerCompose type in the compose packge.

BREAKING CHANGE: The DockerCompose interface, used for the LocalDockerCompose implementation (shelling out to the local binary), was renamed to DockerComposer to prevent a
naming collision when exporting DockerCompose type.

Why is it important?

Returning an un-exported type from a constructor function limits the flexibility and usability of the returned instance. Callers can use the exported methods, but cannot declare variables of that type, pass instances to other functions, or embed them in structs without exposing the constructor itself.

Related issues

@youshibin youshibin requested a review from a team as a code owner January 30, 2025 18:03
Copy link

netlify bot commented Jan 30, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit da1ab41
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/67d81a6ac0ae200008778bd7
😎 Deploy Preview https://deploy-preview-2953--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

Could you clarify why this doesn't work already, as a quick test seems to indicate it does?

func TestHelloWorld(t *testing.T) {
	compose, err := compose.NewDockerCompose("test")
	require.NoError(t, err)
	err = compose.Down(context.Background())
	require.NoError(t, err)
}

@youshibin
Copy link
Contributor Author

@stevenh Yep, you are absolutely right! The type doesn't need to be exported for the methods which are exported to be accessible outside of the package.

@stevenh
Copy link
Contributor

stevenh commented Jan 30, 2025

@stevenh Yep, you are absolutely right! The type doesn't need to be exported for the methods which are exported to be accessible outside of the package.

So we can close this and the associated issue?

@xbc5
Copy link

xbc5 commented Jan 31, 2025

I think the documentation should clarify or emphasise the necessity to use the ComposeStack interface -- it isn't initially obvious that these are related.

@youshibin youshibin changed the title chore: expose DockerCompose type in the compose package chore: return ComposeStack interface in dockerCompose constructor functions Jan 31, 2025
@youshibin
Copy link
Contributor Author

I think the documentation should clarify or emphasise the necessity to use the ComposeStack interface -- it isn't initially obvious that these are related.

@xbc5 I agree, it's a bit confusing, but I believe the reason for the different interface name (ComposeStack) is because the previous interface (DockerComposer) is being deprecated. So, seems like there was a naming conflict.

Where would you like to see documentation updated?

@xbc5
Copy link

xbc5 commented Jan 31, 2025

I think the documentation should clarify or emphasise the necessity to use the ComposeStack interface -- it isn't initially obvious that these are related.

@xbc5 I agree, it's a bit confusing, but I believe the reason for the different interface name (ComposeStack) is because the previous interface (DockerComposer) is being deprecated. So, seems like there was a naming conflict.

Where would you like to see documentation updated?

Inline, on the NewDockerCompose factory; but if it returns the interface then it's not really necessary. It's not my place to say what this function should or should not return, but if it returns a struct, it should mention the interface.

Also, this is the first place I looked to get acquainted with the factory: so perhaps there too? Again, not necessary if it returns the interface.

Thanks for doing this.

@stevenh
Copy link
Contributor

stevenh commented Jan 31, 2025

Sorry I think you miss-understood my comment in the issue, I meant we should update the reason for the fix of exporting the returned type to detail that returning an unexported type restricts it's use, as it means it cannot be stored in a type or passed as a variable to a function, for example neither of the following are possible

type MyType struct {
   Stack *dockerCompose
}

func MyFunc(stack *dockerCompose) {
....
}

You should always return types and accept interfaces. For info on why see this.

@youshibin youshibin changed the title chore: return ComposeStack interface in dockerCompose constructor functions chore: export DockerCompose type in compose package Feb 1, 2025
@youshibin
Copy link
Contributor Author

@stevenh appreciate the review and sharing your wisdom! Great reference you linked there with returning types and accepting interfaces!

I went back to the original implementation, which exports the DockerCompose type in the constructor functions. Due to the naming conflict with the (deprecated) interface, that had to be renamed.

There was a cleanup helper method which used to accept a *dockerCompose, but now accepts a ComposeStack interface.

I don't suppose adding an interface implementation check (or interface compliance assertion) would be useful here to drive home the fact that the DockerCompose type implements the ComposeStack interface?

var _ ComposeStack = (*DockerCompose)(nil)

Copy link
Contributor

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

One clarifying question.

Due to the breaking change the PR title also needs a ! adding to it and "BREAKING CHANGE" to the description see conventional commits.

@youshibin youshibin changed the title chore: export DockerCompose type in compose package chore!: export DockerCompose type in compose package Feb 5, 2025
@mdelapenya mdelapenya self-assigned this Mar 14, 2025
@mdelapenya mdelapenya added the breaking change Causing compatibility issues. label Mar 14, 2025
Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @jasonyunicorn for your work here 🙇

Waiting for a final +1 from @stevenh to merge this.

Copy link
Contributor

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

LGTM

@mdelapenya mdelapenya merged commit e3611ba into testcontainers:main Mar 17, 2025
16 checks passed
mdelapenya added a commit that referenced this pull request Mar 17, 2025
…er-28.0.1incompatible

* main:
  chore!: export DockerCompose type in compose package (#2953)
  chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 in /modules (#3033)
  chore(sonar): set main as default branch (#3038)
  fix(sonar): run on ubuntu and the lowest Go version (#3037)
  fix(ci): update core path in sonar build (#3036)
  fix: use empty dir for the core (#3035)
  fix: pass secret to the reusable workflow (#3034)
  chore(ci): use new GH action for SonarQube (#3007)
mdelapenya added a commit to mdelapenya/testcontainers-go that referenced this pull request Mar 17, 2025
* main:
  chore!: export DockerCompose type in compose package (testcontainers#2953)
  chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 in /modules (testcontainers#3033)
mdelapenya added a commit to mdelapenya/testcontainers-go that referenced this pull request Mar 17, 2025
* main:
  chore(deps)!: bump github.com/docker/docker from 27.1.1+incompatible to 28.0.1+incompatible (testcontainers#3017)
  chore!: export DockerCompose type in compose package (testcontainers#2953)
  chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 in /modules (testcontainers#3033)
  chore(sonar): set main as default branch (testcontainers#3038)
  fix(sonar): run on ubuntu and the lowest Go version (testcontainers#3037)
  fix(ci): update core path in sonar build (testcontainers#3036)
  fix: use empty dir for the core (testcontainers#3035)
  fix: pass secret to the reusable workflow (testcontainers#3034)
  chore(ci): use new GH action for SonarQube (testcontainers#3007)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Causing compatibility issues.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Export dockerCompose type so consumers can store it in a variable and call Down
4 participants