cli-microsoft365
cli-microsoft365 copied to clipboard
Align command's options with our naming convention
We should review all commands and ensure that all options match our naming convention:
- if the option doesn't have a prefix (eg.
id,title), it refers to the last noun in the command name, eg.spo listitem get> last noun =listitemsoidandtitlerefer tolistitem - if the option needs to point to a property of a different object, it needs to be prefixed to make this clear, eg.
listId,listTitleinspo listitem list. Last noun islistitembut we need the user to specify ID of the list, rather than list item, so just prompting foridortitlewouldn't make it clear that we're expecting ID or title of the list
Commands that need adjustments:
- [x]
aad approleassignment add:objectIdanddisplayNameshould be prefixed withapp - [x]
aad approleassignment list:objectIdanddisplayNameshould be prefixed withapp - [x]
aad approleassignment remove:objectIdanddisplayNameshould be prefixed withapp - [x]
aad o365group add:isPrivateshould be a flag instead of a boolean option - [x]
aad o365group recyclebinitem list:displayNameandmailNicknameshould be prefixed withgroup - [x]
aad o365group teamify:groupIddoesn't need thegroupprefix and could be justid - [x]
aad policy list:policyTypedoesn't need thepolicyprefix and could be justtype - [x]
aad sp get:displayNameandobjectIdshould be prefixed withapp - [x]
flow run cancel:flowshould beflowNameto disambiguate how we expect users to denote the flow, same applies toenvironment, which should becomeenvironmentName - [x]
flow run get:flowshould beflowNameto disambiguate how we expect users to denote the flow, same applies toenvironment, which should becomeenvironmentName - [x]
flow run list:flowshould beflowNameto disambiguate how we expect users to denote the flow, same applies toenvironment, which should becomeenvironmentName - [x]
flow run resubmit:flowshould beflowNameto disambiguate how we expect users to denote the flow, same applies toenvironment, which should becomeenvironmentName - [x]
flow disable:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
flow enable:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
flow export:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
flow get:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
flow list:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
flow remove:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
outlook message move:messageIdshould beid - [x]
pa connector export:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
pa connector list:environmentshould beenvironmentNameto make it clear how we expect users to denote the environment - [x]
pa solution reference add:pathshould beprojectPath - [x]
spfx package generate:packageNameshould bename - [x]
spo app add:scopeshould beappCatalogScope - [x]
spo app deploy:scopeshould beappCatalogScope - [x]
spo app get:scopeshould beappCatalogScope - [x]
spo app install:scopeshould beappCatalogScope - [x]
spo app list:scopeshould beappCatalogScope - [x]
spo app remove:scopeshould beappCatalogScope - [x]
spo app retract:scopeshould beappCatalogScope - [x]
spo app uninstall:scopeshould beappCatalogScope - [x]
spo app upgrade:scopeshould beappCatalogScope - [x]
spo apppage set:pageNameshould bename - [x]
spo cdn policy list:typeshould becdnType - [x]
spo cdn policy set:typeshould becdnType - [x]
spo contenttype field set:fieldIdshould beid - [x]
spo customaction add:urlshould bewebUrl - [x]
spo customaction clear:urlshould bewebUrl - [x]
spo customaction get:urlshould bewebUrl - [x]
spo customaction list:urlshould bewebUrl - [x]
spo customaction remove:urlshould bewebUrl - [x]
spo customaction set:urlshould bewebUrl - [ ]
spo feature disable:urlshould bewebUrl,featureIdshould beid - [ ]
spo feature enable:urlshould bewebUrl,featureIdshould beid - [ ]
spo feature list:urlshould bewebUrl - [ ]
spo field get:fieldTitleshould betitle - [ ]
spo field remove:fieldTitleshould betitle - [ ]
spo file checkin:fileUrlshould beurl - [ ]
spo file checkout:fileUrlshould beurl - [ ]
spo file sharinginfo get:urlshould befileUrl - [ ]
spo folder get:folderUrlshould beurl - [ ]
spo folder remove:folderUrlshould beurl - [ ]
spo folder rename:folderUrlshould beurl - [ ]
spo hubsite connect:urlshould besiteUrl - [ ]
spo hubsite disconnect:urlshould besiteUrl - [ ]
spo hubsite register:urlshould besiteUrl - [ ]
spo hubsite rights grant:urlshould behubSiteUrl - [ ]
spo hubsite rights revoke:urlshould behubSiteUrl - [ ]
spo knowledgehub set:urlshould besiteUrl - [ ]
spo list contenttype add:contentTypeIdshould beid - [ ]
spo list contenttype remove:contentTypeIdshould beid - [ ]
spo list view field add:fieldIdshould beid,fieldTitleshould betitle,fieldPositionshould beposition - [ ]
spo list view field remove:fieldIdshould beid,fieldTitleshould betitle - [ ]
spo list view field set:fieldIdshould beid,fieldTitleshould betitle,fieldPositionshould beposition - [ ]
spo list view get:viewIdshould beid,viewTitleshould betitle - [ ]
spo list view remove:viewIdshould beid,viewTitleshould betitle - [ ]
spo list view set:viewIdshould beid,viewTitleshould betitle - [ ]
spo listitem list:idshould belistId,titleshould belistTitle - [ ]
spo listitem record declare:idshould belistItemId - [ ]
spo listitem record undeclare:idshould belistItemId - [ ]
spo page column get:nameshould bepageName - [ ]
spo page column list:nameshould bepageName - [ ]
spo page control get:nameshould bepageName - [ ]
spo page control list:nameshould bepageName - [ ]
spo page control set:nameshould bepageName - [ ]
spo page section add:nameshould bepageName - [ ]
spo page section get:nameshould bepageName - [ ]
spo page section list:nameshould bepageName - [ ]
spo sp grant revoke:grantIdshould beid - [ ]
spo sp permissionrequest approve:requestIdshould beid - [ ]
spo sp permissionrequest deny:requestIdshould beid - [ ]
spo site appcatalog add:urlshould besiteUrl - [ ]
spo site appcatalog remove:urlshould besiteUrl - [ ]
spo site apppermission get:permissionIdshould beid - [ ]
spo site apppermission remove:permissionIdshould beid - [ ]
spo site apppermission set:permissionIdshould beid - [ ]
spo site chrome set:urlshould besiteUrl - [ ]
spo site groupify:siteUrlshould beurl - [ ]
spo site rename:siteUrlshould beurl - [ ]
spo sitedesign rights grant:idshould besiteDesignId - [ ]
spo sitedesign rights list:idshould besiteDesignId - [ ]
spo sitedesign rights revoke:idshould besiteDesignId - [ ]
spo sitedesign task get:taskIdshould beid - [ ]
spo sitedesign task remove:taskIdshould beid - [ ]
spo tenant recyclebinitem remove:urlshould besiteUrl - [ ]
spo tenant recyclebinitem restore:urlshould besiteUrl - [ ]
spo web add:webUrlshould beurl - [ ]
spo web get:webUrlshould beurl - [ ]
spo web list:webUrlshould beurl - [ ]
spo web reindex:webUrlshould beurl - [ ]
spo web remove:webUrlshould beurl - [ ]
spo web set:webUrlshould beurl - [ ]
teams app install:appIdshould beid - [ ]
teams app uninstall:appIdshould beid - [ ]
teams channel get:channelIdshould beid,channelNameshould bename - [ ]
teams channel remove:channelIdshould beid,channelNameshould bename - [ ]
teams channel set:channelNameshould bename - [ ]
teams message get:messageIdshould beid - [ ]
teams tab get:tabIdshould beid,tabNameshould bename - [ ]
teams tab remove:tabIdshould beid - [ ]
teams team archive:teamIdshould beid - [ ]
teams team clone:teamIdshould beid - [ ]
teams team remove:teamIdshould beid - [ ]
teams team set:teamIdshould beid - [ ]
teams team unarchive:teamIdshould beid - [ ]
teams user app add:appIdshould beid - [ ]
teams user app remove:appIdshould beid - [ ]
viva connections app create:appNameshould bename - [ ]
yammer group user add:idshould begroupId,userIdshould beid - [ ]
yammer group user remove:idshould begroupId,userIdshould beid - [ ]
yammer message like set:idshould bemessageId - [ ]
yammer user get:userIdshould beid
In some commands we use filePath and userName as options. While we could shorten them to path and name I wonder if in these cases we should treat the options as a single word. What do you think @pnp/cli-for-microsoft-365-maintainers?
name is too generic, so I think we should stick with userName and I'm happy with sticking with filePath I don't think we would gain any value from changing that.
nameis too generic, so I think we should stick withuserNameand I'm happy with sticking withfilePathI don't think we would gain any value from changing that.
Agree with @garrytrinder. We should stick with this naming
Across different commands, we also have an inconsistency with the short option name for URL:
- sometimes we use
-ufor--url,--webUrlor--siteUrl - some commands use
-wfor--webUrl, where-uis used for--url - some commands use
-sfor--siteUrl, where-uis used for--url
How could we rationalize the use of the -u short so that it makes sense across all commands?`
I would use url only for all commands
Another thing that we should consider and which led to some inconsistencies: in some commands where we have multiple URLs, we chose to explicitly prefix each URL option to disambiguate them, eg:
spo folder get --webUrl --folderUrl. If we were to follow our naming convention, we'd use spo folder get --webUrl --url, because the last URL refers to a folder which is the last noun in the command. The question is though, which one is clearer and in cases where we have multiple sorts of options (names, IDs, titles, URLs) we should choose clarity over consistency?
@plamber:
I would use url only for all commands
That wouldn't be always possible though:
spo folder getrequireswebUrlandfolderUrlspo group get, using just URL would indicate that it's the group URL rather than web URL (webUrl)
So what would be your suggestion?
Add the noun of the object in front of all url commands?
GroupUrl SiteUrl Etc?
So what would be your suggestion? Add the noun of the object in front of all url commands?
@plamber I guess that's the question
- do we always prefix, even when it's clear what the option is for, eg.
spo web get --webUrlinstead ofspo web get --url - do we prefix only when an option is ambiguous, eg.
spo folder get --webUrl --folderUrlinstead ofspo folder get --webUrl --urlbecause it's not clear what--urlis referring to - do we stick to consistency and naming convention and if the option isn't prefixed, it's implicit that it refers to the last noun
I would go for the last option
@pnp/cli-for-microsoft-365-maintainers what do you think?
Across different commands, we also have an inconsistency with the short option name for URL:
- sometimes we use
-ufor--url,--webUrlor--siteUrl- some commands use
-wfor--webUrl, where-uis used for--url- some commands use
-sfor--siteUrl, where-uis used for--urlHow could we rationalize the use of the
-ushort so that it makes sense across all commands?`
@plamber, what about this?
I would always go withe the first or first two letters of the words.
E.g. siteUrl - su or s
We can only use one letter for a short because -su actually means -s -u.
@pnp/cli-for-microsoft-365-maintainers other opinions?
I would always go withe the first or first two letters of the words.
E.g. siteUrl - su or s
What if we have --listId and --listTitle? Current we solve it by exposing respectively -i and -t. In such cases, -l would be ambiguous because the user wouldn't know if it's list ID or Title. We have this issue in some list(item) commands where we use -l for --listId and -t for --listTitle which isn't obvious or consistent.
I reviewed all commands and put all inconsistencies in the list.
To recap, here are the things we need to decide:
- Do we want to disambiguate similar options (eg. web URL vs. list URL vs. folder URL). Available options:
- we always prefix options, even when it's clear what the option is for, eg.
spo web get --webUrlinstead ofspo web get --url - we prefix only when an option is ambiguous, eg.
spo folder get --webUrl --folderUrlinstead ofspo folder get --webUrl --urlbecause it's not clear what--urlis referring to - we stick to consistency and naming convention and if the option isn't prefixed, it's implicit that it refers to the last noun
- we always prefix options, even when it's clear what the option is for, eg.
- Do we want to normalize the use of shorts across commands? Eg. in the different commands we use
-u,-wand-sfor URL. Extra consideration, what if we have multiple URL options in the command (webUrl,listUrl,folderUrl):- We use
-uonly for web/site - We don't use shorts at all
- We use
For 1. @plamber gave his preference to be iii (follow naming convention). What do you think @pnp/cli-for-microsoft-365-maintainers. What about 2.?
For 1 I agree with consensus so far to use the iii option. For 2 I would pick i
However I also want to sleep on it a night cause it feels complex, when writing scripts consistency is key, or at least for me.
I reviewed all commands and put all inconsistencies in the list.
To recap, here are the things we need to decide:
- Do we want to disambiguate similar options (eg. web URL vs. list URL vs. folder URL). Available options:
- we always prefix options, even when it's clear what the option is for, eg.
spo web get --webUrlinstead ofspo web get --url- we prefix only when an option is ambiguous, eg.
spo folder get --webUrl --folderUrlinstead ofspo folder get --webUrl --urlbecause it's not clear what--urlis referring to- we stick to consistency and naming convention and if the option isn't prefixed, it's implicit that it refers to the last noun
- Do we want to normalize the use of shorts across commands? Eg. in the different commands we use
-u,-wand-sfor URL. Extra consideration, what if we have multiple URL options in the command (webUrl,listUrl,folderUrl):
- We use
-uonly for web/site- We don't use shorts at all
For 1. @plamber gave his preference to be iii (follow naming convention). What do you think @pnp/cli-for-microsoft-365-maintainers. What about 2.?
For 2 I would go with 1
To add my thoughts...
I'm not a big fan of using shorts in my scripts, one of the big things I like about CLIs is that each command is descriptive and easy to read, however when using shorts they can introduce ambiguity as to which option is being used, i.e. I am more likely to have to consult the docs to understand what the short relates to. In the majority of cases, we don't use short options in our examples in the docs and prefer the use of the more descriptive long option.
Where there is a potential conflict I think that we should avoid using a short options, if we take the following examples, m365 teams channel get --teamId 00000000-0000-0000-0000-000000000000 --channelId '19:[email protected]' could be rewritten as m365 teams channel get --i 00000000-0000-0000-0000-000000000000 --c '19:[email protected]' to use the available short options, in contrast to m365 teams channel get --teamName "Team Name" --channelName "Channel Name" which uses the name based long options which do not have available shorts.
As a rule I think we should always be explicit in our naming convention, i.e. webUrl, listUrl, folderUrl, teamName, channelName.
This may introduce some duplication between the command name and the command options, however I would say that clarity always wins.
Thanks for sharing your thoughts @garrytrinder. With prefixing options, would you prefix them always, even though it's clear what the option is for, eg. spo web get --webUrl vs. spo web get --url or would you prefix it only where there are multiple URLs, IDs, and we want to disambiguate?
Thanks for sharing your thoughts @garrytrinder. With prefixing options, would you prefix them always, even though it's clear what the option is for, eg.
spo web get --webUrlvs.spo web get --urlor would you prefix it only where there are multiple URLs, IDs, and we want to disambiguate?
I would always prefix, it might seem overkill for a simple example like you have given, but it provides clarity for more complex examples where you have multiple options that are similar.
Understood @garrytrinder. @rabwill, @arjunumenon, @VelinGeorgiev care to share your opinion?
Prefix all the way. Agree with @garrytrinder . Thanks for putting this up as a list @waldekmastykarz 👏🏽
Been crazy weeks and that's why had been away from all CLI fun.
Do we want to disambiguate similar options (eg. web URL vs. list URL vs. folder URL). Available options:
I am with what @garrytrinder suggested (Option 1), giving full name for the parameter.
we always prefix options, even when it's clear what the option is for, eg. spo web get --webUrl instead of spo web get --url
Though the con with the approach is that, parameter name would be too big. I would personally be ok with that since our parameters are very clear for usage and the users need not refer the documentation for commands which has multiple id's.
For short params, my vote would be for this,
We use -u only for web/site
Never been a fan of short params myself. So cannot command which would be beneficial.
@waldekmastykarz - You have done heavy fork-lifting by identifying the commands. Awesome ❤
With having prefixes and renames, old ones will still be working as aliases maybe? in case someone is using it heavily?
@ValerasNarbutas the idea is to introduce these breaking changes in a major version so that we don't need to carry the existing option names forward. Having them available side-by-side would significantly complicate both the codebase and the documentation.
Since the discussion isn't complete and we consider changing our naming convention, we decided to postpone these changes to the next major version.
To better understand the impact of prefixing all options with the command noun, let's have a look at some of the examples from our docs:
m365 spo web add --webTitle Subsite --webDescription Subsite --webUrl subsite --webTemplate STS#0 --parentWebUrl https://contoso.sharepoint.com --webLocale 1033
m365 spo site add --siteType ClassicSite --siteUrl https://contoso.sharepoint.com/sites/team --siteTitle Team --siteOwners [email protected] --siteTimeZone 4 --webTemplate STS#0 --removeDeletedSite --wait
m365 spo serviceprincipal permissionrequest approve --permissionRequestId 4dc4c043-25ee-40f2-81d3-b3bf63da7538
m365 aad groupsettingtemplate get --groupSettingTemplateId 62375ab9-6b52-47ed-826b-58e47e0e304b
m365 aad app get --appObjectId d75be2e1-0204-4f95-857d-51a37cf40be8
m365 search externalconnection add --externalConnectionId MyApp --externalConnectionName "My application" --externalConnectionDescription "Description of your application"
Looking at these examples I'm seeing two things:
- examples and help would be harder to read because all (or at least most) options start with the same prefix. This makes it harder to scan the help to find the option you're looking for in help
- there is a lot of repetition making the commands very verbose. Especially if you're not using command completion in your shell, that's a lot of extra typing
Does prefixing all options add clarity? Absolutely! But for the few cases where we need to disambiguate some options, I wonder if it makes to extend all options in all commands to be prefixed with the command noun. Looking at the examples above, my preference would be to:
- keep the current naming convention
- align where we identified misalignment
- clarify where we see ambiguity
What do you think @pnp/cli-for-microsoft-365-maintainers?
I'm happy with the proposal 👍🏻
Great work @waldekmastykarz to provide the detail and clarity 👏
Thank you @garrytrinder for bringing up other ideas and constructive discussion on the possible directions 👏