@tanagram/cli 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/sync.go +86 -1
- package/package.json +1 -1
package/commands/sync.go
CHANGED
|
@@ -8,6 +8,7 @@ import (
|
|
|
8
8
|
"sync"
|
|
9
9
|
"time"
|
|
10
10
|
|
|
11
|
+
"github.com/tanagram/cli/api"
|
|
11
12
|
"github.com/tanagram/cli/config"
|
|
12
13
|
"github.com/tanagram/cli/extractor"
|
|
13
14
|
"github.com/tanagram/cli/parser"
|
|
@@ -58,9 +59,17 @@ func Sync() error {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
// If no files changed,
|
|
62
|
+
// If no files changed, skip local sync but still try cloud sync
|
|
62
63
|
if len(filesToSync) == 0 {
|
|
63
64
|
fmt.Println("✓ All instruction files are up to date")
|
|
65
|
+
|
|
66
|
+
// Still sync cloud policies if user is authenticated
|
|
67
|
+
if err := syncCloudPolicies(gitRoot); err != nil {
|
|
68
|
+
// Don't fail the whole sync if cloud sync fails - just warn
|
|
69
|
+
fmt.Printf("\nWarning: Could not sync cloud policies: %v\n", err)
|
|
70
|
+
fmt.Println("(Run 'tanagram login' to sync policies from cloud)")
|
|
71
|
+
}
|
|
72
|
+
|
|
64
73
|
return nil
|
|
65
74
|
}
|
|
66
75
|
|
|
@@ -161,6 +170,14 @@ func Sync() error {
|
|
|
161
170
|
}
|
|
162
171
|
|
|
163
172
|
fmt.Printf("\n✓ Synced %d policies from %d changed file(s)\n", totalPolicies, len(filesToSync))
|
|
173
|
+
|
|
174
|
+
// Also sync cloud policies if user is authenticated
|
|
175
|
+
if err := syncCloudPolicies(gitRoot); err != nil {
|
|
176
|
+
// Don't fail the whole sync if cloud sync fails - just warn
|
|
177
|
+
fmt.Printf("\nWarning: Could not sync cloud policies: %v\n", err)
|
|
178
|
+
fmt.Println("(Run 'tanagram login' to sync policies from cloud)")
|
|
179
|
+
}
|
|
180
|
+
|
|
164
181
|
return nil
|
|
165
182
|
}
|
|
166
183
|
|
|
@@ -239,3 +256,71 @@ func getAPIKey() (string, error) {
|
|
|
239
256
|
}
|
|
240
257
|
return apiKey, nil
|
|
241
258
|
}
|
|
259
|
+
|
|
260
|
+
// syncCloudPolicies fetches policies from Tanagram API and saves them locally
|
|
261
|
+
// Returns an error if the user is not authenticated or if the API call fails
|
|
262
|
+
func syncCloudPolicies(gitRoot string) error {
|
|
263
|
+
fmt.Println("\nSyncing cloud policies from Tanagram...")
|
|
264
|
+
|
|
265
|
+
// Create API client (will fail if not authenticated)
|
|
266
|
+
client, err := api.NewAPIClient()
|
|
267
|
+
if err != nil {
|
|
268
|
+
return err
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Fetch policies from API
|
|
272
|
+
response, err := client.GetPolicies()
|
|
273
|
+
if err != nil {
|
|
274
|
+
return err
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if len(response.Policies) == 0 {
|
|
278
|
+
fmt.Println("No cloud policies found for your organization")
|
|
279
|
+
return nil
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Group policies by repository
|
|
283
|
+
repoMap := make(map[string][]api.Policy)
|
|
284
|
+
for _, policy := range response.Policies {
|
|
285
|
+
for _, repo := range policy.PolicyRepositories {
|
|
286
|
+
key := repo.Owner + "/" + repo.Name
|
|
287
|
+
repoMap[key] = append(repoMap[key], policy)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Save policies for each repository
|
|
292
|
+
cloudStorage := storage.NewCloudPolicyStorage(gitRoot)
|
|
293
|
+
savedCount := 0
|
|
294
|
+
|
|
295
|
+
for repoKey, policies := range repoMap {
|
|
296
|
+
// Extract owner and repo name
|
|
297
|
+
owner := policies[0].PolicyRepositories[0].Owner
|
|
298
|
+
repo := policies[0].PolicyRepositories[0].Name
|
|
299
|
+
|
|
300
|
+
err := cloudStorage.SavePoliciesForRepo(owner, repo, policies)
|
|
301
|
+
if err != nil {
|
|
302
|
+
fmt.Printf(" Warning: Failed to save policies for %s: %v\n", repoKey, err)
|
|
303
|
+
continue
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
savedCount++
|
|
307
|
+
fmt.Printf(" ✓ Saved %d policies for %s\n", len(policies), repoKey)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Save metadata
|
|
311
|
+
orgID := ""
|
|
312
|
+
orgName := ""
|
|
313
|
+
if len(response.Policies) > 0 {
|
|
314
|
+
orgID = response.Policies[0].OrganizationID
|
|
315
|
+
orgName = orgID
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
err = cloudStorage.SaveMetadata(orgID, orgName, response.Total, len(repoMap))
|
|
319
|
+
if err != nil {
|
|
320
|
+
return fmt.Errorf("failed to save metadata: %w", err)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
fmt.Printf("\n✓ Synced %d cloud policies across %d repositories\n", response.Total, savedCount)
|
|
324
|
+
|
|
325
|
+
return nil
|
|
326
|
+
}
|