Cli-microsoft365: New command: rename SharePoint Framework project

Created on 8 Feb 2020  路  12Comments  路  Source: pnp/cli-microsoft365

Usage

spfx project rename [options]

Description

Renames SharePoint Framework project

Options

| Option | Description |
| ----------------------- | ----------------------------------------- |
| -n, --newName <newName> | New name for the project |
| --generateNewId | Generate a new solution id for the project |
| -o, --output [output] | Output type. json\|text. Default text |
| --verbose | Runs command with verbose logging |
| --debug | Runs command with debug logging |

Additional Information

Related issue #1327.

Command applies to following changes to the project:

  • yo-rc.json: update libraryName and libraryId
  • deploy-azure-storage.json: update container property
  • package-solution.json: update name, id and zippedPackage
  • package.json: update name
  • readme.md: update title
good first issue new feature work in progress

Most helpful comment

I like 鈥攇enerateNewId, so let鈥檚 go with that 馃槉

All 12 comments

Hi @waldekmastykarz can I take this up?

Hey @aakashbhardwaj619 thanks for helping out, it鈥檚 all yours 馃憤馃徎

Hi guys, I have a couple of queries regarding this:

  • Since we are just updating the solution name, does the solution id need to be updated as well in package-solution.json and .yo-rc.json?
  • Once the project name is updated in all the mentioned files, should the command just return a message saying something like 'Project renamed successfully'?

I was going with the below logic for this. Let me know if I'm missing something.

const filePaths: string[] = [
  path.join(this.projectRootPath, 'package.json'),
  path.join(this.projectRootPath, '.yo-rc.json'),
  path.join(this.projectRootPath, 'config/package-solution.json'),
  path.join(this.projectRootPath, 'config/deploy-azure-storage.json'),
  path.join(this.projectRootPath, 'README.md')
];

const replaceFileContent = (filePath: string) => {
  if (fs.existsSync(filePath)) {
    try {
      let existingContent = fs.readFileSync(filePath, 'utf-8');
      let updatedContent = existingContent.replace(new RegExp(projectName, 'g'), args.options.newName);
      fs.writeFileSync(filePath, updatedContent, 'utf-8');
    } catch { }
  }
}

filePaths.forEach((filePath) => {
  replaceFileContent(filePath);
});

cb('Project renamed successfully');

Since we are just updating the solution name, does the solution id need to be updated as well in package-solution.json and .yo-rc.json?

Yes, we should update libraryId in .yo-rc.json and id in package-solution.json.

Logic looks fine to me.

Maybe it would be useful to use a combination of the debug and verbose modes with the below console outputs for giving feedback to the user. Thoughts @waldekmastykarz @VelinGeorgiev ?

Debug - Renaming SharePoint Framework project to '<newname>'
Debug - Updated yo-rc.json
Debug - Updated deploy-azure-storage.json
Debug - Updated package-solution.json
Debug - Updated package.json
Debug - Updated readme.md
Verbose - DONE
SharePoint Framework project successfully renamed to '<newname>'

Let's not replace the ID by default but expose an option to do it. In some cases the rename could be cosmetic and changing the solution and package ID might be undesired.

Agreed with the log output proposed by @garrytrinder

Let's not replace the ID by default but expose an option to do it. In some cases the rename could be cosmetic and changing the solution and package ID might be undesired.

Great suggestion @waldekmastykarz 馃憦馃徎

@aakashbhardwaj619 I've updated the command spec to include the new option.

@garrytrinder should the command accept a new ID or rather generate one itself or perhaps it should do both? I wonder if you'd want to set the solution ID to a specific guid or just have the command generate a new one for you automatically to avoid version conflicts with the old package.

You make a good point @waldekmastykarz

We could change the --id to a switch instead and make it so that if used, the command will generate a new guid which we can output in the console similar to the file updates.

If --id is omitted, then only the files are updated.

One last suggestion 馃槉 Let's use something like --updateId or --generateNewId rather than just --id. Based on how we use --id in other commands, it would make me think it expects a value rather than being a switch.

I like 鈥攇enerateNewId, so let鈥檚 go with that 馃槉

Hi guys, I was working on the test cases for this and found something interesting.

I used a test project like the one present at src/o365/spfx/commands/project/project-externalize/test-projects/spfx-182-webpart-react with project name as "spfx". As per the above mentioned logic since I was replacing all occurrences of the project name with newName, it replaced "spfx" with newName in the JSON schema URL of
package-solution.json
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json"
and
deploy-azure-storage.json
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json"

As a workaround should I pick a different test project with another name or should the logic be updated to find and replace these entire substrings like below?

let updatedContent = existingContent.replace(`"container": "${projectName}"`, `"container": "${args.options.newName}"`);
and
let updatedContent = existingContent.replace(`"name": "${projectName}-client-side-solution"`, `"name": "${args.options.newName}-client-side-solution"`);

Using string replace is quite unreliable as you have noticed. I'd suggest that instead we consider deserializing file contents to an object first and the replace the values of the specific properties which should be more error-prone.

Was this page helpful?
0 / 5 - 0 ratings