001package Torello.Java.Build; 002 003import Torello.Java.ReadOnly.ReadOnlyList; 004 005import Torello.Java.Shell; 006import Torello.Java.GSUTIL; 007import Torello.Java.OSResponse; 008import Torello.Java.OSExtras; 009import Torello.Java.StringParse; 010 011import Torello.Java.Additional.BiAppendable; 012import Torello.Java.Additional.AppendableSafe; 013 014import static Torello.Java.C.BYELLOW; 015import static Torello.Java.C.BGREEN; 016import static Torello.Java.C.RESET; 017 018import java.io.File; 019import java.io.IOException; 020import java.util.Vector; 021import java.util.stream.Stream; 022 023/** 024 * This is the fifth Build-Stage, and it is part of the synchronization of a project with Google 025 * Cloud Platform Stroage Buckets. This class relies heavily on the GCP Shell-Command 026 * {@code 'gsutil'} and it's Java implementation - {@link GSUTIL Torello.Java.GSUTIL}. 027 * 028 * <BR /><BR />This class' synchronization-efforts entail copying the File-System's Java-Doc 029 * Directory-Contents onto the (User-Specified) Google Cloud Server Storage-Bucket. 030 * 031 * <EMBED CLASS=external-html DATA-FILE-ID=STAGE_PRIVATE_NOTE> 032 * <EMBED CLASS='external-html' DATA-FILE-ID=S05_SYNC_JAVADOC> 033 */ 034@Torello.JavaDoc.StaticFunctional 035public class S05_SyncJavaDoc 036{ 037 // Completely irrelevant, and the 'private' modifier keeps it off of JavaDoc 038 private S05_SyncJavaDoc() { } 039 040 private static final String FS = java.io.File.separator; 041 042 043 // ******************************************************************************************** 044 // ******************************************************************************************** 045 // Copies entire 'javadoc/' directory-tree to GCS 046 // ******************************************************************************************** 047 // ******************************************************************************************** 048 049 050 public static void sync(final BuilderRecord brec) throws IOException 051 { 052 brec.timers.startStage05(); 053 Printing.startStep(5); 054 055 OSResponse osr = null; 056 StringBuilder logOnly = new StringBuilder(); 057 058 final AppendableSafe logAndScreen = new AppendableSafe( 059 new BiAppendable(System.out, logOnly), 060 AppendableSafe.USE_APPENDABLE_ERROR 061 ); 062 063 // Uses Shell-Contructor: 064 // (outputAppendable, commandStrAppendable, standardOutput, errorOutput) 065 066 // GSUTIL gsutil = new GSUTIL(logOnly, logAndScreen, null, null); 067 brec.cloudSync.initStage(logOnly, logAndScreen); 068 Shell shell = new Shell(logOnly, logAndScreen, null, null); 069 070 // Data-Record Explanation: 071 // 072 // brec: BuilderRecord - Top-of-Tree Data-Record for executing a build, Contains everything 073 // cli: (Command-Line-Interface) - All info gathered from user-input to "String[] argv" 074 // aor: Auxiliary-Options Record - A Record containing only final / constant booleans, 075 // whose values are all exactly equal to whether or not each of the 6 or 7 Auxiliary 076 // options were passed, by the user, to "String[] argv" at the command line. 077 078 if (! brec.cli.aor.SKIP_REMOVE_GCS_FILES_SWITCH) 079 { 080 // osr = gsutil.RM(brec.cli.GCS_DIR + "javadoc/" + "**"); 081 osr = brec.cloudSync.removeCloudJavaDocDir(); 082 Util.HALT_ON_ERROR(osr); 083 Printing.PLS(logOnly, false); 084 } 085 086 // TRICKY !!! Do not use 'GCS_JAVADOC_DIR' here - because then it will be 087 // 'javadoc/javadoc/!!! 088 089 // osr = gsutil.CP(brec.LOCAL_JAVADOC_DIR, brec.cli.GCS_DIR, "-r"); 090 osr = brec.cloudSync.copyJavaDocDirToCloudDir(); 091 Util.HALT_ON_ERROR(osr); 092 Printing.PLS(logOnly, false); 093 094 osr = shell.RM(brec.LOCAL_JAVADOC_DIR, "-r"); 095 Util.HALT_ON_ERROR(osr); 096 Printing.PLS(logOnly, false); 097 098 // if (brec.RUN_MAKE_PUBLIC) 099 if (brec.cloudSync.shouldRunMakePublic) 100 { 101 Printing.PLS(logOnly, false); 102 // osr = gsutil.MP(brec.cli.GCS_DIR + "javadoc/**"); 103 osr = brec.cloudSync.makePublicJavaDocDir(); 104 Util.HALT_ON_ERROR(osr); 105 } 106 107 brec.logs.write_S05_LOG(logOnly.toString()); 108 brec.cloudSync.endStage(); 109 brec.timers.endStage05(); 110 } 111 112 113 // ******************************************************************************************** 114 // ******************************************************************************************** 115 // Copies only selected packages of the Java-Doc Directory to GCS 116 // ******************************************************************************************** 117 // ******************************************************************************************** 118 119 120 static void syncPart(final BuilderRecord brec) throws IOException 121 { 122 brec.timers.startStage05(); 123 Printing.startStep(5); 124 125 OSResponse osr = null; 126 StringBuilder logOnly = new StringBuilder(); 127 128 final AppendableSafe logAndScreen = new AppendableSafe( 129 new BiAppendable(System.out, logOnly), 130 AppendableSafe.USE_APPENDABLE_ERROR 131 ); 132 133 // Uses Shell-Contructor: 134 // (outputAppendable, commandStrAppendable, standardOutput, errorOutput) 135 136 Shell shell = new Shell(logOnly, logAndScreen, null, null); 137 OSExtras ose = new OSExtras(); 138 139 // GSUTIL gsutil = new GSUTIL(logOnly, logAndScreen, null, null); 140 brec.cloudSync.initStage(logOnly, logAndScreen); 141 142 Stream.Builder<String> aclCommandB = Stream.builder(); 143 Vector<String> copyDirs = new Vector<>(4); 144 145 146 // brec: class BuilderRecord 147 // cli: class CLI 148 // aor: class AuxiliaryOptRecord 149 150 for (BuildPackage bp : brec.cli.sor.userSpecifiedPackages) 151 { 152 final String pkgRootLocalDir = 153 brec.LOCAL_JAVADOC_DIR + bp.fullName.replace(".", FS) + FS; 154 155 final String pkgRootCloudDir = 156 157 // brec.cli.GCS_DIR + "javadoc/" + bp.fullName.replace('.', '/') + '/'; 158 // 159 // TO-DO: When I am capable of holding this inside my brain, I need to revisit 160 // this line. For now, I simply cannot think - and I'm trying to get this 161 // B.S. to compile. The current plan is to only run "syncAll" and not 162 // "syncPart". I will worry about this very soon, just not right now. 163 // NOTE THE ORIGINAL LINE OF CODE IS DIRECTLY ABOVE, COMMENTED OUT. 164 // 165 // Not sure brec.cloudSync 166 167 brec.cloudSync.cloudRootStorageDir + 168 "javadoc/" + bp.fullName.replace('.', '/') + '/'; 169 170 logAndScreen.append("\nCopying Package HTML: " + BYELLOW + bp.fullName + RESET + '\n'); 171 // osr = gsutil.CP(pkgRootLocalDir + '*', pkgRootCloudDir); 172 osr = brec.cloudSync.copySingleJDPackageToCloud 173 (pkgRootLocalDir, pkgRootCloudDir); 174 175 Util.HALT_ON_ERROR(osr); 176 177 // The GSUTIL.MP (Make-Public) Command is called once at the very end. 178 aclCommandB.accept(pkgRootCloudDir + '*'); 179 180 // Empty out the previous calls stuff 181 copyDirs.clear(); 182 183 if (new java.io.File(pkgRootLocalDir + "doc-files" + FS).exists()) 184 { 185 copyDirs.add("doc-files" + FS); 186 aclCommandB.accept(pkgRootCloudDir + "doc-files" + FS + "**"); 187 } 188 189 if (new java.io.File(pkgRootLocalDir + "hilite-files" + FS).exists()) 190 { 191 copyDirs.add("hilite-files" + FS); 192 aclCommandB.accept(pkgRootCloudDir + "hilite-files" + FS + "**"); 193 } 194 195 if (new java.io.File(pkgRootLocalDir + "stylesheets" + FS).exists()) 196 { 197 copyDirs.add("stylesheets" + FS); 198 aclCommandB.accept(pkgRootCloudDir + "stylesheets" + FS + "**"); 199 } 200 201 202 // This part (this 'if' statement) is a litte weird. 203 // If there are no 'doc-files/', 'stylesheets/' or 'hilite-files/' the next few lines 204 // will CRASH the BUILD. However, there should always be 'hilite-files/', so the 205 // following check should always get a PASS! 206 // 207 // I'm going to leave this check here, for now. This error was discovered when trying 208 // to figure out the source of a different bug. Because it is possible for a user to 209 // actually "turn off" the "HiLite Source" feature for an entire package - this check 210 // isn't actually a complete joke. I never turned of Hi-Lite Files, since that's the 211 // main thing this Upgrader does! Anyway, if such a decision by the user were made, 212 // then this 'if-statement' is very important... OK? :) Have a nice day. 213 // 214 // By the way, it's also possible for this list to empty because there were no 215 // no 'hilite-files/' due to a bug in the CLI-Processing for the "Partial-Build's" 216 // Menu-Options Package-Lists... Specifically if a package were included in the list, 217 // but the Ugprader hadn't been run on that package, then this specific list right here 218 // (directly below) would, indeed, be empty. That's the bug that was just fixed a 219 // moment ago. (TL;DR: If you try to "Synchronize a Package" that wasn't upgraded by 220 // the Upgrader, It's very likely it won't have any of these "Copy-Dirs" either). The 221 // Upgrader will **ALWAYS** at least add a 'hilite-files/' directory, unless that 222 // features was explicitly requested to be turned off by the user. 223 224 if (copyDirs.size() == 0) continue; 225 226 227 // This is the culmination of quite a bit of playing with the OSCommands class 228 // to allow a user to execute / run an external OS-Call (an external program) 229 // as if it had been invoked inside of some other directory that the in which 230 // the original Java-VM / JRE had been invoked. 231 232 ose.currentWorkingDirectory = new File(pkgRootLocalDir); 233 234 logAndScreen.append( 235 "\nOSExtras.currentWorkingDirectory was assigned: " + 236 BYELLOW + pkgRootLocalDir + RESET + '\n' 237 ); 238 239 240 // ORIGINAL: 241 // osr = gsutil.CP(copyDirs, pkgRootCloudDir, "-r"); 242 // 243 // TO-DO PART 2: I am incapable of analyzing this right now. I just want it to compile 244 // and build at the moment. I hate breaking my build, and that is what I 245 // I have just done. When the Build itself won't work, that is when 246 // I get really aggrivated 247 // 248 // THERE ARE ONLY TWO LINES THAT NEED REAL FIXING. 249 // BOTH OF THEM ARE IN THIS FILE. 250 // 251 // OK, I SOLVED THE PROBLEM - HOWEVER, THE REIGNING SOLUTION DOES NOT EXTEND TO THE 252 // SCENARIO WHERE I STOP USING "GSUTIL" AND START ALLOWING "RCLONE" OR SOME KIND OF 253 // "S3". 254 // 255 // Currently, "SyncPart" is a GSUTIL only method. And since Torello.Java.Build is 256 // just impossible for me to think about for very long. I am going to stop this for a 257 // few weeks, and it is now going to be time to finish JavaDoc.Upgrade... 258 // 259 // "syncPart" works, but only with the GSUTILCloudSync version. However since I have 260 // not written S3CloudSync, or RCloneCloudSync - I'm just not going to worry about it 261 // right now. Build is true madness is what it usually feels like. It is nothing but 262 // a long, long, LONG list of configurations, settings, and choices that are supposed 263 // to all be controllable from a simple CLI-argv String...-Array thing. 264 265 osr = brec.cloudSync.copyOtherPackageDirsToCloudDir 266 (ose, copyDirs, pkgRootCloudDir); 267 268 Util.HALT_ON_ERROR(osr); 269 } 270 271 String[] makePublicArr = aclCommandB.build().toArray(String[]::new); 272 273 274 // My Cute little hack for the day. This will make Stage 8 a lot faster. 275 // Well, this isn't considered a hack anymore, because it works pretty well. 276 // 277 // NOTE: Even if "Make-Public" isn't executed on a directory because that GCP Bucket 278 // directory has been assigned "Bucket-Level Permissions", it will stll be necessary 279 // to run the "Set Max Age" (Stage 8 Stuff), if the user has requested it! Therefore 280 // we cannot just 'discard' the 'makePublicArr' when RUN_MAKE_PUBLIC is false. 281 282 brec.stage8GCSDirs = makePublicArr; 283 284 285 // REMEMBER: if this is ever invoked on a bucket that has bucket-level 286 // permissions, instead of object level permissions, THIS WOULD CRASH. 287 // 288 // NOTE: the content of the 'aclCommandB' Stream.Builder are just wholly ignored and 289 // discarded (eventually), by the garbage-collector if the Storage-Bucket has been 290 // assigned Bucket-Level permissions instead of Object-Level Permissions. 291 292 // if (brec.RUN_MAKE_PUBLIC) 293 if (brec.cloudSync.shouldRunMakePublic) 294 { 295 // Print these so they are legible 296 logAndScreen.append(BGREEN + "\nMake Copied Files Public:\n\n" + RESET); 297 for (String gcsDir : makePublicArr) logAndScreen.append('\t' + gcsDir + "\n"); 298 logAndScreen.append('\n'); 299 300 // Now do the actual "Make Public" Command 301 // osr = gsutil.MP(makePublicArr); 302 303 osr = brec.cloudSync.makePublicDirArr(makePublicArr); 304 Util.HALT_ON_ERROR(osr); 305 } 306 307 logAndScreen.append(BGREEN + "\nClean Up:\n" + RESET); 308 osr = shell.RM(brec.LOCAL_JAVADOC_DIR, "-r"); 309 Util.HALT_ON_ERROR(osr); 310 311 brec.logs.write_S05_LOG(logOnly.toString()); 312 brec.cloudSync.endStage(); 313 brec.timers.endStage05(); 314 } 315}