appydave-tools 0.65.0 → 0.67.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/bin/dam +3 -2
- data/lib/appydave/tools/dam/project_listing.rb +195 -67
- data/lib/appydave/tools/version.rb +1 -1
- data/package.json +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bcb556d99a18280e3339c68e65df1fd7e821c1a55e55e2be9f4a8972ab50f07c
|
|
4
|
+
data.tar.gz: f999edff5d375ce8fc34bc708d3ff2c9e7bb099bf8d8301bc25519411b67e0a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77c0312c15cb033e6c7c23ebe6e2c81b18214b199297e25fd0f030faf8de76d479460a93d700066a1a7e1cc9c560f3d20af3263933a35ab2b409dfc1be37533b
|
|
7
|
+
data.tar.gz: 360c380d91269fc8db5bd7713350aaadce1182e918b5318db52ce7e3744b92d0ecce93e4dc0e36af4e8fbb4e31bdef6c943bda8ccbe2aaff94317d6f5c4cb53b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [0.66.0](https://github.com/appydave/appydave-tools/compare/v0.65.0...v0.66.0) (2025-11-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add --detailed flag to brand list showing PATH, SSD BACKUP, WORKFLOW, and ACTIVE PROJECTS ([e336e58](https://github.com/appydave/appydave-tools/commit/e336e585270305f01295c91c0543075a0e0438ad))
|
|
7
|
+
|
|
8
|
+
# [0.65.0](https://github.com/appydave/appydave-tools/compare/v0.64.0...v0.65.0) (2025-11-22)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add last S3 sync time to brand status showing most recent file in s3-staging folders ([d373b66](https://github.com/appydave/appydave-tools/commit/d373b66e6323521be3d750a9330769fa33b4fed2))
|
|
14
|
+
|
|
1
15
|
# [0.64.0](https://github.com/appydave/appydave-tools/compare/v0.63.0...v0.64.0) (2025-11-22)
|
|
2
16
|
|
|
3
17
|
|
data/bin/dam
CHANGED
|
@@ -129,6 +129,7 @@ class VatCLI
|
|
|
129
129
|
|
|
130
130
|
# List brands and projects
|
|
131
131
|
def list_command(args)
|
|
132
|
+
detailed = args.include?('--detailed')
|
|
132
133
|
args = args.reject { |arg| arg.start_with?('--') || arg.start_with?('-') }
|
|
133
134
|
|
|
134
135
|
brand_arg = args[0]
|
|
@@ -136,13 +137,13 @@ class VatCLI
|
|
|
136
137
|
|
|
137
138
|
if brand_arg.nil?
|
|
138
139
|
# List all brands with summary
|
|
139
|
-
Appydave::Tools::Dam::ProjectListing.list_brands_with_counts
|
|
140
|
+
Appydave::Tools::Dam::ProjectListing.list_brands_with_counts(detailed: detailed)
|
|
140
141
|
elsif pattern_arg
|
|
141
142
|
# Pattern matching
|
|
142
143
|
Appydave::Tools::Dam::ProjectListing.list_with_pattern(brand_arg, pattern_arg)
|
|
143
144
|
else
|
|
144
145
|
# Specific brand
|
|
145
|
-
Appydave::Tools::Dam::ProjectListing.list_brand_projects(brand_arg)
|
|
146
|
+
Appydave::Tools::Dam::ProjectListing.list_brand_projects(brand_arg, detailed: detailed)
|
|
146
147
|
end
|
|
147
148
|
rescue StandardError => e
|
|
148
149
|
puts "❌ Error: #{e.message}"
|
|
@@ -10,7 +10,8 @@ module Appydave
|
|
|
10
10
|
# Project listing functionality for VAT
|
|
11
11
|
class ProjectListing
|
|
12
12
|
# List all brands with summary table
|
|
13
|
-
|
|
13
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
14
|
+
def self.list_brands_with_counts(detailed: false)
|
|
14
15
|
brands = Config.available_brands
|
|
15
16
|
|
|
16
17
|
if brands.empty?
|
|
@@ -19,27 +20,53 @@ module Appydave
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
# Gather brand data
|
|
22
|
-
brand_data = brands.map { |brand| collect_brand_data(brand) }
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
brand_data = brands.map { |brand| collect_brand_data(brand, detailed: detailed) }
|
|
24
|
+
|
|
25
|
+
if detailed
|
|
26
|
+
# Detailed view with additional columns
|
|
27
|
+
header = 'BRAND KEY PROJECTS SIZE LAST MODIFIED ' \
|
|
28
|
+
'GIT S3 SYNC PATH SSD BACKUP ' \
|
|
29
|
+
'WORKFLOW ACTIVE'
|
|
30
|
+
puts header
|
|
31
|
+
puts '-' * 200
|
|
32
|
+
|
|
33
|
+
brand_data.each do |data|
|
|
34
|
+
brand_display = "#{data[:shortcut]} - #{data[:name]}"
|
|
35
|
+
|
|
36
|
+
puts format(
|
|
37
|
+
'%-30s %-12s %10d %12s %20s %-15s %-10s %-35s %-30s %-10s %6d',
|
|
38
|
+
brand_display,
|
|
39
|
+
data[:key],
|
|
40
|
+
data[:count],
|
|
41
|
+
format_size(data[:size]),
|
|
42
|
+
format_date(data[:modified]),
|
|
43
|
+
data[:git_status],
|
|
44
|
+
data[:s3_sync],
|
|
45
|
+
shorten_path(data[:path]),
|
|
46
|
+
data[:ssd_backup] || 'N/A',
|
|
47
|
+
data[:workflow] || 'N/A',
|
|
48
|
+
data[:active_count] || 0
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
# Default view
|
|
53
|
+
puts 'BRAND KEY PROJECTS SIZE LAST MODIFIED GIT S3 SYNC'
|
|
54
|
+
puts '-' * 130
|
|
55
|
+
|
|
56
|
+
brand_data.each do |data|
|
|
57
|
+
brand_display = "#{data[:shortcut]} - #{data[:name]}"
|
|
58
|
+
|
|
59
|
+
puts format(
|
|
60
|
+
'%-30s %-12s %10d %12s %20s %-15s %-10s',
|
|
61
|
+
brand_display,
|
|
62
|
+
data[:key],
|
|
63
|
+
data[:count],
|
|
64
|
+
format_size(data[:size]),
|
|
65
|
+
format_date(data[:modified]),
|
|
66
|
+
data[:git_status],
|
|
67
|
+
data[:s3_sync]
|
|
68
|
+
)
|
|
69
|
+
end
|
|
43
70
|
end
|
|
44
71
|
|
|
45
72
|
# Print footer summary
|
|
@@ -51,9 +78,11 @@ module Appydave
|
|
|
51
78
|
"#{total_projects} project#{'s' if total_projects != 1}, " \
|
|
52
79
|
"#{format_size(total_size)}"
|
|
53
80
|
end
|
|
81
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
54
82
|
|
|
55
83
|
# List all projects for a specific brand (Mode 3)
|
|
56
|
-
|
|
84
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
85
|
+
def self.list_brand_projects(brand_arg, detailed: false)
|
|
57
86
|
# ProjectResolver expects the original brand key/shortcut, not the expanded v-* version
|
|
58
87
|
projects = ProjectResolver.list_projects(brand_arg)
|
|
59
88
|
|
|
@@ -76,58 +105,57 @@ module Appydave
|
|
|
76
105
|
|
|
77
106
|
# Gather project data
|
|
78
107
|
brand_path = Config.brand_path(brand_arg)
|
|
108
|
+
brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand_arg)
|
|
79
109
|
is_git_repo = Dir.exist?(File.join(brand_path, '.git'))
|
|
80
110
|
|
|
81
111
|
project_data = projects.map do |project|
|
|
82
|
-
|
|
83
|
-
size = FileHelper.calculate_directory_size(project_path)
|
|
84
|
-
modified = File.mtime(project_path)
|
|
85
|
-
|
|
86
|
-
# Check if project has uncommitted changes (if brand is git repo)
|
|
87
|
-
git_status = if is_git_repo
|
|
88
|
-
calculate_project_git_status(brand_path, project)
|
|
89
|
-
else
|
|
90
|
-
'N/A'
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Check if project has s3-staging folder
|
|
94
|
-
s3_sync = if Dir.exist?(File.join(project_path, 's3-staging'))
|
|
95
|
-
'✓ staged'
|
|
96
|
-
else
|
|
97
|
-
'none'
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
{
|
|
101
|
-
name: project,
|
|
102
|
-
path: project_path,
|
|
103
|
-
size: size,
|
|
104
|
-
modified: modified,
|
|
105
|
-
age: format_age(modified),
|
|
106
|
-
stale: stale?(modified),
|
|
107
|
-
git_status: git_status,
|
|
108
|
-
s3_sync: s3_sync
|
|
109
|
-
}
|
|
112
|
+
collect_project_data(brand_arg, brand_path, brand_info, project, is_git_repo, detailed: detailed)
|
|
110
113
|
end
|
|
111
114
|
|
|
112
|
-
# Print
|
|
115
|
+
# Print common header
|
|
113
116
|
puts "Projects in #{brand}:"
|
|
114
117
|
puts ''
|
|
115
118
|
puts 'ℹ️ Note: Lists only projects with files, not empty directories'
|
|
116
119
|
puts ''
|
|
117
|
-
puts 'PROJECT SIZE AGE GIT S3'
|
|
118
|
-
puts '-' * 130
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
data[:
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
if detailed
|
|
122
|
+
# Detailed view with additional columns
|
|
123
|
+
header = 'PROJECT SIZE AGE GIT S3 ' \
|
|
124
|
+
'PATH HEAVY FILES LIGHT FILES SSD BACKUP'
|
|
125
|
+
puts header
|
|
126
|
+
puts '-' * 200
|
|
127
|
+
|
|
128
|
+
project_data.each do |data|
|
|
129
|
+
age_display = data[:stale] ? "#{data[:age]} ⚠️" : data[:age]
|
|
130
|
+
puts format(
|
|
131
|
+
'%-45s %12s %15s %-15s %-10s %-35s %-18s %-18s %-30s',
|
|
132
|
+
data[:name],
|
|
133
|
+
format_size(data[:size]),
|
|
134
|
+
age_display,
|
|
135
|
+
data[:git_status],
|
|
136
|
+
data[:s3_sync],
|
|
137
|
+
shorten_path(data[:path]),
|
|
138
|
+
data[:heavy_files] || 'N/A',
|
|
139
|
+
data[:light_files] || 'N/A',
|
|
140
|
+
data[:ssd_backup] || 'N/A'
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
else
|
|
144
|
+
# Default view
|
|
145
|
+
puts 'PROJECT SIZE AGE GIT S3'
|
|
146
|
+
puts '-' * 130
|
|
147
|
+
|
|
148
|
+
project_data.each do |data|
|
|
149
|
+
age_display = data[:stale] ? "#{data[:age]} ⚠️" : data[:age]
|
|
150
|
+
puts format(
|
|
151
|
+
'%-45s %12s %15s %-15s %-10s',
|
|
152
|
+
data[:name],
|
|
153
|
+
format_size(data[:size]),
|
|
154
|
+
age_display,
|
|
155
|
+
data[:git_status],
|
|
156
|
+
data[:s3_sync]
|
|
157
|
+
)
|
|
158
|
+
end
|
|
131
159
|
end
|
|
132
160
|
|
|
133
161
|
# Print footer summary
|
|
@@ -137,8 +165,10 @@ module Appydave
|
|
|
137
165
|
puts ''
|
|
138
166
|
puts "Total: #{project_count} project#{'s' if project_count != 1}, #{format_size(total_size)}"
|
|
139
167
|
end
|
|
168
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
140
169
|
|
|
141
170
|
# List with pattern matching (Mode 3b)
|
|
171
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
142
172
|
def self.list_with_pattern(brand_arg, pattern)
|
|
143
173
|
# ProjectResolver expects the original brand key/shortcut, not the expanded v-* version
|
|
144
174
|
matches = ProjectResolver.resolve_pattern(brand_arg, pattern)
|
|
@@ -201,10 +231,12 @@ module Appydave
|
|
|
201
231
|
puts "Total: #{match_count} project#{'s' if match_count != 1}, #{format_size(total_size)} " \
|
|
202
232
|
"(#{percentage}% of #{brand})"
|
|
203
233
|
end
|
|
234
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
204
235
|
|
|
205
236
|
# Helper methods
|
|
206
237
|
|
|
207
238
|
# Show brand context header with git, S3, and SSD info
|
|
239
|
+
# rubocop:disable Metrics/AbcSize
|
|
208
240
|
def self.show_brand_header(brand_arg, brand)
|
|
209
241
|
Appydave::Tools::Configuration::Config.configure
|
|
210
242
|
brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand_arg)
|
|
@@ -239,9 +271,11 @@ module Appydave
|
|
|
239
271
|
|
|
240
272
|
puts ''
|
|
241
273
|
end
|
|
274
|
+
# rubocop:enable Metrics/AbcSize
|
|
242
275
|
|
|
243
276
|
# Collect brand data for display
|
|
244
|
-
|
|
277
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
278
|
+
def self.collect_brand_data(brand, detailed: false)
|
|
245
279
|
Appydave::Tools::Configuration::Config.configure
|
|
246
280
|
brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand)
|
|
247
281
|
brand_path = Config.brand_path(brand)
|
|
@@ -262,7 +296,7 @@ module Appydave
|
|
|
262
296
|
# Get S3 sync status (count of projects with s3-staging)
|
|
263
297
|
s3_sync_status = calculate_s3_sync_status(brand, projects)
|
|
264
298
|
|
|
265
|
-
{
|
|
299
|
+
result = {
|
|
266
300
|
shortcut: shortcut || key,
|
|
267
301
|
key: key,
|
|
268
302
|
name: name || key.capitalize,
|
|
@@ -273,7 +307,33 @@ module Appydave
|
|
|
273
307
|
git_status: git_status,
|
|
274
308
|
s3_sync: s3_sync_status
|
|
275
309
|
}
|
|
310
|
+
|
|
311
|
+
# Add detailed fields if requested
|
|
312
|
+
if detailed
|
|
313
|
+
# SSD backup path
|
|
314
|
+
ssd_backup = brand_info.locations.ssd_backup
|
|
315
|
+
ssd_backup = nil if ssd_backup.nil? || ssd_backup.empty? || ssd_backup == 'NOT-SET'
|
|
316
|
+
|
|
317
|
+
# Workflow type (inferred from projects_subfolder setting)
|
|
318
|
+
workflow = brand_info.settings.projects_subfolder == 'projects' ? 'storyline' : 'flivideo'
|
|
319
|
+
|
|
320
|
+
# Active project count (projects with flat structure, not archived)
|
|
321
|
+
active_count = projects.count do |project|
|
|
322
|
+
project_path = Config.project_path(brand, project)
|
|
323
|
+
# Check if not in archived/ subfolder
|
|
324
|
+
!project_path.include?('/archived/')
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
result.merge!(
|
|
328
|
+
ssd_backup: ssd_backup ? shorten_path(ssd_backup) : nil,
|
|
329
|
+
workflow: workflow,
|
|
330
|
+
active_count: active_count
|
|
331
|
+
)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
result
|
|
276
335
|
end
|
|
336
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
277
337
|
|
|
278
338
|
# Calculate git status for a brand
|
|
279
339
|
def self.calculate_git_status(brand_path)
|
|
@@ -317,6 +377,74 @@ module Appydave
|
|
|
317
377
|
end
|
|
318
378
|
end
|
|
319
379
|
|
|
380
|
+
# Collect project data for display
|
|
381
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists
|
|
382
|
+
def self.collect_project_data(brand_arg, brand_path, brand_info, project, is_git_repo, detailed: false)
|
|
383
|
+
project_path = Config.project_path(brand_arg, project)
|
|
384
|
+
size = FileHelper.calculate_directory_size(project_path)
|
|
385
|
+
modified = File.mtime(project_path)
|
|
386
|
+
|
|
387
|
+
# Check if project has uncommitted changes (if brand is git repo)
|
|
388
|
+
git_status = if is_git_repo
|
|
389
|
+
calculate_project_git_status(brand_path, project)
|
|
390
|
+
else
|
|
391
|
+
'N/A'
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Check if project has s3-staging folder
|
|
395
|
+
s3_sync = if Dir.exist?(File.join(project_path, 's3-staging'))
|
|
396
|
+
'✓ staged'
|
|
397
|
+
else
|
|
398
|
+
'none'
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
result = {
|
|
402
|
+
name: project,
|
|
403
|
+
path: project_path,
|
|
404
|
+
size: size,
|
|
405
|
+
modified: modified,
|
|
406
|
+
age: format_age(modified),
|
|
407
|
+
stale: stale?(modified),
|
|
408
|
+
git_status: git_status,
|
|
409
|
+
s3_sync: s3_sync
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
# Add detailed fields if requested
|
|
413
|
+
if detailed
|
|
414
|
+
# Heavy files (video files in root)
|
|
415
|
+
heavy_count = 0
|
|
416
|
+
heavy_size = 0
|
|
417
|
+
Dir.glob(File.join(project_path, '*.{mp4,mov,avi,mkv,webm}')).each do |file|
|
|
418
|
+
heavy_count += 1
|
|
419
|
+
heavy_size += File.size(file)
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
# Light files (subtitles, images, metadata)
|
|
423
|
+
light_count = 0
|
|
424
|
+
light_size = 0
|
|
425
|
+
Dir.glob(File.join(project_path, '**/*.{srt,vtt,jpg,png,md,txt,json,yml}')).each do |file|
|
|
426
|
+
light_count += 1
|
|
427
|
+
light_size += File.size(file)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# SSD backup path (if exists)
|
|
431
|
+
ssd_backup = brand_info.locations.ssd_backup
|
|
432
|
+
ssd_path = if ssd_backup && !ssd_backup.empty? && ssd_backup != 'NOT-SET'
|
|
433
|
+
ssd_project_path = File.join(ssd_backup, project)
|
|
434
|
+
File.exist?(ssd_project_path) ? shorten_path(ssd_project_path) : nil
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
result.merge!(
|
|
438
|
+
heavy_files: "#{heavy_count} (#{format_size(heavy_size)})",
|
|
439
|
+
light_files: "#{light_count} (#{format_size(light_size)})",
|
|
440
|
+
ssd_backup: ssd_path
|
|
441
|
+
)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
result
|
|
445
|
+
end
|
|
446
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists
|
|
447
|
+
|
|
320
448
|
# Calculate total size of all projects in a brand
|
|
321
449
|
def self.calculate_total_size(brand, projects)
|
|
322
450
|
projects.sum do |project|
|
data/package.json
CHANGED