-
Notifications
You must be signed in to change notification settings - Fork 132
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
Implement auth and transfer commands #1298
base: master
Are you sure you want to change the base?
Conversation
Absolutely no problem, I assumed it would be this way. I'm happy to keep rebasing until it's time. |
I'm afraid it'll take me a few days to review though. This is quite large. |
Of course happy to have @thomashoneyman's review as well here if it doesn't take away time from other things 🙂 |
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 looks good to me! I don't know if I have enough fresh context on Spago to give an approval, but everything seems reasonable. Just a couple comments.
, commandParser "fetch" (Fetch <$> fetchArgsParser) "Downloads all of the project's dependencies" | ||
, commandParser "install" (Install <$> installArgsParser) "Compile the project's dependencies" | ||
, commandParser "uninstall" (Uninstall <$> uninstallArgsParser) "Remove dependencies from a package" | ||
[ commandParser "auth" (Auth <$> authArgsParser) "Authenticate as the owner of a package, to allow transfer and unpiblish operations" |
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.
[ commandParser "auth" (Auth <$> authArgsParser) "Authenticate as the owner of a package, to allow transfer and unpiblish operations" | |
[ commandParser "auth" (Auth <$> authArgsParser) "Authenticate as the owner of a package, to allow transfer and unpublish operations" |
Just _rest -> keyPath | ||
Nothing -> keyPath <> ".pub" | ||
|
||
newOwner <- FS.exists path >>= case _ of |
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.
When I first read this file I was wondering why this was necessarily a "new owner", until I saw that this function is specifically intended as a command for adding a new key. Could that be added as a module comment so someone coming into this file without a lot of context knows its purpose?
@@ -254,7 +254,7 @@ fetchPackagesToLocalCache packages = do | |||
case tarExists, tarIsGood, offline of | |||
true, true, _ -> pure unit -- Tar exists and is good, and we already unpacked it. Happy days! | |||
_, _, Offline -> die $ "Package " <> packageVersion <> " is not in the local cache, and Spago is running in offline mode - can't make progress." | |||
_, _, Online -> do | |||
_, _, _ -> do |
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 more love for exhaustive cases? 😆
Authentication and operations that use it are automated by Spago, through the `spago auth` command: if you'd like to | ||
be able to perform authenticated operations you need a SSH keypair, and run `spago auth` passing those keys in. | ||
This will populate the `package.publish.owners` field in the `spago.yaml` - commit that and publish a new version, | ||
and from that moment you'll be able to perform authenticated operations on this package. |
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.
Does this mean that I can "take over" somebody else's package by doing this before they get to 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.
Oh, this is dependent on me having the right to commit the public key to the repo?
The transfer procedure is automated by Spago commands, and goes as follows: | ||
* Add your (or the new owner's) SSH public key to the `spago.yaml` through `spago auth` if they are not there already (see previous section) | ||
* Transfer the repository to the new owner using the hosting platform's transfer mechanism (e.g. GitHub's transfer feature) | ||
* Depending whose key is present in the `owners` field, either you or the new owner will update the `publish.location` field in the `spago.yaml`, and call `spago registry transfer` to initiate the transfer. If all goes well you'll now be able to publish a new version from the new location. |
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.
* Depending whose key is present in the `owners` field, either you or the new owner will update the `publish.location` field in the `spago.yaml`, and call `spago registry transfer` to initiate the transfer. If all goes well you'll now be able to publish a new version from the new location. | |
* Depending on whose key is present in the `owners` field, either you or the new owner will update the `publish.location` field in the `spago.yaml`, and call `spago registry transfer` to initiate the transfer. If all goes well you'll now be able to publish a new version from the new location. |
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.
Looks fluffy!
{ doc, package, configPath } <- case workspace.selected, workspace.rootPackage of | ||
Just { doc, package, path: packagePath }, _ -> pure { doc, package, configPath: Path.concat [ packagePath, "spago.yaml" ] } | ||
Nothing, Just rootPackage -> pure { doc: workspace.doc, package: rootPackage, configPath: "spago.yaml" } | ||
Nothing, Nothing -> die "No package was selected. Please select a package with the -p 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.
I feel like this should be a reusable thing.
case Array.elem newOwner currentOwners of | ||
true -> logWarn "The selected key is already present in the config file." | ||
false -> do | ||
logInfo $ "Adding the selected key to the list of the owners: " <> path |
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.
logInfo $ "Adding the selected key to the list of the owners: " <> path | |
logInfo $ "Adding selected key to the list of the owners: " <> path |
Just { owners: maybeOwners } -> do | ||
let currentOwners = fromMaybe [] maybeOwners | ||
case Array.elem newOwner currentOwners of | ||
true -> logWarn "The selected key is already present in the config 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.
true -> logWarn "The selected key is already present in the config file." | |
true -> logWarn "Selected key is already present in the config file." |
, toDoc "Location:" | ||
, indent (toDoc $ "- " <> prettyPrintLocation location) | ||
, toDoc "Remotes:" | ||
, lines $ map (\r -> indent $ toDoc $ "- " <> r.name <> ": " <> r.url) locationResult.remotes |
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.
, lines $ map (\r -> indent $ toDoc $ "- " <> r.name <> ": " <> r.url) locationResult.remotes | |
, lines $ locationResult.remotes <#> \r -> indent $ toDoc $ "- " <> r.name <> ": " <> r.url |
@@ -0,0 +1,7 @@ | |||
import readlineSync from 'readline-sync'; | |||
|
|||
export function question(query) { |
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 this specifically uses hideEchoBack: true
, perhaps give it a less generic name? Like questionPassword
or something? Or, alternatively, take the hideEchoBack
parameter from up the stack?
[--pedantic-packages] [--pure] [--purs-args ARGS] | ||
[-p|--package PACKAGE] ([--verbose-stats] | | ||
[--censor-stats]) [--strict] | ||
Usage: index.dev.js build [--migrate] [--monochrome|--no-color] [--offline] [-q|--quiet] [-v|--verbose] [--backend-args ARGS] [--ensure-ranges] [--json-errors] [--output DIR] [--pedantic-packages] [--pure] [--purs-args ARGS] [-p|--package PACKAGE] ([--verbose-stats] | [--censor-stats]) [--strict] |
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.
What happened to the line wrapping?
@@ -14,6 +12,5 @@ Available options: | |||
-q,--quiet Suppress all spago logging | |||
-v,--verbose Enable additional debug logging, e.g. printing `purs` | |||
commands | |||
--json Format the output as JSON | |||
PACKAGE Package name | |||
--json Format the output as JSON PACKAGE Package name |
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.
And here.
We fix #1123 by adding the
auth
andregistry transfer
commands, to allow for authenticated interactions with the Registry. Theunpublish
command is still unimplemented, but it should be easy now that the rest of the scaffolding is in place.This PR includes a whole set of tests to verify that things do what they should, and docs to inform users how the authenticated flow looks like.
@fsoikin I intend to merge this before #1296 since I've been rebasing it for months already and I'd love to not have to do it once more 😄
(this fixes #1294 as well)