-
Notifications
You must be signed in to change notification settings - Fork 212
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
adding functionality to porter create in a specified directory #2778
adding functionality to porter create in a specified directory #2778
Conversation
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.
Some nits and a question/suggestion about the create command.
cmd/porter/bundle.go
Outdated
RunE: func(cmd *cobra.Command, args []string) error { | ||
return p.Create() | ||
bundleName := "mybundle" // Default value |
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.
Is this necessary? This command will error if bundle name is not passed which I believe is what we want.
porter create // will error out
porter create mybundle //will not fail
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.
bundleName := "mybundle" // Default value | |
var bundleName string |
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.
@troy0820 currently it will not throw any error. It instead will create a bundle with the default name "mybundle". But if we want to throw an error if the argument isn't passed, then sure, I will fix it.
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.
@schristoff @phillipgibson Do we want the behavior to error (error being a word used to describe not executing the command but show the usage) when the argument for the create bundle isn't given to make the user do this?
porter create [bundle]
Or do we want to create the bundle with the default mybundle
in the directory if the argument isn't given?
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.
But if we want to throw an error if the argument isn't passed, then sure, I will fix it.
@sbdtu5498
I'm not quite sure but I want to see what is the desired behavior that we want and asking the community. From the issue I believe we want to emulate the same behavior as the below clis.
helm create
requires 1 argument
cargo new
requires 1 argument
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.
@troy0820 sure thing! Once we get more reviews on how it should be handled, I will add the required changes.
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.
My bias is towards helm, and feeling that most users of our product are familiar with helm.
In that case, let's force the user to do the hard thing, and pick a name. Error if they don't pass in an argument, because making assumptions can cause issues down the line. :)
On second thought, this is user facing.
There could be users who have scripts that rely on Porter to do stuff in the current directory.
For now, if they don't pass in an argument, we do it in the current directory. If they pass in an argument, then we create the directory.
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.
Sure thing, this seems feasible.
pkg/porter/create.go
Outdated
// Create a directory with the given bundle name | ||
err := os.Mkdir(bundleName, os.ModePerm) | ||
if err != nil { | ||
return fmt.Errorf("failed to create directory for bundle: %w", err) |
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.
return fmt.Errorf("failed to create directory for bundle: %w", err) | |
return fmt.Errorf("failed to create directory for bundle %s: %w", bundleName, err) |
ddceee7
to
2d4c508
Compare
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.
Just a couple of comments and changes requested.
pkg/porter/create.go
Outdated
bundleName = "." | ||
} | ||
|
||
fmt.Fprintf(p.Out, "creating porter configuration for %s\n", bundleName) |
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.
If bundle name is an empty string this will say creating porter configuration for .
.
Could getting the cwd os.Getwd()
p.FileSystem.Getwd()
be a better way to do this?
Setting bundle name to os.Getwd()
p.FileSystem.Getwd()
can do two things:
- It can default to the current working directory and allow this to print what it needs to be.
- It will still work with what you have for the writing of the files to the filepath below.
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.
You can get the basePath with porter.FileSystem.Getwd()
and use that for the bundleName if it is blank.
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.
sure this one is done
pkg/porter/create.go
Outdated
|
||
err := p.CopyTemplate(p.Templates.GetManifest, config.Name) | ||
// Create a directory with the given bundle name | ||
err := os.MkdirAll(bundleName, os.ModePerm) |
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.
err := os.MkdirAll(bundleName, os.ModePerm) | |
err := os.MkdirAll(bundleName, pkg.FileModeDirectory) |
pkg/porter/create.go
Outdated
// Create a directory with the given bundle name | ||
err := os.MkdirAll(bundleName, os.ModePerm) | ||
if err != nil { | ||
return fmt.Errorf("failed to create directory for bundle: %w", err) |
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.
return fmt.Errorf("failed to create directory for bundle: %w", err) | |
return fmt.Errorf("failed to create directory for bundle %s: %w", bundleName, err) |
pkg/porter/create_test.go
Outdated
p := NewTestPorter(t) | ||
defer p.Close() | ||
|
||
err := p.Create("mybundle") |
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.
If we pass in mybundle/yourbundle/superbundle
will this work?
Helm has a thing where it will create the directory (base directory) if the others exists. So it os.Stat
's the previous directories before making a helm create
in the last (superbundle) "directory" assuming the last isn't a file.
We are creating the whole path regardless if it's a file at that path to include a directory of that and the bundle name will be mybundle/yourbundle/superbundle
.
We may need to Stat the filepath of the directories if they are passed like this to ensure we do not have a bundle name with slashes, etc.
Helm has an example of this in their create flow.
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.
Oh I am sorry I was a bit busy at the moment to answer. Let me get back on to this
If we pass in mybundle/yourbundle/superbundle will this work?
Yes this will work. But there's a catch. It would update the directory if it exists. Now I want to ask should we block the user from running porter create or porter create mybundle if any of the related files exist or should we stick with the behavior that it is in.
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.
Yes this will work.
I'm curious as what the name will be. Will it be mybundle/yourbundle/superbundle
But there's a catch. It would update the directory if it exists.
I don't think that's a problem. Helm does the same thing. If there exists a directory, it will overwrite what's in there if the target exists.
Now I want to ask should we block the user from running porter create or porter create mybundle if any of the related files exist or should we stick with the behavior that it is in.
The existing functionality will allow you to create a bundle in the current directory if anything exits there and overwrite what is laid down on disks as an overwritten file. This behavior should stay and expect that to be the case with the target directory (if new created, if old overwrite)
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.
I'm curious as what the name will be. Will it be mybundle/yourbundle/superbundle
it will be named superbundle. And will be inside youbundle folder which will be inside, superbundle. It would work exactly like how helm create works
The existing functionality will allow you to create a bundle in the current directory if anything exits there and overwrite what is laid down on disks as an overwritten file. This behavior should stay and expect that to be the case with the target directory (if new created, if old overwrite)
Sure I have made those small changes will push it in few moments. Let me know if anything else is required.
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.
@troy0820 now it is 100% similar to helm create. I have also written the test cases to prove the point and looked at them locally as well. Kindly take a look.
2d4c508
to
ee0ecf5
Compare
cmd/porter/bundle.go
Outdated
Short: "Create a bundle", | ||
Long: "Create a bundle. This generates a porter bundle in the current directory.", | ||
Long: "Create a bundle. This generates a porter bundle with the directory with the specified name or in the root directory if no name is provided.", |
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.
I would leave this as "current directory" or use "working directory" instead of "root directory"
Root directory can have a lot of different meanings depending on the users background, and in my interpretation that is not where I would want my bundle. :)
pkg/porter/create.go
Outdated
if bundleName == "" { | ||
bundleName = p.FileSystem.Getwd() // Use the current directory if no directory is passed |
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.
if bundleName == "" { | |
bundleName = p.FileSystem.Getwd() // Use the current directory if no directory is passed | |
// Use the current directory if no directory is passed | |
if bundleName == "" { | |
bundleName = p.FileSystem.Getwd() |
pkg/porter/create.go
Outdated
bundleName = p.FileSystem.Getwd() // Use the current directory if no directory is passed | ||
} | ||
|
||
fmt.Fprintf(p.Out, "creating porter configuration in %s\n", bundleName) |
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.
I feel like this should be moved to the end of the function, so if we succeed, this outputs
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.
Okay, will move it.
cmd/porter/bundle.go
Outdated
RunE: func(cmd *cobra.Command, args []string) error { | ||
return p.Create() | ||
bundleName := "" // Default value |
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.
bundleName := "" // Default value | |
// By default we create the bundle in the current directory | |
bundleName := "" |
Minor comment nit
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.
By the way it is hard to do suggestions for comments in github because it won't let me use tabs :( so it may look a little weird
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.
Yeah, but I got it anyways! would fix them up.
Hey @sbdtu5498 - just following up on this to see if you need any help! :) |
ee0ecf5
to
1b4918b
Compare
Extremely sorry for the delays @schristoff. This thing really got out of my mind. Thanks a lot for reminding me as well. Everything has been fixed. Take a look. |
02a9591
to
6b1f2b1
Compare
pkg/porter/create.go
Outdated
// It takes both the relative path and absolute path into consideration. | ||
// For example if we want to create a bundle named mybundle in an existing directory /home/user we can call porter create /home/user/mybundle or porter create mybundle in the /home/user directory. | ||
// If we are in a directory /home/user and we want to create mybundle in the directory /home/user/directory given the directory exists, | ||
// we can call porter create directory/mybundle from the /home/user directory or with any relative paths' combinations that one can come up with. |
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.
To clarify, when we do this I feel like we may have to split on the porter create scripts/bundles/porter
is the name going to be this as well?/
to os.Stat
the directory path if it doesn't/does exist but only use the last name from the /
when creating the bundle. Do we not have to walk the directory structure?
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.
No the name will be let say if you create /home/sbdtu5498/gentoo/nix/os. let say both gentoo and nix exist then it will work and will create bundle in the directory named os. If os doesn't exist, it will create a directory called os. But if nix doesn't exist, then it will throw error no such directory exist. This is the exact behavior that helm commands show. I tried to closely replicate it. Hope it makes sense. I will add few more descriptor comments.
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.
// Only condition to use porter create with absolute and relative paths is that all the directories in the path except the last one should strictly exist.
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.
I will add this line here. Now it will make sense.
pkg/porter/create.go
Outdated
if err != nil { | ||
return fmt.Errorf("failed to create directory for bundle: %w", err) | ||
} | ||
} else if err != nil { |
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.
nit: Because the err != nil
in both places, you can check for the err != nil
first and then checi to see if the os.IsNotExist(err)
pkg/porter/create_test.go
Outdated
|
||
func TestCreateInDirectory(t *testing.T) { | ||
// Create a temporary directory for testing | ||
tempDir, err := ioutil.TempDir("", "porter-test") |
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.
tempDir, err := ioutil.TempDir("", "porter-test") | |
tempDir, err := os.TempDir("", "porter-test") |
ioutil.TempDir is deprecated and will not pass the gate for staticcheck/go vet
pkg/porter/create_test.go
Outdated
|
||
func TestCreateInChildDirectoryWithExistingParentDirectory(t *testing.T) { | ||
// Create a temporary directory for testing | ||
tempDir, err := ioutil.TempDir("", "porter-test") |
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.
tempDir, err := ioutil.TempDir("", "porter-test") | |
tempDir, err := os.TempDir("", "porter-test") |
pkg/porter/create_test.go
Outdated
|
||
func TestCreateInChildDirectoryWithoutExistingParentDirectory(t *testing.T) { | ||
// Create a temporary directory for testing | ||
tempDir, err := ioutil.TempDir("", "porter-test") |
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.
tempDir, err := ioutil.TempDir("", "porter-test") | |
tempDir, err := os.TempDir("", "porter-test") |
pkg/porter/create_test.go
Outdated
@@ -1,25 +1,28 @@ | |||
package porter | |||
|
|||
import ( | |||
"io/ioutil" |
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.
"io/ioutil" |
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.
Just some nits but passing through the gates for static check we need to change the ioutil
import and use os.TempDir
This is looking good. Definitely appreciate your patience.
Also, a question about the bundlename to make sure we don't fail prematurely if we need to walk the directories before creating/not creating them.
No problem at all and sorry for some delays on my part as well.
Have answered it above.
Fixing it ASAP. |
Signed-off-by: Sanskar Bhushan <[email protected]>
6b1f2b1
to
c4d00bd
Compare
@troy0820 please take a look. I think there would be some merge conflicts. I will rebase the branch later if that's fine. |
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.
Last change needed but this is so close @sbdtu5498. Thank you for your contribution and appreciate your patience with us.
// If we are in a directory /home/user and we want to create mybundle in the directory /home/user/directory given the directory exists, | ||
// we can call porter create directory/mybundle from the /home/user directory or with any relative paths' combinations that one can come up with. | ||
// Only condition to use porter create with absolute and relative paths is that all the directories in the path except the last one should strictly exist. | ||
err = os.Mkdir(bundleName, os.ModePerm) |
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.
err = os.Mkdir(bundleName, os.ModePerm) | |
err = os.MkdirAll(bundleName, os.ModePerm) |
This will make sure that this creates bundles such as porter create mybundle/newestbundle
_, err := os.Stat(bundleName) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
// This code here attempts to create the directory in which bundle needs to be created, |
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.
This comment is HUGE. Can we shorten this some?
Oh @sbdtu5498 I am so sorry, I never saw that you updated this awhile back. Once those last comments of Troy's are merged I will look over and get this merged ASAP. |
Hi @sbdtu5498 , are you still working on this? |
What does this change
Appropriate feature has been added and locally tested as well.
What issue does it fix
Closes #2772
If there is not an existing issue, please make sure we have context on why this change is needed. See our Contributing Guide for examples of when an existing issue isn't necessary.
Checklist
Reviewer Checklist