or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdenvironment-validation.mdindex.mdinteractive-selection.mdpackage-parsing.mdpackage-upgrading.mdrequirements-detection.mdstatus-detection.md

interactive-selection.mddocs/

0

# Interactive Selection

1

2

User interface for selecting packages to upgrade, presenting upgrade information in formatted tables with interactive prompts and pre-selection options.

3

4

## Capabilities

5

6

### Interactive Package Selection

7

8

Presents available package upgrades in a formatted table and handles user selection through an interactive command-line interface.

9

10

```python { .api }

11

class PackageInteractiveSelector:

12

def __init__(self, packages_map, options):

13

"""

14

Initialize interactive package selector.

15

16

Args:

17

packages_map (dict): Package status map from PackagesStatusDetector

18

options (dict): Command-line options including -p for pre-selection

19

20

Raises:

21

KeyboardInterrupt: If no packages need upgrading

22

"""

23

24

def get_packages(self):

25

"""

26

Return the list of packages selected for upgrade.

27

28

Returns:

29

list: List of package status dictionaries for selected packages

30

"""

31

32

def ask_for_packages(self):

33

"""

34

Display interactive upgrade table and prompt for user selection.

35

36

Displays:

37

- Formatted table with package names, versions, and upload dates

38

- Color-coded output for better readability

39

- Interactive prompt for package selection

40

41

Raises:

42

KeyboardInterrupt: On invalid selection or user cancellation

43

"""

44

```

45

46

### Package Selection Processing

47

48

Processes user selection input and validates package choices.

49

50

```python { .api }

51

def _select_packages(self, indexes):

52

"""

53

Select packages by index numbers from the upgrade table.

54

55

Args:

56

indexes (list): List of integer indexes corresponding to table rows

57

58

Returns:

59

list: List of booleans indicating successful selections

60

61

Side effects:

62

Populates self.selected_packages with selected package dictionaries

63

"""

64

```

65

66

### Cross-Platform Input Handling

67

68

Provides compatible input handling across Python 2 and 3.

69

70

```python { .api }

71

def user_input(prompt=None):

72

"""

73

Cross-Python compatible input function.

74

75

Args:

76

prompt (str, optional): Prompt string to display

77

78

Returns:

79

str: User input string

80

81

Compatibility:

82

Uses raw_input for Python 2, input for Python 3

83

"""

84

```

85

86

## Selection Modes

87

88

### Interactive Mode (Default)

89

90

When no `-p` option is provided, displays an interactive table for package selection.

91

92

**Table Format:**

93

```

94

Available upgrades:

95

┌─────┬─────────────────┬─────────────────┬────────────────┬─────────────────┐

96

│ No. │ Package │ Current version │ Latest version │ Release date │

97

├─────┼─────────────────┼─────────────────┼────────────────┼─────────────────┤

98

│ 1 │ django │ 3.2.0 │ 4.1.0 │ 2022-08-03 │

99

│ 2 │ requests │ 2.25.1 │ 2.28.1 │ 2022-06-29 │

100

│ 3 │ flask │ 2.0.0 │ 2.2.2 │ 2022-08-08 │

101

└─────┴─────────────────┴─────────────────┴────────────────┴─────────────────┘

102

103

Please choose which packages should be upgraded. Choices: "all", "q" (quit), "x" (exit) or "1 2 3"

104

Choice:

105

```

106

107

**Selection Options:**

108

- `all` - Select all available upgrades

109

- `q` or `x` - Quit/exit without upgrading

110

- `1 2 3` - Space-separated list of package numbers

111

- Empty input - Cancel operation

112

113

### Pre-Selection Mode

114

115

When `-p` option is provided, skips interactive prompts.

116

117

**All Packages:**

118

```bash

119

pip-upgrade requirements.txt -p all

120

```

121

122

**Specific Packages:**

123

```bash

124

pip-upgrade requirements.txt -p django -p flask

125

```

126

127

Matches package names case-insensitively.

128

129

## Usage Examples

130

131

### Interactive Selection

132

133

```python

134

from pip_upgrader.packages_interactive_selector import PackageInteractiveSelector

135

136

# Package status map from status detector

137

packages_map = {

138

'django': {

139

'name': 'django',

140

'current_version': Version('3.2.0'),

141

'latest_version': Version('4.1.0'),

142

'upgrade_available': True,

143

'upload_time': '2022-08-03 08:15:30'

144

},

145

'requests': {

146

'name': 'requests',

147

'current_version': Version('2.25.1'),

148

'latest_version': Version('2.28.1'),

149

'upgrade_available': True,

150

'upload_time': '2022-06-29 14:22:18'

151

}

152

}

153

154

# Interactive selection (no -p option)

155

options = {'-p': []}

156

selector = PackageInteractiveSelector(packages_map, options)

157

selected = selector.get_packages()

158

159

# User sees table and chooses "1 2"

160

print(len(selected)) # 2 packages selected

161

```

162

163

### Pre-Selection All

164

165

```python

166

# Select all packages automatically

167

options = {'-p': ['all']}

168

selector = PackageInteractiveSelector(packages_map, options)

169

selected = selector.get_packages()

170

171

print(len(selected)) # All upgradeable packages selected

172

```

173

174

### Pre-Selection Specific

175

176

```python

177

# Pre-select specific packages

178

options = {'-p': ['django', 'flask']}

179

selector = PackageInteractiveSelector(packages_map, options)

180

selected = selector.get_packages()

181

182

# Only django and flask will be selected (if available for upgrade)

183

```

184

185

## Color-Coded Output

186

187

The interface uses `colorclass` for enhanced terminal output:

188

189

### Table Headers

190

- **Blue**: Column headers (No., Package, Current version, etc.)

191

192

### Package Information

193

- **Green**: Package names and row numbers

194

- **Default**: Version numbers and dates

195

196

### User Prompts

197

- **Green**: "Available upgrades:" header

198

- **Red**: Error messages ("No choice selected", "Invalid choice")

199

200

### Status Messages

201

- **Green**: "All packages are up-to-date" when no upgrades available

202

203

## Input Validation

204

205

### Valid Inputs

206

207

```python

208

"all" # Select all packages

209

"1" # Select package #1

210

"1 2 3" # Select packages #1, #2, #3

211

"q" # Quit

212

"x" # Exit

213

```

214

215

### Invalid Inputs

216

217

```python

218

"" # Empty input -> "No choice selected"

219

" " # Whitespace only -> "No choice selected"

220

"5 6 7" # Non-existent indexes -> "No valid choice selected"

221

"abc" # Non-numeric -> "Invalid choice"

222

```

223

224

All invalid inputs raise `KeyboardInterrupt` with appropriate error messages.

225

226

## Edge Cases

227

228

### No Upgrades Available

229

230

When all packages are up-to-date:

231

232

```python

233

# Prints colored message and raises KeyboardInterrupt

234

print(Color('{autogreen}All packages are up-to-date.{/autogreen}'))

235

raise KeyboardInterrupt()

236

```

237

238

### Package Filtering

239

240

Only packages with `upgrade_available: True` are included in the interactive table. Up-to-date packages are filtered out automatically.

241

242

### Case-Insensitive Matching

243

244

Pre-selected package names are matched case-insensitively:

245

246

```python

247

# These are equivalent:

248

-p Django

249

-p django

250

-p DJANGO

251

```

252

253

### Index Mapping

254

255

Interactive selection uses 1-based indexing for user-friendliness, but internally maps to 0-based dictionary keys.

256

257

## Error Handling

258

259

### Selection Errors

260

261

- **Empty selection**: Displays "No choice selected" and cancels

262

- **Invalid numbers**: Displays "Invalid choice" and cancels

263

- **Out-of-range numbers**: Displays "No valid choice selected" and cancels

264

- **No matching pre-selected packages**: Results in empty selection (not an error)

265

266

### User Cancellation

267

268

- **Keyboard interrupts**: Ctrl+C during input gracefully exits

269

- **Quit commands**: 'q' and 'x' commands raise KeyboardInterrupt for clean exit

270

- **Empty selections**: Treated as cancellation

271

272

### Package Mapping Errors

273

274

- **Missing packages**: Pre-selected packages not found in packages_map are silently skipped

275

- **Invalid package data**: Malformed package dictionaries may cause processing errors in later stages

276

277

## Integration Points

278

279

### Input from PackagesStatusDetector

280

281

Requires package status map with specific structure:

282

283

```python

284

{

285

'package_name': {

286

'name': str,

287

'current_version': Version,

288

'latest_version': Version,

289

'upgrade_available': bool,

290

'upload_time': str

291

}

292

}

293

```

294

295

### Output to PackagesUpgrader

296

297

Produces list of package dictionaries for upgrade processing:

298

299

```python

300

[

301

{

302

'name': 'django',

303

'current_version': Version('3.2.0'),

304

'latest_version': Version('4.1.0'),

305

'upgrade_available': True,

306

'upload_time': '2022-08-03 08:15:30'

307

}

308

]

309

```