Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 47 additions & 8 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,11 @@ def scanner_status():

@app.route('/api/repo/branches', methods=['POST'])
def get_branches():
"""Fetch branches for a given repository URL."""
"""Fetch branches for a given repository URL.

For GitHub repositories, also returns the default_branch as reported
by the GitHub REST API so the UI can pre-select it.
"""
data = request.get_json()
repo_url = data.get('url')

Expand All @@ -215,6 +219,32 @@ def get_branches():

# Strip query parameters and hash fragments from URL
repo_url = repo_url.split('?')[0].split('#')[0]

# --- Detect GitHub URL and fetch default branch via the GitHub API ---
default_branch = None
import re as _re
github_match = _re.match(
r'https?://github\.com/([^/]+)/([^/]+?)(?:\.git)?/?$',
repo_url,
_re.IGNORECASE
)
if github_match:
owner, repo_name = github_match.group(1), github_match.group(2)
try:
gh_headers = {'Accept': 'application/vnd.github+json'}
gh_token = os.getenv('GITHUB_TOKEN', '').strip()
if gh_token:
gh_headers['Authorization'] = f'Bearer {gh_token}'
gh_resp = requests.get(
f'https://api.github.com/repos/{owner}/{repo_name}',
headers=gh_headers,
timeout=10
)
if gh_resp.status_code == 200:
default_branch = gh_resp.json().get('default_branch')
except Exception:
pass # Non-fatal – fall back to ls-remote ordering
# --- End GitHub detection ---

try:
g = cmd.Git()
Expand All @@ -225,18 +255,27 @@ def get_branches():
if '\trefs/heads/' in line:
branches.append(line.split('\trefs/heads/')[-1])

# Sort branches, but keep 'main' or 'master' at the top if they exist
# Sort branches alphabetically
if branches:
branches.sort()
for primary in ['main', 'master']:
if primary in branches:
branches.remove(primary)
branches.insert(0, primary)
# Promote the actual default branch to the top
top_branch = default_branch if default_branch and default_branch in branches else None
if top_branch is None:
# Fallback: prefer 'main', then 'master'
for primary in ['main', 'master']:
if primary in branches:
top_branch = primary
break
if top_branch and top_branch in branches:
branches.remove(top_branch)
branches.insert(0, top_branch)
else:
# If no heads found, return common defaults as a fallback
branches = ['main', 'master']
if default_branch and default_branch not in branches:
branches.insert(0, default_branch)

return jsonify({'branches': branches})
return jsonify({'branches': branches, 'default_branch': default_branch})
except Exception as e:
error_msg = str(e).lower()
if 'could not read' in error_msg or 'not found' in error_msg or 'does not exist' in error_msg:
Expand Down Expand Up @@ -636,4 +675,4 @@ def subscribe_newsletter():
return jsonify({'error': 'Failed to complete subscription'}), 500

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
app.run(debug=True, host='0.0.0.0', port=5000)
9 changes: 7 additions & 2 deletions static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function initApp() {
if (!data) return;

const isHostedReport = window.location.pathname.startsWith('/report/');

if (!isHostedReport) {
// Hide all web app specific UI parts for standalone CLI
if (scanInputContainer) scanInputContainer.style.display = 'none';
Expand Down Expand Up @@ -449,6 +449,11 @@ function initApp() {
if (data.branches && data.branches.length > 0) {
if (branchSelect) {
branchSelect.innerHTML = data.branches.map(b => `<option value="${escapeHtml(b)}">${escapeHtml(b)}</option>`).join('');
// Pre-select the repository's actual default branch when available
if (data.default_branch) {
const defaultOption = branchSelect.querySelector(`option[value="${CSS.escape(data.default_branch)}"]`);
if (defaultOption) defaultOption.selected = true;
}
}
if (branchSelectionContainer) branchSelectionContainer.classList.remove('hidden');
}
Expand Down Expand Up @@ -1682,4 +1687,4 @@ function toggleCVE(cveId) {
details.style.display = 'none';
if (icon) icon.textContent = '▼';
}
}
}
Loading