or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-communication.mdcoverage-processing.mdindex.mdmain-workflow.mdrepository-integration.md

repository-integration.mddocs/

0

# Repository Integration

1

2

The repository integration module provides version control system support for extracting git and mercurial repository information. It automatically detects the VCS type and extracts commit details, branch information, and remote URLs required by the coveralls.io API.

3

4

## Capabilities

5

6

### Auto-Detection and Information Extraction

7

8

Automatically detects repository type and extracts comprehensive repository information.

9

10

```python { .api }

11

def repo(root):

12

"""

13

Auto-detect repository type and extract information.

14

15

Args:

16

root (str): Path to repository root directory

17

18

Returns:

19

dict | None: Repository information dictionary or None if no VCS detected

20

21

Detection Logic:

22

1. Check for .git directory (Git repository)

23

2. Check for .hg directory (Mercurial repository)

24

3. Return None if neither found

25

26

Repository Info Structure:

27

{

28

"head": {

29

"id": str, # Commit hash/ID

30

"author_name": str, # Author name

31

"author_email": str, # Author email

32

"committer_name": str, # Committer name

33

"committer_email": str, # Committer email

34

"message": str, # Commit message

35

},

36

"branch": str, # Current branch name

37

"remotes": [ # Remote repositories

38

{

39

"name": str, # Remote name (e.g., "origin")

40

"url": str, # Remote URL

41

}

42

]

43

}

44

"""

45

```

46

47

### Git Repository Integration

48

49

Extracts comprehensive information from Git repositories including commit details, branch, and remote configuration.

50

51

```python { .api }

52

def gitrepo(root):

53

"""

54

Extract information from Git repository.

55

56

Args:

57

root (str): Path to Git repository root

58

59

Returns:

60

dict: Git repository information

61

62

Extracted Information:

63

- Latest commit details (hash, author, committer, message)

64

- Current branch (with CI environment variable fallbacks)

65

- All configured remotes with fetch URLs

66

67

Branch Detection Priority:

68

1. CIRCLE_BRANCH environment variable (Circle CI)

69

2. TRAVIS_BRANCH environment variable (Travis CI)

70

3. git rev-parse --abbrev-ref HEAD (local branch)

71

72

Commands Used:

73

- git log -1 --pretty=format:[format] (commit info)

74

- git rev-parse --abbrev-ref HEAD (branch name)

75

- git remote -v (remote URLs)

76

"""

77

```

78

79

### Mercurial Repository Integration

80

81

Extracts information from Mercurial repositories with similar structure to Git integration.

82

83

```python { .api }

84

def hgrepo(root):

85

"""

86

Extract information from Mercurial repository.

87

88

Args:

89

root (str): Path to Mercurial repository root

90

91

Returns:

92

dict: Mercurial repository information

93

94

Extracted Information:

95

- Latest changeset details (hash, author, message)

96

- Current branch (with CI environment variable fallbacks)

97

- Configured paths (remotes)

98

99

Branch Detection Priority:

100

1. CIRCLE_BRANCH environment variable (Circle CI)

101

2. TRAVIS_BRANCH environment variable (Travis CI)

102

3. hg branch (local branch)

103

104

Commands Used:

105

- hg log -l 1 --template=[template] (changeset info)

106

- hg branch (branch name)

107

- hg paths (remote URLs)

108

"""

109

```

110

111

## Data Structures and Formats

112

113

### Git Log Format

114

115

```python { .api }

116

# Internal format string for git log command

117

FORMAT = '%n'.join(['%H', '%aN', '%ae', '%cN', '%ce', '%s'])

118

# %H: Commit hash

119

# %aN: Author name

120

# %ae: Author email

121

# %cN: Committer name

122

# %ce: Committer email

123

# %s: Subject (commit message)

124

```

125

126

### Mercurial Log Template

127

128

```python { .api }

129

# Template for mercurial log command

130

HGLOG = """{node}

131

{author|person}

132

{author|email}

133

{author|person}

134

{author|email}

135

{desc}"""

136

# {node}: Changeset hash

137

# {author|person}: Author name

138

# {author|email}: Author email

139

# {desc}: Description (commit message)

140

```

141

142

## Usage Examples

143

144

### Basic Repository Detection

145

146

```python

147

from coveralls.repository import repo

148

149

# Auto-detect and extract repository info

150

repo_info = repo('/path/to/project')

151

152

if repo_info:

153

print(f"Repository detected: {repo_info['head']['id'][:8]}")

154

print(f"Branch: {repo_info['branch']}")

155

print(f"Author: {repo_info['head']['author_name']}")

156

157

for remote in repo_info['remotes']:

158

print(f"Remote {remote['name']}: {remote['url']}")

159

else:

160

print("No version control system detected")

161

```

162

163

### Git-Specific Integration

164

165

```python

166

from coveralls.repository import gitrepo

167

import os

168

169

# Direct Git repository processing

170

try:

171

git_info = gitrepo('/path/to/git/repo')

172

173

# Access commit information

174

commit = git_info['head']

175

print(f"Commit: {commit['id']}")

176

print(f"Author: {commit['author_name']} <{commit['author_email']}>")

177

print(f"Message: {commit['message']}")

178

179

# Branch information (with CI detection)

180

print(f"Branch: {git_info['branch']}")

181

182

# Remote repositories

183

for remote in git_info['remotes']:

184

print(f"{remote['name']}: {remote['url']}")

185

186

except subprocess.CalledProcessError as e:

187

print(f"Git command failed: {e}")

188

except Exception as e:

189

print(f"Repository processing error: {e}")

190

```

191

192

### Mercurial Integration

193

194

```python

195

from coveralls.repository import hgrepo

196

197

# Direct Mercurial repository processing

198

try:

199

hg_info = hgrepo('/path/to/hg/repo')

200

201

# Access changeset information

202

head = hg_info['head']

203

print(f"Changeset: {head['id']}")

204

print(f"Author: {head['author_name']} <{head['author_email']}>")

205

print(f"Description: {head['message']}")

206

207

# Branch and remotes

208

print(f"Branch: {hg_info['branch']}")

209

for remote in hg_info['remotes']:

210

print(f"{remote['name']}: {remote['url']}")

211

212

except subprocess.CalledProcessError as e:

213

print(f"Mercurial command failed: {e}")

214

except Exception as e:

215

print(f"Repository processing error: {e}")

216

```

217

218

## CI Environment Integration

219

220

### Environment Variable Detection

221

222

The module automatically detects CI environments and uses their branch information:

223

224

```python { .api }

225

# Branch detection priority (in gitrepo and hgrepo)

226

branch_sources = [

227

"CIRCLE_BRANCH", # Circle CI

228

"TRAVIS_BRANCH", # Travis CI

229

# Local VCS command as fallback

230

]

231

232

# Example CI integration

233

import os

234

235

# Circle CI

236

if 'CIRCLE_BRANCH' in os.environ:

237

branch = os.environ['CIRCLE_BRANCH']

238

239

# Travis CI

240

elif 'TRAVIS_BRANCH' in os.environ:

241

branch = os.environ['TRAVIS_BRANCH']

242

243

# Local detection

244

else:

245

branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])

246

```

247

248

### CI Service Configuration

249

250

```bash

251

# Travis CI - automatic detection

252

language: python

253

script: pytest --cov=mypackage

254

after_success: coveralls

255

256

# Circle CI - manual branch setting

257

version: 2

258

jobs:

259

build:

260

environment:

261

CIRCLE_BRANCH: ${CIRCLE_BRANCH}

262

steps:

263

- run: pytest --cov=mypackage

264

- run: coveralls

265

266

# GitHub Actions - manual configuration

267

env:

268

GITHUB_BRANCH: ${GITHUB_REF#refs/heads/}

269

run: |

270

pytest --cov=mypackage

271

TRAVIS_BRANCH=$GITHUB_BRANCH coveralls

272

```

273

274

## Error Handling and Edge Cases

275

276

### Repository Detection Failures

277

278

```python

279

from coveralls.repository import repo

280

281

# Handle missing VCS

282

repo_info = repo('/path/without/vcs')

283

if repo_info is None:

284

# No git or mercurial repository found

285

# Use empty dict or skip repository info

286

repo_info = {}

287

```

288

289

### Command Execution Errors

290

291

```python

292

from coveralls.repository import gitrepo

293

import subprocess

294

295

try:

296

git_info = gitrepo('/path/to/repo')

297

except subprocess.CalledProcessError as e:

298

# Git command failed (corrupted repo, permissions, etc.)

299

print(f"Git error: {e}")

300

git_info = None

301

except FileNotFoundError:

302

# Git not installed or not in PATH

303

print("Git not found")

304

git_info = None

305

```

306

307

### Malformed Repository Data

308

309

```python

310

# Robust repository info processing

311

def safe_repo_info(repo_path):

312

try:

313

info = repo(repo_path)

314

315

# Validate required fields

316

if info and 'head' in info and 'id' in info['head']:

317

return info

318

else:

319

return None

320

321

except Exception as e:

322

print(f"Repository info extraction failed: {e}")

323

return None

324

325

# Usage with fallback

326

repo_info = safe_repo_info('/path/to/project') or {}

327

```

328

329

## Integration with Main Workflow

330

331

### Conditional Repository Integration

332

333

```python

334

# From main workflow (wear function)

335

def wear(args=None):

336

# ... other setup ...

337

338

# Extract repository info only if not disabled

339

if not args.nogit:

340

git_info = repo(args.base_dir)

341

if git_info is None:

342

git_info = {} # Empty dict for no VCS

343

else:

344

git_info = {} # Skip repository info entirely

345

346

# ... continue with API submission ...

347

```

348

349

### Directory Context Management

350

351

```python

352

# Repository functions change working directory temporarily

353

import os

354

355

original_dir = os.getcwd()

356

try:

357

repo_info = gitrepo('/path/to/repo') # Changes to repo directory internally

358

finally:

359

os.chdir(original_dir) # Always restore original directory

360

```

361

362

## Best Practices

363

364

### Working Directory Management

365

366

The repository functions change the current working directory temporarily. Ensure proper restoration:

367

368

```python

369

import os

370

from coveralls.repository import repo

371

372

# Save current directory

373

original_cwd = os.getcwd()

374

375

try:

376

# Extract repository info (may change directory)

377

repo_info = repo('/path/to/project')

378

finally:

379

# Always restore original directory

380

os.chdir(original_cwd)

381

```

382

383

### Error Resilience

384

385

```python

386

# Robust repository integration

387

def get_repo_info(project_path, skip_git=False):

388

if skip_git:

389

return {}

390

391

try:

392

return repo(project_path) or {}

393

except Exception as e:

394

logging.warning(f"Repository info extraction failed: {e}")

395

return {}

396

```