11using System ;
22using System . Collections . Generic ;
3+ using System . IO ;
34using System . Linq ;
5+ using Newtonsoft . Json ;
46using Yuka . Cli . Util ;
57using Yuka . IO ;
68
@@ -13,7 +15,7 @@ public CopyCommand(CommandParameters parameters) : base(parameters) {
1315
1416 public override string [ ] Description => new [ ] {
1517 "Copies files from one place to another while optionally converting them in some way." ,
16- "\a acopy \a - forms the basis of most other commands ."
18+ "Most other commands use copy internally ."
1719 } ;
1820
1921 public override ( string syntax , string description ) [ ] Usage => new [ ] {
@@ -25,20 +27,23 @@ public override (string syntax, string description)[] Usage => new[] {
2527
2628 // reminder: when changing these, also change all inheriting classes
2729 public override ( char shorthand , string name , string fallback , string description ) [ ] Flags => new [ ] {
28- ( 's' , "source" , null , "Source location" ) ,
29- ( 'd' , "destination" , null , "Destination location" ) ,
30- ( 'f' , "format" , "keep" , "The preferred output format (valid values: \a bkeep\a -, \a bpacked\a -, \a bunpacked\a -)" ) ,
31- ( 'r' , "raw" , null , "Short form of \a c--format=keep\a -, overwrites the format flag if set" ) ,
32- ( 'm' , "move" , "false" , "Delete each fileName after successfully copying it" ) ,
33- ( 'o' , "overwrite" , "false" , "Delete existing destination archive/folder" ) ,
34- ( 'q' , "quiet" , null , "Disable user-friendly output" ) ,
35- ( 'v' , "verbose" , null , "Whether to enable detailed output" ) ,
36- ( 'w' , "wait" , null , "Whether to wait after the command finished" )
30+ ( 's' , "source" , null , "Source location" ) ,
31+ ( 'd' , "destination" , null , "Destination location" ) ,
32+ ( 'f' , "format" , "keep" , "The preferred output format (valid values: \a bkeep\a -, \a bpacked\a -, \a bunpacked\a -)" ) ,
33+ ( 'r' , "raw" , null , "Short form of \a c--format=keep\a -, overwrites the format flag if set" ) ,
34+ ( 'm' , "move" , "false" , "Delete each fileName after successfully copying it" ) ,
35+ ( ' ' , "manifest" , "false" , "Generate a manifest file" ) ,
36+ ( 'i' , "ignoremanifest" , "false" , "Ignore the manifest, if it exists" ) ,
37+ ( 'o' , "overwrite" , "false" , "Delete existing destination archive/folder" ) ,
38+ ( 'q' , "quiet" , null , "Disable user-friendly output" ) ,
39+ ( 'v' , "verbose" , null , "Whether to enable detailed output" ) ,
40+ ( 'w' , "wait" , null , "Whether to wait after the command finished" )
3741 } ;
3842
3943 // copy modes
4044 protected FormatType _prefererredFormatType ;
41- protected bool _rawCopy , _deleteAfterCopy , _overwriteExisting ;
45+ protected bool _rawCopy , _deleteAfterCopy , _overwriteExisting , _generateManifest , _ignoreManifest ;
46+ protected Manifest _inputManifest ;
4247
4348 public override bool Execute ( ) {
4449 try {
@@ -47,8 +52,10 @@ public override bool Execute() {
4752
4853 CheckPaths ( sourcePath , destinationPath ) ;
4954
50- int fileCount ;
55+ Manifest outputManifest ;
5156 using ( var sourceFs = FileSystem . OpenExisting ( sourcePath ) ) {
57+ _inputManifest = _ignoreManifest ? null : ReadManifest ( sourceFs ) ;
58+
5259 using ( var destinationFs = FileSystem . OpenOrCreate ( destinationPath , sourceFs is SingleFileSystem , _overwriteExisting ) ) {
5360 // collect files
5461 var files = new List < string > ( ) ;
@@ -57,11 +64,12 @@ public override bool Execute() {
5764 }
5865
5966 // call copy loop
60- fileCount = CopyFiles ( sourceFs , destinationFs , files . Distinct ( ) , _rawCopy , _deleteAfterCopy ) ;
67+ outputManifest = CopyFiles ( sourceFs , destinationFs , files . Distinct ( ) , _rawCopy , _deleteAfterCopy ) ;
68+ if ( _generateManifest ) WriteManifest ( outputManifest , destinationFs ) ;
6169 }
6270 }
6371
64- Success ( $ "Successfully copied { fileCount } files") ;
72+ Success ( $ "Successfully copied { outputManifest . Count } files") ;
6573 }
6674 catch ( Exception e ) when ( ! System . Diagnostics . Debugger . IsAttached ) {
6775 Error ( $ "{ e . GetType ( ) . Name } : { e . Message } ") ;
@@ -71,6 +79,19 @@ public override bool Execute() {
7179 return true ;
7280 }
7381
82+ protected virtual void WriteManifest ( Manifest manifest , FileSystem fs ) {
83+ using ( var writer = new JsonTextWriter ( new StreamWriter ( fs . CreateFile ( ".manifest" ) ) ) ) {
84+ new JsonSerializer { Formatting = Formatting . Indented } . Serialize ( writer , manifest ) ;
85+ }
86+ }
87+
88+ protected virtual Manifest ReadManifest ( FileSystem fs ) {
89+ if ( ! fs . FileExists ( ".manifest" ) ) return null ;
90+ using ( var reader = new JsonTextReader ( new StreamReader ( fs . OpenFile ( ".manifest" ) ) ) ) {
91+ return new JsonSerializer { Formatting = Formatting . Indented } . Deserialize < Manifest > ( reader ) ;
92+ }
93+ }
94+
7495 protected virtual ( string sourcePath , string destinationPath , string [ ] filters ) GetPaths ( ) {
7596 string sourcePath , destinationPath ;
7697 string [ ] filters = { "*.*" } ;
@@ -118,6 +139,8 @@ protected virtual void SetCopyModes() {
118139 string format = Parameters . GetString ( "format" , 'f' , FormatTypeFallback ) . ToLower ( ) ;
119140 _rawCopy = Parameters . GetBool ( "raw" , 'r' , false ) ;
120141 _deleteAfterCopy = Parameters . GetBool ( "move" , 'm' , false ) ;
142+ _generateManifest = Parameters . GetBool ( "manifest" , false ) ;
143+ _ignoreManifest = Parameters . GetBool ( "ignoremanifest" , 'i' , false ) ;
121144 _overwriteExisting = Parameters . GetBool ( "overwrite" , 'o' , false ) ;
122145
123146 switch ( format ) {
@@ -139,46 +162,67 @@ protected virtual void SetCopyModes() {
139162 }
140163
141164 protected virtual FormatPreference GetOutputFormat ( object obj , string fileName , Format fileFormat ) {
165+ if ( _inputManifest != null ) {
166+ foreach ( var ( source , target ) in _inputManifest ) {
167+ // find the entry that produced this file
168+ if ( target . Any ( pair => pair . Name == fileName ) ) {
169+ // return the original format
170+ return new FormatPreference ( source [ 0 ] . Format , _prefererredFormatType ) ;
171+ }
172+ }
173+ }
142174 return new FormatPreference ( null , _prefererredFormatType ) ;
143175 }
144176
145- protected virtual ( object obj , Format fileFormat ) ReadFile ( FileSystem sourceFs , string fileName ) {
146- return FileReader . DecodeObject ( fileName , sourceFs , true ) ;
177+ protected virtual ( object obj , Format fileFormat ) ReadFile ( FileSystem sourceFs , string fileName , FileList files ) {
178+ return FileReader . DecodeObject ( fileName , sourceFs , files , true ) ;
147179 }
148180
149- protected virtual Format WriteFile ( object obj , Format inputFormat , FileSystem destinationFs , string fileName ) {
150- return FileWriter . EncodeObject ( obj , fileName , destinationFs , GetOutputFormat ( obj , fileName , inputFormat ) ) ;
181+ protected virtual void WriteFile ( object obj , Format inputFormat , FileSystem destinationFs , string fileName , FileList files ) {
182+ FileWriter . EncodeObject ( obj , fileName , destinationFs , GetOutputFormat ( obj , fileName , inputFormat ) , files ) ;
151183 }
152184
153- protected virtual int CopyFiles ( FileSystem sourceFs , FileSystem destinationFs , IEnumerable < string > files , bool rawCopy , bool deleteAfterCopy ) {
185+ protected virtual Manifest CopyFiles ( FileSystem sourceFs , FileSystem destinationFs , IEnumerable < string > files , bool rawCopy , bool deleteAfterCopy ) {
154186 bool verbose = Parameters . GetBool ( "verbose" , 'v' , false ) ;
155- int fileCount = 0 ;
187+
188+ var manifest = new Manifest ( ) ;
156189
157190 // main loop
158191 foreach ( string fileName in files ) {
192+ if ( fileName == ".manifest" ) continue ;
193+
159194 if ( rawCopy ) {
160195 Log ( $ "Copying \a e{ fileName } ") ;
161196 using ( var sourceStream = sourceFs . OpenFile ( fileName ) ) {
162197 using ( var destinationStream = destinationFs . CreateFile ( fileName ) ) {
163198 sourceStream . CopyTo ( destinationStream ) ;
164- fileCount ++ ;
199+
200+ manifest . Add (
201+ new FileList { ( fileName , Format . Raw ) } ,
202+ new FileList { ( fileName , Format . Raw ) }
203+ ) ;
165204 }
166205 }
167206 }
168207 else {
169208
170- var ( obj , fileFormat ) = ReadFile ( sourceFs , fileName ) ;
209+ var readFiles = new FileList ( ) ;
210+ var writtenFiles = new FileList ( ) ;
211+
212+ var ( obj , fileFormat ) = ReadFile ( sourceFs , fileName , readFiles ) ;
171213
172214 if ( obj == null ) {
173- if ( verbose ) Output . WriteLine ( $ "Skipping { fileName } ", ConsoleColor . Yellow ) ;
215+ // if(verbose) Output.WriteLine($"Skipping {fileName}", ConsoleColor.Yellow);
174216 continue ;
175217 }
218+ //if(verbose) Output.WriteLine($"Processing {fileName}", ConsoleColor.Yellow);
176219
177- Log ( $ "Decoded \ a e{ fileName } \a - to \a b{ obj . GetType ( ) . Name } ") ;
220+ Log ( $ "Decoded [ { string . Join ( ", " , readFiles . Select ( pair => $ " \a b { pair . Format . Name } \ a e{ pair . Name } \a -" ) ) } ] to \a b{ obj . GetType ( ) . Name } ") ;
178221
179- var outputFormat = WriteFile ( obj , fileFormat , destinationFs , fileName ) ;
222+ WriteFile ( obj , fileFormat , destinationFs , fileName , writtenFiles ) ;
180223
181- Log ( $ "Encoded \a b{ obj . GetType ( ) . Name } \a - ({ outputFormat . GetType ( ) . Name } )") ;
224+ Log ( $ "Encoded [{ string . Join ( ", " , writtenFiles . Select ( pair => $ "\a b{ pair . Format . Name } \a e{ pair . Name } \a -") ) } ]") ;
225+ Log ( "" ) ;
182226
183227 if ( deleteAfterCopy ) {
184228 // delete auxiliary files (csv, frm, ani, etc...)
@@ -191,11 +235,11 @@ protected virtual int CopyFiles(FileSystem sourceFs, FileSystem destinationFs, I
191235 sourceFs . DeleteFile ( fileName ) ;
192236 }
193237
194- fileCount ++ ;
238+ manifest . Add ( readFiles , writtenFiles ) ;
195239 }
196240 }
197241
198- return fileCount ;
242+ return manifest ;
199243 }
200244 }
201245}
0 commit comments