|
|
|
@@ -1,6 +1,9 @@
|
|
|
|
|
import { getContext, setContext } from 'svelte'
|
|
|
|
|
import { JobService, WorkspaceService, ResourceService } from '$lib/gen'
|
|
|
|
|
import type { GitRepositorySettings as BackendGitRepositorySettings, GitSyncObjectType } from '$lib/gen'
|
|
|
|
|
import type {
|
|
|
|
|
GitRepositorySettings as BackendGitRepositorySettings,
|
|
|
|
|
GitSyncObjectType
|
|
|
|
|
} from '$lib/gen'
|
|
|
|
|
import { jobManager } from '$lib/services/JobManager'
|
|
|
|
|
import hubPaths from '$lib/hubPaths.json'
|
|
|
|
|
import type { SettingsObject } from '$lib/git-sync'
|
|
|
|
@@ -37,9 +40,9 @@ export type GitSyncSettings = {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type ModalState = {
|
|
|
|
|
push: { idx: number, repo: GitSyncRepository, open: boolean } | null
|
|
|
|
|
pull: { idx: number, repo: GitSyncRepository, open: boolean, settingsOnly?: boolean } | null
|
|
|
|
|
success: { open: boolean, savedWithoutInit?: boolean } | null
|
|
|
|
|
push: { idx: number; repo: GitSyncRepository; open: boolean } | null
|
|
|
|
|
pull: { idx: number; repo: GitSyncRepository; open: boolean; settingsOnly?: boolean } | null
|
|
|
|
|
success: { open: boolean; savedWithoutInit?: boolean } | null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type ValidationState = {
|
|
|
|
@@ -101,10 +104,10 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
const validationStates = getValidationStates()
|
|
|
|
|
|
|
|
|
|
// Check if any individual repositories have changes
|
|
|
|
|
const individualChanges = validationStates.some(v => v.hasChanges)
|
|
|
|
|
const individualChanges = validationStates.some((v) => v.hasChanges)
|
|
|
|
|
|
|
|
|
|
// Check if any legacy repos were imported
|
|
|
|
|
const anyLegacyImported = repositories.some(r => r.legacyImported)
|
|
|
|
|
const anyLegacyImported = repositories.some((r) => r.legacyImported)
|
|
|
|
|
|
|
|
|
|
// Check if the set of repositories has changed (added/removed repos)
|
|
|
|
|
const repositorySetChanged = (() => {
|
|
|
|
@@ -113,31 +116,33 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!initialRepositories || initialRepositories.length === 0) {
|
|
|
|
|
return repositories.filter((_,i) => validationStates[i]?.isValid).length > 0
|
|
|
|
|
return repositories.filter((_, i) => validationStates[i]?.isValid).length > 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const initialValidPaths = new Set(
|
|
|
|
|
initialRepositories
|
|
|
|
|
.filter(r => r.git_repo_resource_path && r.git_repo_resource_path.trim() !== '')
|
|
|
|
|
.map(r => r.git_repo_resource_path)
|
|
|
|
|
.filter((r) => r.git_repo_resource_path && r.git_repo_resource_path.trim() !== '')
|
|
|
|
|
.map((r) => r.git_repo_resource_path)
|
|
|
|
|
)
|
|
|
|
|
const currentValidPaths = new Set(
|
|
|
|
|
repositories
|
|
|
|
|
.filter((_,i) => validationStates[i]?.isValid)
|
|
|
|
|
.map(r => r.git_repo_resource_path)
|
|
|
|
|
.filter((_, i) => validationStates[i]?.isValid)
|
|
|
|
|
.map((r) => r.git_repo_resource_path)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Check if sets are different (repos added or removed)
|
|
|
|
|
return initialValidPaths.size !== currentValidPaths.size ||
|
|
|
|
|
[...initialValidPaths].some(path => !currentValidPaths.has(path)) ||
|
|
|
|
|
[...currentValidPaths].some(path => !initialValidPaths.has(path))
|
|
|
|
|
return (
|
|
|
|
|
initialValidPaths.size !== currentValidPaths.size ||
|
|
|
|
|
[...initialValidPaths].some((path) => !currentValidPaths.has(path)) ||
|
|
|
|
|
[...currentValidPaths].some((path) => !initialValidPaths.has(path))
|
|
|
|
|
)
|
|
|
|
|
})()
|
|
|
|
|
|
|
|
|
|
return individualChanges || anyLegacyImported || repositorySetChanged
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getAllRepositoriesValid = () => getValidationStates().every(v => v.isValid)
|
|
|
|
|
const getHasUnsavedConnections = () => repositories.some(repo => repo.isUnsavedConnection)
|
|
|
|
|
const getAllRepositoriesValid = () => getValidationStates().every((v) => v.isValid)
|
|
|
|
|
const getHasUnsavedConnections = () => repositories.some((repo) => repo.isUnsavedConnection)
|
|
|
|
|
|
|
|
|
|
function validateRepository(repo: GitSyncRepository, idx: number): boolean {
|
|
|
|
|
if (!repo.git_repo_resource_path) return false
|
|
|
|
@@ -146,7 +151,9 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
|
|
|
|
|
function checkDuplicate(repo: GitSyncRepository, idx: number): boolean {
|
|
|
|
|
if (!repo.git_repo_resource_path) return false
|
|
|
|
|
const firstIdx = repositories.findIndex(r => r.git_repo_resource_path === repo.git_repo_resource_path)
|
|
|
|
|
const firstIdx = repositories.findIndex(
|
|
|
|
|
(r) => r.git_repo_resource_path === repo.git_repo_resource_path
|
|
|
|
|
)
|
|
|
|
|
return firstIdx !== -1 && firstIdx < idx
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -157,7 +164,9 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
// Legacy repositories always have "changes" because they need migration
|
|
|
|
|
if (repo.legacyImported) return true
|
|
|
|
|
|
|
|
|
|
return JSON.stringify(serializeRepository(repo)) !== JSON.stringify(serializeRepository(initial))
|
|
|
|
|
return (
|
|
|
|
|
JSON.stringify(serializeRepository(repo)) !== JSON.stringify(serializeRepository(initial))
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function serializeRepository(repo: GitSyncRepository) {
|
|
|
|
@@ -166,8 +175,9 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
script_path: repo.script_path,
|
|
|
|
|
use_individual_branch: repo.use_individual_branch,
|
|
|
|
|
group_by_folder: repo.group_by_folder,
|
|
|
|
|
force_branch: repo.force_branch,
|
|
|
|
|
settings: repo.settings,
|
|
|
|
|
exclude_types_override: repo.exclude_types_override,
|
|
|
|
|
exclude_types_override: repo.exclude_types_override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -200,7 +210,7 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
|
|
|
|
|
// Check if this repository exists in the initial (saved) state
|
|
|
|
|
const existsInInitialState = initialRepositories.some(
|
|
|
|
|
initialRepo => initialRepo.git_repo_resource_path === repo.git_repo_resource_path
|
|
|
|
|
(initialRepo) => initialRepo.git_repo_resource_path === repo.git_repo_resource_path
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Only call backend API if repository exists in the saved state
|
|
|
|
@@ -214,7 +224,7 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
|
|
|
|
|
// Update initial state to remove the deleted repository
|
|
|
|
|
const initialIdx = initialRepositories.findIndex(
|
|
|
|
|
initialRepo => initialRepo.git_repo_resource_path === repo.git_repo_resource_path
|
|
|
|
|
(initialRepo) => initialRepo.git_repo_resource_path === repo.git_repo_resource_path
|
|
|
|
|
)
|
|
|
|
|
if (initialIdx !== -1) {
|
|
|
|
|
initialRepositories.splice(initialIdx, 1)
|
|
|
|
@@ -309,45 +319,42 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
repo._detectionTimestamp = detectionTimestamp
|
|
|
|
|
|
|
|
|
|
// Use JobManager for polling - result will be the actual job response
|
|
|
|
|
await jobManager.runWithProgress(
|
|
|
|
|
() => Promise.resolve(jobId),
|
|
|
|
|
{
|
|
|
|
|
workspace,
|
|
|
|
|
timeout: 60000,
|
|
|
|
|
timeoutMessage: 'Detection job timed out after 60s',
|
|
|
|
|
onProgress: (status) => {
|
|
|
|
|
// Only update state if this detection is still current
|
|
|
|
|
if (repo._detectionTimestamp !== detectionTimestamp) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
await jobManager.runWithProgress(() => Promise.resolve(jobId), {
|
|
|
|
|
workspace,
|
|
|
|
|
timeout: 60000,
|
|
|
|
|
timeoutMessage: 'Detection job timed out after 60s',
|
|
|
|
|
onProgress: (status) => {
|
|
|
|
|
// Only update state if this detection is still current
|
|
|
|
|
if (repo._detectionTimestamp !== detectionTimestamp) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
repo.detectionJobStatus = status.status
|
|
|
|
|
repo.detectionJobStatus = status.status
|
|
|
|
|
|
|
|
|
|
// Process successful detection result
|
|
|
|
|
if (status.status === 'success' && status.result) {
|
|
|
|
|
const response = status.result as any
|
|
|
|
|
if (response.isInitialSetup) {
|
|
|
|
|
repo.detectionState = 'no-wmill'
|
|
|
|
|
} else {
|
|
|
|
|
repo.detectionState = 'has-wmill'
|
|
|
|
|
// Apply extracted settings from the git repository
|
|
|
|
|
if (response.local) {
|
|
|
|
|
repo.extractedSettings = response.local
|
|
|
|
|
// Auto-apply the extracted settings
|
|
|
|
|
repo.settings = {
|
|
|
|
|
...response.local,
|
|
|
|
|
exclude_path: response.local.exclude_path || [],
|
|
|
|
|
extra_include_path: response.local.extra_include_path || []
|
|
|
|
|
}
|
|
|
|
|
// Process successful detection result
|
|
|
|
|
if (status.status === 'success' && status.result) {
|
|
|
|
|
const response = status.result as any
|
|
|
|
|
if (response.isInitialSetup) {
|
|
|
|
|
repo.detectionState = 'no-wmill'
|
|
|
|
|
} else {
|
|
|
|
|
repo.detectionState = 'has-wmill'
|
|
|
|
|
// Apply extracted settings from the git repository
|
|
|
|
|
if (response.local) {
|
|
|
|
|
repo.extractedSettings = response.local
|
|
|
|
|
// Auto-apply the extracted settings
|
|
|
|
|
repo.settings = {
|
|
|
|
|
...response.local,
|
|
|
|
|
exclude_path: response.local.exclude_path || [],
|
|
|
|
|
extra_include_path: response.local.extra_include_path || []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (status.status === 'failure') {
|
|
|
|
|
repo.detectionState = 'error'
|
|
|
|
|
repo.detectionError = status.error || 'Detection failed'
|
|
|
|
|
}
|
|
|
|
|
} else if (status.status === 'failure') {
|
|
|
|
|
repo.detectionState = 'error'
|
|
|
|
|
repo.detectionError = status.error || 'Detection failed'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
// Only set error if this detection is still current
|
|
|
|
|
if (repo._detectionTimestamp !== detectionTimestamp) {
|
|
|
|
@@ -369,68 +376,88 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
if (settings.git_sync !== undefined && settings.git_sync !== null) {
|
|
|
|
|
// Detect workspace-level legacy settings (outside repositories)
|
|
|
|
|
const workspaceLegacyIncludePath: string[] = (settings.git_sync as any)?.include_path ?? []
|
|
|
|
|
const workspaceLegacyIncludeTypeRaw: GitSyncObjectType[] = (settings.git_sync as any)?.include_type ?? []
|
|
|
|
|
const workspaceLegacyIncludeTypeRaw: GitSyncObjectType[] =
|
|
|
|
|
(settings.git_sync as any)?.include_type ?? []
|
|
|
|
|
const workspaceLegacyIncludeType: GitSyncObjectType[] = [...workspaceLegacyIncludeTypeRaw]
|
|
|
|
|
|
|
|
|
|
// Update legacy workspace state
|
|
|
|
|
legacyWorkspaceIncludePath.splice(0, legacyWorkspaceIncludePath.length, ...workspaceLegacyIncludePath)
|
|
|
|
|
legacyWorkspaceIncludeType.splice(0, legacyWorkspaceIncludeType.length, ...workspaceLegacyIncludeType)
|
|
|
|
|
legacyWorkspaceIncludePath.splice(
|
|
|
|
|
0,
|
|
|
|
|
legacyWorkspaceIncludePath.length,
|
|
|
|
|
...workspaceLegacyIncludePath
|
|
|
|
|
)
|
|
|
|
|
legacyWorkspaceIncludeType.splice(
|
|
|
|
|
0,
|
|
|
|
|
legacyWorkspaceIncludeType.length,
|
|
|
|
|
...workspaceLegacyIncludeType
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (settings.git_sync.repositories) {
|
|
|
|
|
repositories.splice(0, repositories.length, ...settings.git_sync.repositories.map(repo => {
|
|
|
|
|
// Check if this is a legacy repo (no nested settings object)
|
|
|
|
|
const isRepoLegacy = !repo.settings
|
|
|
|
|
const repoExcludeTypesOverride = repo.exclude_types_override ?? []
|
|
|
|
|
repositories.splice(
|
|
|
|
|
0,
|
|
|
|
|
repositories.length,
|
|
|
|
|
...settings.git_sync.repositories.map((repo) => {
|
|
|
|
|
// Check if this is a legacy repo (no nested settings object)
|
|
|
|
|
const isRepoLegacy = !repo.settings
|
|
|
|
|
const repoExcludeTypesOverride = repo.exclude_types_override ?? []
|
|
|
|
|
|
|
|
|
|
// Determine default types - use workspace legacy or fallback
|
|
|
|
|
const defaultTypes: GitSyncObjectType[] = workspaceLegacyIncludeType.length > 0
|
|
|
|
|
? [...workspaceLegacyIncludeType]
|
|
|
|
|
: ['script', 'flow', 'app', 'folder']
|
|
|
|
|
// Determine default types - use workspace legacy or fallback
|
|
|
|
|
const defaultTypes: GitSyncObjectType[] =
|
|
|
|
|
workspaceLegacyIncludeType.length > 0
|
|
|
|
|
? [...workspaceLegacyIncludeType]
|
|
|
|
|
: ['script', 'flow', 'app', 'folder']
|
|
|
|
|
|
|
|
|
|
let repoSettings: SettingsObject
|
|
|
|
|
if (isRepoLegacy) {
|
|
|
|
|
// Legacy repo: inherit from workspace-level settings and apply exclude_types_override
|
|
|
|
|
const inheritedIncludeType = repo.settings?.include_type ?? [...defaultTypes]
|
|
|
|
|
const effectiveIncludeType = repoExcludeTypesOverride.length > 0
|
|
|
|
|
? inheritedIncludeType.filter(type => !repoExcludeTypesOverride.includes(type))
|
|
|
|
|
: inheritedIncludeType
|
|
|
|
|
let repoSettings: SettingsObject
|
|
|
|
|
if (isRepoLegacy) {
|
|
|
|
|
// Legacy repo: inherit from workspace-level settings and apply exclude_types_override
|
|
|
|
|
const inheritedIncludeType = repo.settings?.include_type ?? [...defaultTypes]
|
|
|
|
|
const effectiveIncludeType =
|
|
|
|
|
repoExcludeTypesOverride.length > 0
|
|
|
|
|
? inheritedIncludeType.filter(
|
|
|
|
|
(type) => !repoExcludeTypesOverride.includes(type)
|
|
|
|
|
)
|
|
|
|
|
: inheritedIncludeType
|
|
|
|
|
|
|
|
|
|
repoSettings = {
|
|
|
|
|
include_path: repo.settings?.include_path ?? [...workspaceLegacyIncludePath],
|
|
|
|
|
exclude_path: repo.settings?.exclude_path ?? [],
|
|
|
|
|
extra_include_path: repo.settings?.extra_include_path ?? [],
|
|
|
|
|
include_type: effectiveIncludeType
|
|
|
|
|
repoSettings = {
|
|
|
|
|
include_path: repo.settings?.include_path ?? [...workspaceLegacyIncludePath],
|
|
|
|
|
exclude_path: repo.settings?.exclude_path ?? [],
|
|
|
|
|
extra_include_path: repo.settings?.extra_include_path ?? [],
|
|
|
|
|
include_type: effectiveIncludeType
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// New format: use repo's own settings
|
|
|
|
|
repoSettings = {
|
|
|
|
|
include_path: repo.settings?.include_path ?? ['f/**'],
|
|
|
|
|
exclude_path: repo.settings?.exclude_path ?? [],
|
|
|
|
|
extra_include_path: repo.settings?.extra_include_path ?? [],
|
|
|
|
|
include_type: repo.settings?.include_type ?? ['script', 'flow', 'app']
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// New format: use repo's own settings
|
|
|
|
|
repoSettings = {
|
|
|
|
|
include_path: repo.settings?.include_path ?? ['f/**'],
|
|
|
|
|
exclude_path: repo.settings?.exclude_path ?? [],
|
|
|
|
|
extra_include_path: repo.settings?.extra_include_path ?? [],
|
|
|
|
|
include_type: repo.settings?.include_type ?? ['script', 'flow', 'app']
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...repo,
|
|
|
|
|
git_repo_resource_path: repo.git_repo_resource_path.replace('$res:', ''),
|
|
|
|
|
settings: repoSettings,
|
|
|
|
|
exclude_types_override: repoExcludeTypesOverride,
|
|
|
|
|
// Mark legacy repos for UI handling
|
|
|
|
|
legacyImported: isRepoLegacy
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
return {
|
|
|
|
|
...repo,
|
|
|
|
|
git_repo_resource_path: repo.git_repo_resource_path.replace('$res:', ''),
|
|
|
|
|
settings: repoSettings,
|
|
|
|
|
exclude_types_override: repoExcludeTypesOverride,
|
|
|
|
|
// Mark legacy repos for UI handling
|
|
|
|
|
legacyImported: isRepoLegacy
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store initial state for change tracking
|
|
|
|
|
initialRepositories.splice(0, initialRepositories.length, ...repositories.map(repo => ({ ...repo })))
|
|
|
|
|
initialRepositories.splice(
|
|
|
|
|
0,
|
|
|
|
|
initialRepositories.length,
|
|
|
|
|
...repositories.map((repo) => ({ ...repo }))
|
|
|
|
|
)
|
|
|
|
|
} finally {
|
|
|
|
|
loading = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Migration utility for legacy repositories
|
|
|
|
|
function migrateLegacyRepository(repo: GitSyncRepository): GitSyncRepository {
|
|
|
|
|
if (!repo.legacyImported) {
|
|
|
|
@@ -465,6 +492,7 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
script_path: repoToSave.script_path,
|
|
|
|
|
use_individual_branch: repoToSave.use_individual_branch,
|
|
|
|
|
group_by_folder: repoToSave.group_by_folder,
|
|
|
|
|
force_branch: repoToSave.force_branch,
|
|
|
|
|
settings: repoToSave.settings,
|
|
|
|
|
exclude_types_override: repoToSave.exclude_types_override
|
|
|
|
|
}
|
|
|
|
@@ -485,8 +513,6 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper functions for original functionality
|
|
|
|
|
|
|
|
|
|
function revertRepository(idx: number) {
|
|
|
|
@@ -496,8 +522,6 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reset detection state for a repository
|
|
|
|
|
function resetDetectionState(idx: number) {
|
|
|
|
|
const repo = repositories[idx]
|
|
|
|
@@ -515,7 +539,6 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
repo.detectionJobStatus = undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function runTestJob(idx: number) {
|
|
|
|
|
const repo = repositories[idx]
|
|
|
|
|
if (!repo?.git_repo_resource_path || !repo?.script_path) {
|
|
|
|
@@ -539,24 +562,29 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use JobManager for polling
|
|
|
|
|
await jobManager.runWithProgress(
|
|
|
|
|
() => Promise.resolve(jobId),
|
|
|
|
|
{
|
|
|
|
|
workspace,
|
|
|
|
|
timeout: 5000,
|
|
|
|
|
timeoutMessage: 'Git sync test job timed out after 5s',
|
|
|
|
|
onProgress: (status) => {
|
|
|
|
|
gitSyncTestJobs[idx].status = status.status === 'success' ? 'success' :
|
|
|
|
|
status.status === 'failure' ? 'failure' : 'running'
|
|
|
|
|
if (status.status === 'failure') {
|
|
|
|
|
gitSyncTestJobs[idx].error = status.error
|
|
|
|
|
}
|
|
|
|
|
await jobManager.runWithProgress(() => Promise.resolve(jobId), {
|
|
|
|
|
workspace,
|
|
|
|
|
timeout: 5000,
|
|
|
|
|
timeoutMessage: 'Git sync test job timed out after 5s',
|
|
|
|
|
onProgress: (status) => {
|
|
|
|
|
gitSyncTestJobs[idx].status =
|
|
|
|
|
status.status === 'success'
|
|
|
|
|
? 'success'
|
|
|
|
|
: status.status === 'failure'
|
|
|
|
|
? 'failure'
|
|
|
|
|
: 'running'
|
|
|
|
|
if (status.status === 'failure') {
|
|
|
|
|
gitSyncTestJobs[idx].error = status.error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
// Initialize the job entry if it doesn't exist (e.g., job creation failed)
|
|
|
|
|
const errorMessage = (typeof error?.body === 'string' ? error.body : error?.body?.message) || error?.message || error?.toString() || 'Failed to run test job'
|
|
|
|
|
const errorMessage =
|
|
|
|
|
(typeof error?.body === 'string' ? error.body : error?.body?.message) ||
|
|
|
|
|
error?.message ||
|
|
|
|
|
error?.toString() ||
|
|
|
|
|
'Failed to run test job'
|
|
|
|
|
if (!gitSyncTestJobs[idx]) {
|
|
|
|
|
gitSyncTestJobs[idx] = {
|
|
|
|
|
jobId: '',
|
|
|
|
@@ -570,18 +598,18 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getPrimarySyncRepository(): { repo: GitSyncRepository, idx: number } | null {
|
|
|
|
|
const idx = repositories.findIndex(r => !r.use_individual_branch)
|
|
|
|
|
function getPrimarySyncRepository(): { repo: GitSyncRepository; idx: number } | null {
|
|
|
|
|
const idx = repositories.findIndex((r) => !r.use_individual_branch)
|
|
|
|
|
return idx !== -1 ? { repo: repositories[idx], idx } : null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getPrimaryPromotionRepository(): { repo: GitSyncRepository, idx: number } | null {
|
|
|
|
|
const idx = repositories.findIndex(r => r.use_individual_branch)
|
|
|
|
|
function getPrimaryPromotionRepository(): { repo: GitSyncRepository; idx: number } | null {
|
|
|
|
|
const idx = repositories.findIndex((r) => r.use_individual_branch)
|
|
|
|
|
return idx !== -1 ? { repo: repositories[idx], idx } : null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getSecondarySyncRepositories(): { repo: GitSyncRepository, idx: number }[] {
|
|
|
|
|
const result: { repo: GitSyncRepository, idx: number }[] = []
|
|
|
|
|
function getSecondarySyncRepositories(): { repo: GitSyncRepository; idx: number }[] {
|
|
|
|
|
const result: { repo: GitSyncRepository; idx: number }[] = []
|
|
|
|
|
let foundFirst = false
|
|
|
|
|
repositories.forEach((repo, idx) => {
|
|
|
|
|
if (!repo.use_individual_branch) {
|
|
|
|
@@ -595,8 +623,8 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getSecondaryPromotionRepositories(): { repo: GitSyncRepository, idx: number }[] {
|
|
|
|
|
const result: { repo: GitSyncRepository, idx: number }[] = []
|
|
|
|
|
function getSecondaryPromotionRepositories(): { repo: GitSyncRepository; idx: number }[] {
|
|
|
|
|
const result: { repo: GitSyncRepository; idx: number }[] = []
|
|
|
|
|
let foundFirst = false
|
|
|
|
|
repositories.forEach((repo, idx) => {
|
|
|
|
|
if (repo.use_individual_branch) {
|
|
|
|
@@ -611,7 +639,7 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function removeRepositoryByPath(resourcePath: string) {
|
|
|
|
|
const idx = repositories.findIndex(r => r.git_repo_resource_path === resourcePath)
|
|
|
|
|
const idx = repositories.findIndex((r) => r.git_repo_resource_path === resourcePath)
|
|
|
|
|
if (idx !== -1) {
|
|
|
|
|
await removeRepository(idx)
|
|
|
|
|
}
|
|
|
|
@@ -697,20 +725,44 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
// Return context object
|
|
|
|
|
return {
|
|
|
|
|
// State (read-only access)
|
|
|
|
|
get repositories() { return repositories },
|
|
|
|
|
get loading() { return loading },
|
|
|
|
|
get activeModals() { return activeModals },
|
|
|
|
|
get gitSyncTestJobs() { return gitSyncTestJobs },
|
|
|
|
|
get initialRepositories() { return initialRepositories },
|
|
|
|
|
get legacyWorkspaceIncludePath() { return legacyWorkspaceIncludePath },
|
|
|
|
|
get legacyWorkspaceIncludeType() { return legacyWorkspaceIncludeType },
|
|
|
|
|
get repositories() {
|
|
|
|
|
return repositories
|
|
|
|
|
},
|
|
|
|
|
get loading() {
|
|
|
|
|
return loading
|
|
|
|
|
},
|
|
|
|
|
get activeModals() {
|
|
|
|
|
return activeModals
|
|
|
|
|
},
|
|
|
|
|
get gitSyncTestJobs() {
|
|
|
|
|
return gitSyncTestJobs
|
|
|
|
|
},
|
|
|
|
|
get initialRepositories() {
|
|
|
|
|
return initialRepositories
|
|
|
|
|
},
|
|
|
|
|
get legacyWorkspaceIncludePath() {
|
|
|
|
|
return legacyWorkspaceIncludePath
|
|
|
|
|
},
|
|
|
|
|
get legacyWorkspaceIncludeType() {
|
|
|
|
|
return legacyWorkspaceIncludeType
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Computed states - use getter functions that compute on access
|
|
|
|
|
get validationStates() { return getValidationStates() },
|
|
|
|
|
get hasAnyChanges() { return getHasAnyChanges() },
|
|
|
|
|
get allRepositoriesValid() { return getAllRepositoriesValid() },
|
|
|
|
|
get hasUnsavedConnections() { return getHasUnsavedConnections() },
|
|
|
|
|
get hasWorkspaceLevelSettings() { return hasWorkspaceLevelSettings },
|
|
|
|
|
get validationStates() {
|
|
|
|
|
return getValidationStates()
|
|
|
|
|
},
|
|
|
|
|
get hasAnyChanges() {
|
|
|
|
|
return getHasAnyChanges()
|
|
|
|
|
},
|
|
|
|
|
get allRepositoriesValid() {
|
|
|
|
|
return getAllRepositoriesValid()
|
|
|
|
|
},
|
|
|
|
|
get hasUnsavedConnections() {
|
|
|
|
|
return getHasUnsavedConnections()
|
|
|
|
|
},
|
|
|
|
|
get hasWorkspaceLevelSettings() {
|
|
|
|
|
return hasWorkspaceLevelSettings
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Methods
|
|
|
|
|
addRepository,
|
|
|
|
@@ -741,7 +793,7 @@ export function createGitSyncContext(workspace: string) {
|
|
|
|
|
getSecondaryPromotionRepositories,
|
|
|
|
|
|
|
|
|
|
// Helper methods
|
|
|
|
|
getTargetBranch,
|
|
|
|
|
getTargetBranch
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|