@@ -7,11 +7,11 @@ import {
77 promptForCopilotInstructions ,
88 isCopilotInstalled ,
99 quickCreateNewVenv ,
10- removeCopilotInstructions ,
1110 replaceInFilesAndNames ,
12- replaceInFile ,
11+ manageCopilotInstructionsFile ,
12+ manageLaunchJsonFile ,
1313} from './creationHelpers' ;
14- import { EXTENSION_ROOT_DIR } from '../../common/constants' ;
14+ import { NEW_PROJECT_TEMPLATES_FOLDER } from '../../common/constants' ;
1515import { EnvironmentManagers } from '../../internal.api' ;
1616import { showInputBoxWithButtons } from '../../common/window.apis' ;
1717
@@ -23,13 +23,16 @@ export class NewPackageProject implements PythonProjectCreator {
2323
2424 constructor ( private readonly envManagers : EnvironmentManagers ) { }
2525
26- async create ( _options ?: PythonProjectCreatorOptions ) : Promise < PythonProject | undefined > {
27- // Prompt for package name (TODO: this doesn't make sense if the _options is already being passed in )
28- const packageName = await showInputBoxWithButtons ( {
29- prompt : 'What is the name of the package? (e.g. my_package)' ,
30- ignoreFocusOut : true ,
31- showBackButton : true ,
32- } ) ;
26+ async create ( options ?: PythonProjectCreatorOptions ) : Promise < PythonProject | undefined > {
27+ // Prompt for package name if not provided
28+ let packageName = options ?. name ;
29+ if ( ! packageName ) {
30+ packageName = await showInputBoxWithButtons ( {
31+ prompt : 'What is the name of the package? (e.g. my_package)' ,
32+ ignoreFocusOut : true ,
33+ showBackButton : true ,
34+ } ) ;
35+ }
3336 if ( ! packageName ) {
3437 return undefined ;
3538 }
@@ -55,102 +58,73 @@ export class NewPackageProject implements PythonProjectCreator {
5558 ) ;
5659
5760 // 1. Copy template folder
58- const templateFolder = path . join (
59- EXTENSION_ROOT_DIR ,
60- 'src' ,
61- 'features' ,
62- 'creators' ,
63- 'templates' ,
64- 'newPackageTemplate' ,
65- ) ;
66- if ( ! ( await fs . pathExists ( templateFolder ) ) ) {
67- window . showErrorMessage ( 'Template folder does not exist.' ) ;
61+ const newPackageTemplateFolder = path . join ( NEW_PROJECT_TEMPLATES_FOLDER , 'newPackageTemplate' ) ;
62+ if ( ! ( await fs . pathExists ( newPackageTemplateFolder ) ) ) {
63+ window . showErrorMessage ( 'Template folder does not exist, aborting creation.' ) ;
6864 return undefined ;
69- // might need another check or error handling here
7065 }
71- const workspaceFolders = workspace . workspaceFolders ;
72- if ( ! workspaceFolders || workspaceFolders . length === 0 ) {
73- window . showErrorMessage ( 'No workspace folder is open.' ) ;
74- return undefined ;
66+
67+ // Check if the destination folder is provided, otherwise use the first workspace folder
68+ let destRoot = options ?. uri ?. fsPath ;
69+ if ( ! destRoot ) {
70+ const workspaceFolders = workspace . workspaceFolders ;
71+ if ( ! workspaceFolders || workspaceFolders . length === 0 ) {
72+ window . showErrorMessage ( 'No workspace folder is open or provided, aborting creation.' ) ;
73+ return undefined ;
74+ }
75+ destRoot = workspaceFolders [ 0 ] . uri . fsPath ;
7576 }
76- const destRoot = workspaceFolders [ 0 ] . uri . fsPath ; // this doesn't seem right...
77+
7778 // Check if the destination folder already exists
78- const destFolder = path . join ( destRoot , `${ packageName } _project` ) ;
79- if ( await fs . pathExists ( destFolder ) ) {
80- window . showErrorMessage ( 'A project folder by that name already exists, aborting.' ) ;
79+ const projectDestinationFolder = path . join ( destRoot , `${ packageName } _project` ) ;
80+ if ( await fs . pathExists ( projectDestinationFolder ) ) {
81+ window . showErrorMessage (
82+ 'A project folder by that name already exists, aborting creation. Please retry with a unique package name given your workspace.' ,
83+ ) ;
8184 return undefined ;
8285 }
83- await fs . copy ( templateFolder , destFolder ) ;
84-
85- // custom instructions
86- const instructionsTextPath = path . join (
87- EXTENSION_ROOT_DIR ,
88- 'src' ,
89- 'features' ,
90- 'creators' ,
91- 'templates' ,
92- 'copilot-instructions-text' ,
93- 'package-copilot-instructions.md' ,
94- ) ;
95- const instructionsText = `\n \n` + ( await fs . readFile ( instructionsTextPath , 'utf-8' ) ) ;
96-
97- // check to see if .github folder exists
98- const githubFolderPath = path . join ( destRoot , '.github' ) ;
99- const customInstructionsPath = path . join ( githubFolderPath , 'copilot-instructions.md' ) ;
100- const ghFolder = await fs . pathExists ( githubFolderPath ) ;
101- if ( ghFolder ) {
102- const customInstructions = await fs . pathExists ( customInstructionsPath ) ;
103- if ( customInstructions ) {
104- // Append to the existing file
105- await fs . appendFile ( customInstructionsPath , instructionsText ) ;
106- } else {
107- // Create the file if it doesn't exist
108- await fs . writeFile ( customInstructionsPath , instructionsText ) ;
109- }
110- } else {
111- // Create the .github folder and the file
112- await fs . mkdir ( githubFolderPath ) ;
113- await fs . writeFile ( customInstructionsPath , instructionsText ) ;
114- }
86+ await fs . copy ( newPackageTemplateFolder , projectDestinationFolder ) ;
11587
116- // 2. Replace <package_name> in all files and file/folder names using helper
117- await replaceInFilesAndNames ( destFolder , 'package_name' , packageName ) ;
118-
119- // 3. Remove Copilot instructions folder if needed
120- if ( ! createCopilotInstructions ) {
121- await removeCopilotInstructions ( destFolder ) ;
122- }
88+ // 2. Replace 'package_name' in all files and file/folder names using a helper
89+ await replaceInFilesAndNames ( projectDestinationFolder , 'package_name' , packageName ) ;
12390
12491 // 4. Create virtual environment if requested
12592 if ( createVenv ) {
126- await quickCreateNewVenv ( this . envManagers , destFolder ) ;
93+ await quickCreateNewVenv ( this . envManagers , projectDestinationFolder ) ;
12794 }
12895
12996 // 5. Get the Python environment for the destination folder
130- // could be either the one created in step 4 or an existing one
131- const pythonEnvironment = await this . envManagers . getEnvironment ( Uri . parse ( destFolder ) ) ;
97+ // could be either the one created in an early step or an existing one
98+ const pythonEnvironment = await this . envManagers . getEnvironment ( Uri . parse ( projectDestinationFolder ) ) ;
13299
133- // 6. Replace <run_exec> and <activation_command> in README.md
134- // const readmeFilePath = path.join(destFolder, 'README.md');
135100 if ( ! pythonEnvironment ) {
136101 window . showErrorMessage ( 'Python environment not found.' ) ;
137102 return undefined ;
138103 }
139- const execInfo = pythonEnvironment . execInfo ;
140- if ( execInfo . run ) {
141- // const { executable, args = [] } = execInfo.run;
142- // const execRunStr = [executable, ...args].join(' ');
143- // TODO: check this as I don't think I need this anymore
144- await replaceInFile ( customInstructionsPath , '<package_name>' , packageName ) ;
104+
105+ // add custom github copilot instructions
106+ if ( createCopilotInstructions ) {
107+ const packageInstructionsPath = path . join (
108+ NEW_PROJECT_TEMPLATES_FOLDER ,
109+ 'copilot-instructions-text' ,
110+ 'package-copilot-instructions.md' ,
111+ ) ;
112+ await manageCopilotInstructionsFile ( destRoot , packageName , packageInstructionsPath ) ;
145113 }
146114
147- // TODO: insert copilot instructions text into the copilot instructions file
148- // TODO: insert configs into existing launch.json file
115+ // update launch.json file with config for the package
116+ const launchJsonConfig = {
117+ name : `Python Package: ${ packageName } ` ,
118+ type : 'debugpy' ,
119+ request : 'launch' ,
120+ module : packageName ,
121+ } ;
122+ await manageLaunchJsonFile ( destRoot , JSON . stringify ( launchJsonConfig ) ) ;
149123
150124 // Return a PythonProject OR Uri (if no venv was created)
151125 return {
152126 name : packageName ,
153- uri : Uri . file ( destFolder ) ,
127+ uri : Uri . file ( projectDestinationFolder ) ,
154128 } ;
155129 }
156130}
0 commit comments