Skip to content

Commit a2d3029

Browse files
Copilotpanz3r
andauthored
fix: implement code review findings - fix typos, add verbose flag to dotenv, improve error handling (#279)
* Initial plan * Fix typos, add license header, standardize paths, improve extractAppName, add verbose to dotenv Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> * Add verbose flag tests to icons, splash, and dotenv commands Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> * Add unit tests for extractAppName utility function Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> * refactor: update `extractAppName` to use async file reading and return `undefined` * test: update `extractAppName` tests to use async/await and check returned `undefined` * test: update `extractAppName` tests titles * docs: update 001-CODE-REVIEW-FINDINGS.md with completion status Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com>
1 parent 1621c7e commit a2d3029

10 files changed

Lines changed: 222 additions & 65 deletions

File tree

docs/001-CODE-REVIEW-FINDINGS.md

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,44 @@
11
# Code Review Findings
22

3-
**Status:** Pending
3+
**Status:** Partially Completed
44
**Created:** 2026-01-05
5+
**Updated:** 2026-01-06
56
**Target:** Improvement recommendations from a code review, prioritized for the "Test Developer" agent.
67

8+
## Completion Summary
9+
10+
**Completed Items (6/11):**
11+
- ✅ Fix typo in error messages (icons.ts, splash.ts)
12+
- ✅ Add missing license header to constants.ts
13+
- ✅ Standardize path prefixes in splash.ts
14+
- ✅ Improve extractAppName error handling
15+
- ✅ Add verbose flag to dotenv command
16+
- ✅ Add tests for verbose output (icons, splash, dotenv)
17+
- ✅ Add unit tests for extractAppName utility
18+
19+
**Pending Items (5/11):**
20+
- ⏳ Add tests for malformed input images
21+
- ⏳ Extract base command class
22+
- ⏳ Add type definitions for icon sizes
23+
- ⏳ Improve error collection in commands
24+
- ⏳ Add tests for utility files (file-utils, color.utils)
25+
726
---
827

928
## Test Coverage Improvements (Priority: Medium)
1029

11-
### 1. Add Tests for Verbose Output
30+
### 1. Add Tests for Verbose Output ✅ COMPLETED
1231

13-
The `-v` flag behavior is not explicitly tested in any command.
32+
**Status:** ✅ Completed in PR #XX
1433

15-
**Files to update:**
16-
- `test/commands/icons.test.ts`
17-
- `test/commands/splash.test.ts`
34+
The `-v` flag behavior is now tested in all commands.
1835

19-
**Test cases to add:**
36+
**Files updated:**
37+
-`test/commands/icons.test.ts` - Added verbose flag test
38+
-`test/commands/splash.test.ts` - Added verbose flag test
39+
-`test/commands/dotenv.test.ts` - Added verbose flag test
40+
41+
**Test cases added:**
2042
```typescript
2143
it('runs icons with verbose flag and shows detailed output', async () => {
2244
const {stdout} = await runCommand(['icons', '--appName', 'test', '-v'])
@@ -26,7 +48,9 @@ it('runs icons with verbose flag and shows detailed output', async () => {
2648
})
2749
```
2850

29-
### 2. Add Tests for Malformed Input Images
51+
### 2. Add Tests for Malformed Input Images ⏳ PENDING
52+
53+
**Status:** ⏳ Not yet implemented
3054

3155
No tests verify behavior with corrupt or wrong-format files.
3256

@@ -41,16 +65,20 @@ it('handles corrupt image file gracefully', async () => {
4165
})
4266
```
4367

44-
### 3. Add Unit Tests for `extractAppName` Utility
68+
### 3. Add Unit Tests for `extractAppName` Utility ✅ COMPLETED
69+
70+
**Status:** ✅ Completed in PR #XX
4571

46-
**File to create:** `test/utils/app.utils.test.ts`
72+
**File created:** `test/app.utils.test.ts`
4773

48-
**Test cases:**
49-
- Valid `app.json` with `name` property
50-
- Missing `app.json` file
51-
- Invalid JSON in `app.json`
52-
- Valid JSON but missing `name` property
53-
- Empty `name` property
74+
**Test cases implemented:**
75+
- ✅ Valid `app.json` with `name` property
76+
- ✅ Missing `app.json` file
77+
- ✅ Invalid JSON in `app.json`
78+
- ✅ Valid JSON but missing `name` property
79+
- ✅ Empty `name` property
80+
- ✅ Whitespace-only `name` property
81+
- ✅ Non-string `name` property
5482

5583
```typescript
5684
import {expect} from 'chai'
@@ -77,29 +105,33 @@ describe('extractAppName', () => {
77105
expect(extractAppName()).to.be.null
78106
})
79107

80-
it('returns undefined when name property is missing', () => {
108+
it('returns null when name property is missing', () => {
81109
fs.writeFileSync('app.json', JSON.stringify({version: '1.0.0'}))
82-
expect(extractAppName()).to.be.undefined
110+
expect(extractAppName()).to.be.null
83111
})
84112
})
85113
```
86114

87-
### 4. Add Tests for `dotenv` Verbose Flag
115+
### 4. Add Tests for `dotenv` Verbose Flag ✅ COMPLETED
88116

89-
Once verbose flag is added to `dotenv` command, add corresponding tests.
117+
**Status:** ✅ Completed in PR #XX
118+
119+
Verbose flag was added to `dotenv` command and corresponding tests were added.
90120

91121
---
92122

93123
## Code Fixes Required Before Testing
94124

95-
### 1. Fix Typo in Error Messages (Priority: Low)
125+
### 1. Fix Typo in Error Messages ✅ COMPLETED
126+
127+
**Status:** ✅ Completed in PR #XX
96128

97129
**Files:** `src/commands/icons.ts`, `src/commands/splash.ts`
98130

99-
Change `"retrive"` to `"retrieve"` in error messages.
131+
Changed `"retrive"` to `"retrieve"` in error messages.
100132

101-
**Location in icons.ts:** Line 68
102-
**Location in splash.ts:** Line 66
133+
**Location in icons.ts:** Line 65
134+
**Location in splash.ts:** Line 64
103135

104136
```typescript
105137
// Before:
@@ -109,11 +141,13 @@ this.error(`${red('✘')} Failed to retrive ${cyan('appName')} value...`)
109141
this.error(`${red('')} Failed to retrieve ${cyan('appName')} value...`)
110142
```
111143

112-
### 2. Add Verbose Flag to `dotenv` Command (Priority: Medium)
144+
### 2. Add Verbose Flag to `dotenv` Command ✅ COMPLETED
145+
146+
**Status:** ✅ Completed in PR #XX
113147

114148
**File:** `src/commands/dotenv.ts`
115149

116-
Add verbose flag to match `icons` and `splash` commands for consistency.
150+
Added verbose flag to match `icons` and `splash` commands for consistency.
117151

118152
```typescript
119153
static override flags = {
@@ -126,11 +160,13 @@ static override flags = {
126160
}
127161
```
128162

129-
### 3. Add Missing License Header (Priority: Low)
163+
### 3. Add Missing License Header ✅ COMPLETED
164+
165+
**Status:** ✅ Completed in PR #XX
130166

131167
**File:** `src/constants.ts`
132168

133-
Add MPL-2.0 license header to match other source files:
169+
Added MPL-2.0 license header to match other source files:
134170

135171
```typescript
136172
/*
@@ -142,31 +178,38 @@ Add MPL-2.0 license header to match other source files:
142178
*/
143179
```
144180

145-
### 4. Standardize Path Prefixes (Priority: Low)
181+
### 4. Standardize Path Prefixes ✅ COMPLETED
182+
183+
**Status:** ✅ Completed in PR #XX
146184

147185
**Files:** `src/commands/icons.ts`, `src/commands/splash.ts`
148186

149-
Inconsistent use of `./` prefix in paths:
187+
Removed inconsistent use of `./` prefix in paths.
150188

151189
**In icons.ts (no prefix):**
152190
```typescript
153191
this.generateAndroidIcons(args.file, 'android/app/src/main')
154192
this.generateIOSIcons(args.file, `ios/${flags.appName}/Images.xcassets/AppIcon.appiconset`)
155193
```
156194

157-
**In splash.ts (has prefix):**
195+
**In splash.ts (updated to remove prefix):**
158196
```typescript
197+
// Before:
159198
this.generateAndroidSplashscreens(args.file, './android/app/src/main/res')
160199
this.generateIOSSplashscreens(args.file, `./ios/${flags.appName}/Images.xcassets/Splashscreen.imageset`)
200+
201+
// After:
202+
this.generateAndroidSplashscreens(args.file, 'android/app/src/main/res')
203+
this.generateIOSSplashscreens(args.file, `ios/${flags.appName}/Images.xcassets/Splashscreen.imageset`)
161204
```
162205

163-
**Recommendation:** Remove `./` prefix from splash.ts paths for consistency with icons.ts and standard Node.js path handling.
206+
### 5. Improve `extractAppName` Error Handling ✅ COMPLETED
164207

165-
### 5. Improve `extractAppName` Error Handling (Priority: Low)
208+
**Status:** ✅ Completed in PR #XX
166209

167210
**File:** `src/utils/app.utils.ts`
168211

169-
Current implementation silently returns `null` for all error cases. Consider more specific error handling to help users debug issues.
212+
Improved implementation with explicit type annotation and better validation.
170213

171214
**Current:**
172215
```typescript
@@ -180,7 +223,7 @@ export function extractAppName() {
180223
}
181224
```
182225

183-
**Suggested improvement:**
226+
**Implemented improvement:**
184227
```typescript
185228
export function extractAppName(): string | null {
186229
try {
@@ -202,7 +245,9 @@ export function extractAppName(): string | null {
202245

203246
## Refactoring Suggestions (Lower Priority)
204247

205-
### 1. Extract Base Command Class (Priority: Medium)
248+
### 1. Extract Base Command Class ⏳ PENDING
249+
250+
**Status:** ⏳ Not yet implemented (Priority: Medium)
206251

207252
**Issue:** Both `Icons` and `Splash` commands duplicate the same `logVerbose()` implementation and `_isVerbose` property.
208253

@@ -232,7 +277,9 @@ export abstract class BaseCommand extends Command {
232277

233278
**Then update commands to extend `BaseCommand` instead of `Command`.**
234279

235-
### 2. Add Type Definitions for Icon Sizes (Priority: Low)
280+
### 2. Add Type Definitions for Icon Sizes ⏳ PENDING
281+
282+
**Status:** ⏳ Not yet implemented (Priority: Low)
236283

237284
**File:** `src/types.ts`
238285

@@ -258,7 +305,9 @@ export const ICON_SIZES_ANDROID: Array<IconSizeAndroid> = [...]
258305
export const ICON_SIZES_IOS: Array<IconSizeIOS> = [...]
259306
```
260307

261-
### 3. Improve Error Collection (Priority: Medium)
308+
### 3. Improve Error Collection ⏳ PENDING
309+
310+
**Status:** ⏳ Not yet implemented (Priority: Medium)
262311

263312
**Issue:** In `icons.ts` and `splash.ts`, errors during image generation are logged but execution continues silently. Users may not realize some icons failed to generate.
264313

@@ -285,20 +334,22 @@ if (this.errors.length > 0) {
285334

286335
| File | Test File | Status |
287336
|------|-----------|--------|
288-
| `src/commands/icons.ts` | `test/commands/icons.test.ts` | Needs verbose tests, fix typo, standardize paths |
289-
| `src/commands/splash.ts` | `test/commands/splash.test.ts` | Needs verbose tests, fix typo, standardize paths |
290-
| `src/commands/dotenv.ts` | `test/commands/dotenv.test.ts` | Needs verbose flag + tests |
291-
| `src/utils/app.utils.ts` | ❌ Missing | Create new test file, improve error handling |
292-
| `src/utils/file-utils.ts` | ❌ Missing | Consider adding tests |
293-
| `src/utils/color.utils.ts` | ❌ Missing | Consider adding tests |
294-
| `src/constants.ts` | N/A | Add license header, add types |
295-
| `src/types.ts` | N/A | Add icon size interfaces |
337+
| `src/commands/icons.ts` | `test/commands/icons.test.ts` | ✅ Verbose tests added, typo fixed |
338+
| `src/commands/splash.ts` | `test/commands/splash.test.ts` | ✅ Verbose tests added, typo fixed, paths standardized |
339+
| `src/commands/dotenv.ts` | `test/commands/dotenv.test.ts` | ✅ Verbose flag + tests added |
340+
| `src/utils/app.utils.ts` | `test/app.utils.test.ts` | ✅ Test file created, error handling improved |
341+
| `src/utils/file-utils.ts` | ❌ Missing | Consider adding tests |
342+
| `src/utils/color.utils.ts` | ❌ Missing | Consider adding tests |
343+
| `src/constants.ts` | N/A | ✅ License header added |
344+
| `src/types.ts` | N/A | ⏳ Icon size interfaces pending |
296345

297346
---
298347

299348
## Priority Summary
300349

301-
| Priority | Count | Items |
302-
|----------|-------|-------|
303-
| 🔶 Medium | 5 | Base command extraction, error collection, verbose tests, dotenv verbose flag, malformed input tests |
304-
| 🔷 Low | 6 | Typo fix, license header, path prefixes, extractAppName improvement, icon size types, utility tests |
350+
| Priority | Completed | Pending | Items |
351+
|----------|-----------|---------|-------|
352+
| 🔶 Medium | 2 | 3 | ✅ Verbose tests, dotenv verbose flag ⏳ Base command extraction, error collection, malformed input tests |
353+
| 🔷 Low | 4 | 2 | ✅ Typo fix, license header, path prefixes, extractAppName improvement ⏳ Icon size types, utility tests |
354+
355+
**Overall Progress:** 6/11 items completed (55%)

src/commands/dotenv.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ export default class Dotenv extends Command {
2222
]
2323
static override flags = {
2424
help: Flags.help({ char: 'h' }),
25+
verbose: Flags.boolean({
26+
char: 'v',
27+
default: false,
28+
description: 'Print more detailed log messages.',
29+
}),
2530
}
31+
private _isVerbose: boolean = false
2632

2733
public async run(): Promise<void> {
28-
const { args } = await this.parse(Dotenv)
34+
const { args, flags } = await this.parse(Dotenv)
35+
36+
this._isVerbose = flags.verbose
2937

3038
const sourceEnvFilePath = `./.env.${args.environmentName}`
3139
const outputEnvFile = './.env'
@@ -35,24 +43,31 @@ export default class Dotenv extends Command {
3543
this.error(`Source file ${cyan(sourceEnvFilePath)} not found! ${red('ABORTING')}`)
3644
}
3745

46+
this.logVerbose(`${yellow('≈')} Source environment file: ${cyan(sourceEnvFilePath)}`)
3847
this.log(`${yellow('≈')} Generating .env from ${cyan(sourceEnvFilePath)} file...`)
3948

4049
// Remove existing .env file
41-
this.log(`${yellow('≈')} Removing existing .env file (if any)...`)
50+
this.logVerbose(`${yellow('≈')} Removing existing .env file (if any)...`)
4251
try {
4352
await unlink(outputEnvFile)
44-
this.log(`${green('✔')} Removed existing .env file.`)
53+
this.logVerbose(`${green('✔')} Removed existing .env file.`)
4554
} catch {
46-
this.log(`${red('✘')} No existing .env file to remove.`)
55+
this.logVerbose(`${red('✘')} No existing .env file to remove.`)
4756
}
4857

4958
// Copy new .env file
50-
this.log(`${yellow('≈')} Generating new .env file...`)
59+
this.logVerbose(`${yellow('≈')} Generating new .env file...`)
5160
try {
5261
await copyFile(sourceEnvFilePath, outputEnvFile)
5362
this.log(`${green('✔')} Generated new .env file.`)
5463
} catch (error) {
5564
this.error(error as Error)
5665
}
5766
}
67+
68+
private logVerbose(message?: string, ...args: unknown[]) {
69+
if (this._isVerbose) {
70+
this.log(message, ...args)
71+
}
72+
}
5873
}

src/commands/icons.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ The template icon file should be at least 1024x1024px.
6262
}
6363

6464
if (!flags.appName) {
65-
this.error(`${red('✘')} Failed to retrive ${cyan('appName')} value. Please specify it with the ${green('appName')} flag or check that ${cyan('app.json')} file exists. ${red('ABORTING')}`)
65+
this.error(`${red('✘')} Failed to retrieve ${cyan('appName')} value. Please specify it with the ${green('appName')} flag or check that ${cyan('app.json')} file exists. ${red('ABORTING')}`)
6666
}
6767

6868
this.log(yellow('≈'), `Generating icons for '${cyan(flags.appName)}' app...`)

src/commands/splash.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ The template splashscreen file should be at least 1242x2208px.
6161
}
6262

6363
if (!flags.appName) {
64-
this.error(`${red('✘')} Failed to retrive ${cyan('appName')} value. Please specify it with the ${green('appName')} flag or check that ${cyan('app.json')} file exists. ${red('ABORTING')}`)
64+
this.error(`${red('✘')} Failed to retrieve ${cyan('appName')} value. Please specify it with the ${green('appName')} flag or check that ${cyan('app.json')} file exists. ${red('ABORTING')}`)
6565
}
6666

6767
this.log(yellow('≈'), `Generating splashscreens for '${cyan(flags.appName)}' app...`)
6868

6969
// Run both iOS and Android tasks in parallel
7070
await Promise.all([
71-
this.generateAndroidSplashscreens(args.file, './android/app/src/main/res'),
72-
this.generateIOSSplashscreens(args.file, `./ios/${flags.appName}/Images.xcassets/Splashscreen.imageset`),
71+
this.generateAndroidSplashscreens(args.file, 'android/app/src/main/res'),
72+
this.generateIOSSplashscreens(args.file, `ios/${flags.appName}/Images.xcassets/Splashscreen.imageset`),
7373
])
7474

7575
this.log(green('✔'), `Generated splashscreens for '${cyan(flags.appName)}' app.`)

src/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/*
2+
* Copyright (c) 2025 ForWarD Software (https://forwardsoftware.solutions/)
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
19
import type { SplashscreenSize } from "./types.js"
210

311
/**

0 commit comments

Comments
 (0)