-
Notifications
You must be signed in to change notification settings - Fork 13
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
Improve login command ux #859
base: master
Are you sure you want to change the base?
Conversation
131dfc4
to
b02576e
Compare
b02576e
to
7dabc73
Compare
39198ea
to
d439086
Compare
0f23dae
to
0f8ffce
Compare
0f8ffce
to
d6af96e
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.
Add comments & questions
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.
Did a quick pass. Structurally things are looking very good.
I'd like to dig in a bit into DatasetRefRemote
and TransferDatasetRef
types and see if they can be simplified. Left some ideas.
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct RemoteAliasRef { |
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.
The name of the struct doesn't make sense to me. This service uses aliases and an optional --to
target hint to figure out a unambiguous remote target for a push - so it's not an alias or reference any more.
Should we call it RemoteTarget
?
async fn resolve_remote_alias( | ||
&self, | ||
local_dataset_handle: &DatasetHandle, | ||
dataset_push_target_maybe: Option<DatasetPushTarget>, | ||
remote_alias_kind: RemoteAliasKind, | ||
) -> Result<RemoteAliasRef, ResolveAliasError>; |
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 thought that your intent here is to have one generic function that resolves both push and pull targets (thus the RemoteAliasKind
parameter to tell which one is it), but DatasetPushTarget
kinda ruins that.
Should we call this function resolve_push_target
and get rid of remote_alias_kind
parameter?
Later we may add resolve_pull_target
, but implementation of this service will be free to generalize the logic under the hood if it wants - I think it's more important to keep the interface clear.
if self.skip_add_repo { | ||
return Ok(()); | ||
} |
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.
Such checks are better done at the place of the function call. Seeing add_repository
call below I was immediately surprised that the call is unconditional and thought it's a bug.
#[serde(rename_all = "camelCase")] | ||
pub struct DatasetInfoResponse { | ||
pub id: DatasetID, | ||
pub account_name: Option<AccountName>, |
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.
Let's add account_id
too. Name is good for visualization, but navigating from dataset to an account should be done by IDs that are resistant to renaming.
return Err(ResolveAliasError::EmptyRepositoryList); | ||
} | ||
} | ||
let remote_repo = self.remote_repo_reg.get_repository(&repo_name).int_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.
If dataset_push_target_maybe == Some(Repository("blah"))
and "blah" repository does not exist will we get an internal error here instead of RepositoryNotFound
?
let repo_name: odf::RepoName; | ||
let mut account_name = None; | ||
let mut dataset_name = None; |
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.
Might be better to rewrite this as:
let (repo_name, account_name, dataset_name) = if ... { .. } else { ... };
This way you get certainty that all branches of logic consider all three of these values and not simply forget to assign one of them.
let transfer_dataset_name = dataset_name.clone().unwrap_or( | ||
self.resolve_remote_dataset_name( | ||
local_dataset_handle, | ||
&remote_repo.url, | ||
access_token_maybe.as_ref(), | ||
) | ||
.await?, | ||
); |
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.
Isn't resolve_remote_dataset_name
an expensive function? Written like this we will always be calling it even if dataset_name
was not None
.
.send() | ||
.await | ||
.int_err()? | ||
.error_for_status() |
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.
Have you tested this with plain storage repos like S3
or local FS? I don't see any logic that would differentiate those from ODF repos.
Even if a repo has HTTP(S) scheme it's not a fact that it's an ODF node. So we likely need some fallback logic for cases when /info
is not present.
// Return account name if remote workspace is in multi tenant mode | ||
pub async fn resolve_remote_account_name( | ||
server_backend_url: &Url, | ||
access_token_maybe: Option<&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.
Since you have extracted this helper as a type - you could pass token as constructor argument, not to have to pass it through every function's arguments.
## [Unreleased] | ||
### Changed | ||
- `kamu push <dataset>` command now can be called without `--to` reference and Alias or Remote dataset repository will be used as destination | ||
- `kamu login` command now will store repository to Repository registry. Name can be provided with `--repo-name` flag and to skip creating repo can be used `--skip-add-repo` flag |
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.
We also need to check if our instructions on pulling/pushing datasets in the Jupyter demo notebooks need to be updated or can be simplified.
Description
Closes: #450
Checklist before requesting a review