Skip to content

Commit

Permalink
ask questions if arguments are not passed in the command
Browse files Browse the repository at this point in the history
  • Loading branch information
sharjeelyunus committed Oct 7, 2024
1 parent 74efb17 commit 328e416
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ pubspec_overrides.yaml
/starter/ios/Flutter
starter/ios/Runner.xcodeproj/project.pbxproj
/node_modules
starter/node_modules
starter/package-lock.json
104 changes: 87 additions & 17 deletions starter/dart_runner.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
const { exec } = require('child_process');
const readline = require('readline');

// Common parameters available across scripts and modules
const commonParameters = ['platform'];
const commonParameters = [
{ key: 'platform', question: 'Which platform are you targeting? (e.g., ios, android, web): ', required: true }
];

// Modules (called with `enable` command)
const modules = [
{
name: 'camera',
path: 'scripts/modules/enable_camera.dart',
parameters: ['camera_description']
parameters: [
{ key: 'camera_description', question: 'Please provide a camera usage description for iOS: ', required: true, condition: (args) => args.platform === 'ios' }
]
},
{
name: 'files',
path: 'scripts/modules/enable_files.dart',
parameters: ['photo_library_description', 'music_description']
parameters: [
{ key: 'photo_library_description', question: 'Please provide a description for accessing the photo library: ', required: true, condition: (args) => args.platform === 'ios' },
{ key: 'music_description', question: 'Please provide a description for accessing music files: ', required: true, condition: (args) => args.platform === 'ios' }
]
},
{
name: 'contacts',
path: 'scripts/modules/enable_contacts.dart',
parameters: ['contacts_description']
parameters: [
{ key: 'contacts_description', question: 'Please provide a description for accessing contacts: ', required: true, condition: (args) => args.platform === 'ios' }
]
},
{
name: 'connect',
path: 'scripts/modules/enable_connect.dart',
parameters: ['camera_description'],
parameters: [
{ key: 'camera_description', question: 'Please provide a camera usage description: ', required: true, condition: (args) => args.platform === 'ios' }
]
},
{
name: 'location',
path: 'scripts/modules/enable_location.dart',
parameters: ['in_use_location_description', 'always_use_location_description', 'google_maps', 'google_maps_api_key']
parameters: [
{ key: 'in_use_location_description', question: 'Please provide a description for using location services while the app is in use: ', required: true, condition: (args) => args.platform === 'ios' },
{ key: 'always_use_location_description', question: 'Please provide a description for using location services always: ', required: true, condition: (args) => args.platform === 'ios' },
{ key: 'google_maps', question: 'Are you enabling Google Maps? (yes/no): ', required: true },
{ key: 'google_maps_api_key', question: 'Please provide your Google Maps API key: ', required: true, condition: (args) => args.google_maps === 'yes' }
]
},
{
name: 'deeplink',
path: 'scripts/modules/enable_deeplink.dart',
parameters: ['branch_live_key', 'branch_test_key', 'use_test_key', 'scheme', 'links']
parameters: [
{ key: 'branch_live_key', question: 'Please provide the live Branch.io key: ', required: true },
{ key: 'branch_test_key', question: 'Please provide the test Branch.io key: ', required: false },
{ key: 'use_test_key', question: 'Are you using the test key? (yes/no): ', required: true },
{ key: 'scheme', question: 'Please provide the URI scheme for deeplinking: ', required: true },
{ key: 'links', question: 'Please provide a comma-separated list of deeplink URLs: ', required: true }
]
},
{
name: 'firebaseAnalytics',
Expand Down Expand Up @@ -72,15 +95,20 @@ const scripts = [
{
name: 'generateKeystore',
path: 'scripts/generate_keystore.dart',
parameters: ['storePassword', 'keyPassword', 'keyAlias']
parameters: [
{ key: 'storePassword', question: 'Please provide the store password: ', required: true },
{ key: 'keyPassword', question: 'Please provide the key password: ', required: true },
{ key: 'keyAlias', question: 'Please provide the key alias: ', required: true }
]
},
{
name: 'getShaKeys',
path: 'scripts/get_sha_keys.dart',
parameters: []
}
];

// find the script object
// Find the script object by name
function findScript(name) {
return scripts.find(script => script.name === name) ||
modules.find(module => module.name === name);
Expand Down Expand Up @@ -109,7 +137,8 @@ function generateArgsForScript(scriptObj, argsArray) {
const [key, value] = arg.split('=');

// Only include arguments that are in the scriptObj's parameters or common parameters
if (scriptObj.parameters.includes(key) || commonParameters.includes(key)) {
const allowedKeys = scriptObj.parameters.map(p => p.key).concat(commonParameters.map(p => p.key));
if (allowedKeys.includes(key)) {
return `${key}=${value}`;
}

Expand All @@ -119,6 +148,39 @@ function generateArgsForScript(scriptObj, argsArray) {
.join(' ');
}

// Create readline interface for asking questions
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

function askQuestion(query) {
return new Promise(resolve => rl.question(query, resolve));
}

// Check for missing arguments and ask for them
async function checkAndAskForMissingArgs(scriptObj, argsArray) {
const providedArgs = argsArray.map(arg => arg.split('=')[0]);
const args = Object.fromEntries(argsArray.map(arg => arg.split('=')));

const allParameters = [
...commonParameters,
...scriptObj.parameters
];

for (const param of allParameters) {
const conditionMet = param.condition ? param.condition(args) : true;

if (!providedArgs.includes(param.key) && conditionMet) {
const answer = await askQuestion(param.question);
argsArray.push(`${param.key}=${answer}`);
args[param.key] = answer;
}
}

return argsArray;
}

// Execute a Dart script
function runScript(scriptObj, argsArray, callback = () => { }) {
const dartArgs = generateArgsForScript(scriptObj, argsArray);
Expand All @@ -139,12 +201,13 @@ function runScript(scriptObj, argsArray, callback = () => { }) {
}

// Function to run multiple Dart scripts in sequence (for modules)
function runScriptsSequentially(scripts, argsArray) {
async function runScriptsSequentially(scripts, argsArray) {
let index = 0;

function next(err) {
async function next(err) {
if (err) {
console.error('Stopping execution due to an error.');
rl.close();
process.exit(1);
}

Expand All @@ -154,30 +217,37 @@ function runScriptsSequentially(scripts, argsArray) {

if (!scriptObj) {
console.error(`Error: Script "${scriptName}" not found.`);
rl.close();
return process.exit(1);
}

runScript(scriptObj, argsArray, next);
// Check and prompt for missing arguments
const updatedArgsArray = await checkAndAskForMissingArgs(scriptObj, argsArray);

runScript(scriptObj, updatedArgsArray, next);
} else {
rl.close();
process.exit(0);
}
}

next();
await next();
}

function main() {
async function main() {
const [firstArg, ...restArgs] = process.argv.slice(2);

if (firstArg === 'enable') {
const { scripts, argsArray } = parseArguments(restArgs);
runScriptsSequentially(scripts, argsArray);
await runScriptsSequentially(scripts, argsArray);
} else {
const scriptObj = findScript(firstArg);

if (scriptObj) {
const { argsArray } = parseArguments(restArgs);
runScript(scriptObj, argsArray, (err) => {
const updatedArgsArray = await checkAndAskForMissingArgs(scriptObj, argsArray);
runScript(scriptObj, updatedArgsArray, (err) => {
rl.close();
if (err) {
process.exit(1);
} else {
Expand Down
5 changes: 4 additions & 1 deletion starter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
},
"keywords": [],
"author": "",
"license": "ISC"
"license": "ISC",
"dependencies": {
"readline": "^1.3.0"
}
}

0 comments on commit 328e416

Please sign in to comment.