or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

change-management.mdcode-assistance.mderror-handling.mdindex.mdproject-management.mdrefactoring-operations.md

change-management.mddocs/

0

# Change Management

1

2

System for representing, combining, and applying code changes safely. Enables previewing modifications before applying them and supports undo operations through project history.

3

4

## Capabilities

5

6

### Change Representation

7

8

Changes represent modifications to be made to the project, providing a safe way to preview and apply code transformations.

9

10

```python { .api }

11

class Change:

12

"""

13

Base class for representing code changes.

14

"""

15

16

def do(self):

17

"""

18

Apply the change to the project.

19

This method should not be called directly - use project.do() instead.

20

"""

21

22

def get_description(self):

23

"""

24

Get human-readable description of the change.

25

26

Returns:

27

str: Description of what this change does

28

"""

29

30

class ChangeSet:

31

"""

32

Collection of multiple changes to be applied together.

33

"""

34

35

def __init__(self, description=""):

36

"""

37

Create a new change set.

38

39

Parameters:

40

- description (str): Description of the change set

41

"""

42

43

def add_change(self, change):

44

"""

45

Add a change to the set.

46

47

Parameters:

48

- change (Change): Change to add to the set

49

"""

50

51

def do(self):

52

"""Apply all changes in the set."""

53

54

def get_description(self):

55

"""Get description of all changes in the set."""

56

```

57

58

### Content Changes

59

60

Modifications to file contents including text replacement and formatting changes.

61

62

```python { .api }

63

class ChangeContents(Change):

64

"""

65

Change the contents of a file.

66

67

Parameters:

68

- resource (Resource): File to modify

69

- new_contents (str): New file contents

70

- old_contents (str, optional): Expected current contents for validation

71

"""

72

def __init__(self, resource, new_contents, old_contents=None): ...

73

74

class ChangeContentsContent(Change):

75

"""

76

Change specific content within a file using string replacement.

77

78

Parameters:

79

- resource (Resource): File to modify

80

- old_content (str): Content to replace

81

- new_content (str): Replacement content

82

- offset (int, optional): Starting offset for change

83

"""

84

def __init__(self, resource, old_content, new_content, offset=None): ...

85

```

86

87

### Resource Changes

88

89

Operations for creating, moving, and removing files and folders.

90

91

```python { .api }

92

class CreateResource(Change):

93

"""

94

Create a new file or folder.

95

96

Parameters:

97

- project (Project): Project instance

98

- path (str): Path for new resource

99

"""

100

def __init__(self, project, path): ...

101

102

class CreateFile(CreateResource):

103

"""

104

Create a new file with optional initial content.

105

106

Parameters:

107

- project (Project): Project instance

108

- path (str): File path relative to project root

109

- contents (str, optional): Initial file contents

110

"""

111

def __init__(self, project, path, contents=""): ...

112

113

class CreateFolder(CreateResource):

114

"""

115

Create a new folder.

116

117

Parameters:

118

- project (Project): Project instance

119

- path (str): Folder path relative to project root

120

"""

121

def __init__(self, project, path): ...

122

123

class RemoveResource(Change):

124

"""

125

Remove a file or folder.

126

127

Parameters:

128

- project (Project): Project instance

129

- path (str): Path of resource to remove

130

"""

131

def __init__(self, project, path): ...

132

133

class MoveResource(Change):

134

"""

135

Move or rename a file or folder.

136

137

Parameters:

138

- project (Project): Project instance

139

- path (str): Current resource path

140

- new_path (str): New resource path

141

"""

142

def __init__(self, project, path, new_path): ...

143

```

144

145

### Task Handling

146

147

Progress monitoring and cancellation support for long-running operations.

148

149

```python { .api }

150

class BaseTaskHandle:

151

"""Abstract base class for task monitoring."""

152

153

def stop(self):

154

"""Request task cancellation."""

155

156

def is_stopped(self):

157

"""

158

Check if task has been cancelled.

159

160

Returns:

161

bool: True if task should stop

162

"""

163

164

def is_finished(self):

165

"""

166

Check if task has completed.

167

168

Returns:

169

bool: True if task is finished

170

"""

171

172

class TaskHandle(BaseTaskHandle):

173

"""

174

Concrete task handle for monitoring refactoring progress.

175

176

Parameters:

177

- name (str): Task name for display

178

- cancel (callable, optional): Cancellation callback

179

"""

180

def __init__(self, name, cancel=None): ...

181

182

class BaseJobSet:

183

"""Abstract base class for managing multiple jobs."""

184

185

def create_job(self, name, count=None):

186

"""

187

Create a new job within the set.

188

189

Parameters:

190

- name (str): Job name

191

- count (int, optional): Expected number of work units

192

193

Returns:

194

Job instance for progress tracking

195

"""

196

197

class JobSet(BaseJobSet):

198

"""

199

Concrete job set for managing multiple parallel operations.

200

201

Parameters:

202

- task_handle (TaskHandle): Parent task handle

203

- count (int): Number of expected jobs

204

"""

205

def __init__(self, task_handle, count): ...

206

207

class NullTaskHandle(BaseTaskHandle):

208

"""No-op task handle that does nothing."""

209

pass

210

211

class NullJobSet(BaseJobSet):

212

"""No-op job set that does nothing."""

213

pass

214

```

215

216

### Constants

217

218

```python { .api }

219

DEFAULT_TASK_HANDLE = NullTaskHandle()

220

"""Default task handle instance for operations without progress monitoring."""

221

```

222

223

### History Management

224

225

Project history tracking for undo/redo functionality.

226

227

```python { .api }

228

class History:

229

"""

230

Project change history for undo/redo operations.

231

"""

232

233

def do(self, changes):

234

"""

235

Execute changes and add to history.

236

237

Parameters:

238

- changes (Change or ChangeSet): Changes to execute and record

239

"""

240

241

def undo(self):

242

"""

243

Undo the last set of changes.

244

245

Returns:

246

ChangeSet: Changes that were undone

247

"""

248

249

def redo(self):

250

"""

251

Redo previously undone changes.

252

253

Returns:

254

ChangeSet: Changes that were redone

255

"""

256

257

def get_description(self):

258

"""Get description of current history state."""

259

260

class ChangeStack:

261

"""

262

Stack-based change management for contrib modules.

263

"""

264

265

def push(self, changes):

266

"""

267

Add changes to the stack.

268

269

Parameters:

270

- changes (Change or ChangeSet): Changes to add

271

"""

272

273

def pop(self):

274

"""

275

Remove and return top changes from stack.

276

277

Returns:

278

Change or ChangeSet: Top changes from stack

279

"""

280

281

def top(self):

282

"""

283

Get top changes without removing them.

284

285

Returns:

286

Change or ChangeSet: Top changes from stack

287

"""

288

289

def is_empty(self):

290

"""Check if stack is empty."""

291

```

292

293

## Usage Examples

294

295

### Basic Change Operations

296

297

```python

298

from rope.base.project import Project

299

from rope.base.change import ChangeContents, ChangeSet, CreateFile

300

301

project = Project('/path/to/project')

302

303

try:

304

# Create individual changes

305

myfile = project.get_resource('mymodule.py')

306

307

# Change file contents

308

new_content = "# Modified content\nprint('Hello, World!')\n"

309

content_change = ChangeContents(myfile, new_content)

310

311

# Create a new file

312

new_file_change = CreateFile(project, 'newmodule.py', '# New module\n')

313

314

# Combine changes into a change set

315

changes = ChangeSet("Update project files")

316

changes.add_change(content_change)

317

changes.add_change(new_file_change)

318

319

# Preview changes

320

print(f"About to apply: {changes.get_description()}")

321

322

# Apply all changes

323

project.do(changes)

324

325

finally:

326

project.close()

327

```

328

329

### Task Progress Monitoring

330

331

```python

332

from rope.base.project import Project

333

from rope.base.taskhandle import TaskHandle

334

from rope.refactor.rename import Rename

335

336

def my_cancel_callback():

337

print("Cancellation requested!")

338

return True

339

340

project = Project('/path/to/project')

341

342

try:

343

# Create task handle for monitoring

344

task_handle = TaskHandle("Rename refactoring", my_cancel_callback)

345

346

# Perform refactoring with progress monitoring

347

myfile = project.get_resource('mymodule.py')

348

renamer = Rename(project, myfile, 150)

349

changes = renamer.get_changes('new_name', task_handle=task_handle)

350

351

# Check if operation was cancelled

352

if not task_handle.is_stopped():

353

project.do(changes, task_handle)

354

print("Refactoring completed")

355

else:

356

print("Refactoring cancelled")

357

358

finally:

359

project.close()

360

```

361

362

### Resource Management Changes

363

364

```python

365

from rope.base.project import Project

366

from rope.base.change import CreateFolder, MoveResource, RemoveResource

367

368

project = Project('/path/to/project')

369

370

try:

371

# Create a new package structure

372

package_folder = CreateFolder(project, 'mypackage')

373

init_file = CreateFile(project, 'mypackage/__init__.py', '# Package init\n')

374

375

# Move existing module into package

376

move_module = MoveResource(project, 'oldmodule.py', 'mypackage/module.py')

377

378

# Remove obsolete file

379

remove_old = RemoveResource(project, 'obsolete.py')

380

381

# Apply all changes together

382

changes = ChangeSet("Reorganize project structure")

383

changes.add_change(package_folder)

384

changes.add_change(init_file)

385

changes.add_change(move_module)

386

changes.add_change(remove_old)

387

388

project.do(changes)

389

390

finally:

391

project.close()

392

```

393

394

### History and Undo Operations

395

396

```python

397

from rope.base.project import Project

398

from rope.base.change import ChangeContents

399

400

project = Project('/path/to/project')

401

402

try:

403

# Enable history tracking

404

history = project.history

405

406

# Make some changes

407

myfile = project.get_resource('mymodule.py')

408

original_content = myfile.read()

409

410

# First change

411

change1 = ChangeContents(myfile, original_content + "\n# First change")

412

history.do(change1)

413

414

# Second change

415

current_content = myfile.read()

416

change2 = ChangeContents(myfile, current_content + "\n# Second change")

417

history.do(change2)

418

419

# Undo last change

420

undone = history.undo()

421

print(f"Undone: {undone.get_description()}")

422

423

# Redo the change

424

redone = history.redo()

425

print(f"Redone: {redone.get_description()}")

426

427

finally:

428

project.close()

429

```

430

431

### Change Validation

432

433

```python

434

from rope.base.project import Project

435

from rope.base.change import ChangeContents

436

437

project = Project('/path/to/project')

438

439

try:

440

myfile = project.get_resource('mymodule.py')

441

original_content = myfile.read()

442

443

# Create change with content validation

444

new_content = "# New content\nprint('Hello')\n"

445

change = ChangeContents(

446

myfile,

447

new_content,

448

old_contents=original_content # Validate current content

449

)

450

451

try:

452

project.do(change)

453

print("Change applied successfully")

454

except Exception as e:

455

print(f"Change failed: {e}")

456

457

finally:

458

project.close()

459

```