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=S05_SYNC_JAVADOC> 032 */ 033@Torello.JavaDoc.StaticFunctional 034public class S05_SyncJavaDoc 035{ 036 // Completely irrelevant, and the 'private' modifier keeps it off of JavaDoc 037 private S05_SyncJavaDoc() { } 038 039 private static final String FS = java.io.File.separator; 040 041 042 // ******************************************************************************************** 043 // ******************************************************************************************** 044 // Copies entire 'javadoc/' directory-tree to GCS 045 // ******************************************************************************************** 046 // ******************************************************************************************** 047 048 049 public static void sync(Builder builder) throws IOException 050 { 051 builder.timers.startStage05(); 052 Printing.startStep(5); 053 054 OSResponse osr = null; 055 StringBuilder logOnly = new StringBuilder(); 056 057 final AppendableSafe logAndScreen = new AppendableSafe( 058 new BiAppendable(System.out, logOnly), 059 AppendableSafe.USE_APPENDABLE_ERROR 060 ); 061 062 // Uses Shell-Contructor: 063 // (outputAppendable, commandStrAppendable, standardOutput, errorOutput) 064 065 // GSUTIL gsutil = new GSUTIL(logOnly, logAndScreen, null, null); 066 builder.cloudSync.initStage05(logOnly, logAndScreen); 067 Shell shell = new Shell(logOnly, logAndScreen, null, null); 068 069 if (! builder.cli.SKIP_REMOVE_GCS_FILES) 070 { 071 // osr = gsutil.RM(builder.cli.GCS_DIR + "javadoc/" + "**"); 072 osr = builder.cloudSync.removeCloudJavaDocDir(); 073 Util.HALT_ON_ERROR(osr); 074 Printing.PLS(logOnly, false); 075 } 076 077 // TRICKY !!! Do not use 'GCS_JAVADOC_DIR' here - because then it will be 078 // 'javadoc/javadoc/!!! 079 080 // osr = gsutil.CP(builder.LOCAL_JAVADOC_DIR, builder.cli.GCS_DIR, "-r"); 081 osr = builder.cloudSync.copyJavaDocDirToCloudDir(); 082 Util.HALT_ON_ERROR(osr); 083 Printing.PLS(logOnly, false); 084 085 osr = shell.RM(builder.LOCAL_JAVADOC_DIR, "-r"); 086 Util.HALT_ON_ERROR(osr); 087 Printing.PLS(logOnly, false); 088 089 if (builder.RUN_MAKE_PUBLIC) 090 { 091 Printing.PLS(logOnly, false); 092 // osr = gsutil.MP(builder.cli.GCS_DIR + "javadoc/**"); 093 osr = builder.cloudSync.makePublicJavaDocDir(); 094 Util.HALT_ON_ERROR(osr); 095 } 096 097 builder.logs.write_S05_LOG(logOnly.toString()); 098 builder.cloudSync.endStage05(); 099 builder.timers.endStage05(); 100 } 101 102 103 // ******************************************************************************************** 104 // ******************************************************************************************** 105 // Copies only selected packages of the Java-Doc Directory to GCS 106 // ******************************************************************************************** 107 // ******************************************************************************************** 108 109 110 static void syncPart(Builder builder) throws IOException 111 { 112 builder.timers.startStage05(); 113 Printing.startStep(5); 114 115 ReadOnlyList<BuildPackage> packageSyncList; 116 117 if (builder.cli.userSpecifiedPackages != null) 118 { 119 packageSyncList = builder.cli.userSpecifiedPackages; 120 121 for (BuildPackage bp : packageSyncList) if (! bp.mustDocument) 122 throw new IllegalArgumentException("Not allowd to document: " + bp.fullName); 123 } 124 125 else packageSyncList = builder.packageList; 126 127 OSResponse osr = null; 128 StringBuilder logOnly = new StringBuilder(); 129 130 final AppendableSafe logAndScreen = new AppendableSafe( 131 new BiAppendable(System.out, logOnly), 132 AppendableSafe.USE_APPENDABLE_ERROR 133 ); 134 135 // Uses Shell-Contructor: 136 // (outputAppendable, commandStrAppendable, standardOutput, errorOutput) 137 138 Shell shell = new Shell(logOnly, logAndScreen, null, null); 139 OSExtras ose = new OSExtras(); 140 141 // GSUTIL gsutil = new GSUTIL(logOnly, logAndScreen, null, null); 142 builder.cloudSync.initStage05(logOnly, logAndScreen); 143 144 Stream.Builder<String> aclCommandB = Stream.builder(); 145 Vector<String> copyDirs = new Vector<>(4); 146 147 for (BuildPackage bp : packageSyncList) 148 { 149 final String PN_FS = 150 builder.LOCAL_JAVADOC_DIR + bp.fullName.replace(".", FS) + FS; 151 152 final String PN_GCS = 153 builder.cli.GCS_DIR + "javadoc/" + bp.fullName.replace('.', '/') + '/'; 154 155 logAndScreen.append("\nCopying Package HTML: " + BYELLOW + bp.fullName + RESET + '\n'); 156 // osr = gsutil.CP(PN_FS + '*', PN_GCS); 157 osr = builder.cloudSync.copySingleJDPackageToCloud(PN_FS, PN_GCS); 158 159 Util.HALT_ON_ERROR(osr); 160 161 // The GSUTIL.MP (Make-Public) Command is called once at the very end. 162 aclCommandB.accept(PN_GCS + '*'); 163 164 // Empty out the previous calls stuff 165 copyDirs.clear(); 166 167 if (new java.io.File(PN_FS + "doc-files" + FS).exists()) 168 { 169 copyDirs.add("doc-files" + FS); 170 aclCommandB.accept(PN_GCS + "doc-files" + FS + "**"); 171 } 172 173 if (new java.io.File(PN_FS + "hilite-files" + FS).exists()) 174 { 175 copyDirs.add("hilite-files" + FS); 176 aclCommandB.accept(PN_GCS + "hilite-files" + FS + "**"); 177 } 178 179 if (new java.io.File(PN_FS + "stylesheets" + FS).exists()) 180 { 181 copyDirs.add("stylesheets" + FS); 182 aclCommandB.accept(PN_GCS + "stylesheets" + FS + "**"); 183 } 184 185 ose.currentWorkingDirectory = new File(PN_FS); 186 // gsutil.osExtras = ose; 187 188 logAndScreen.append( 189 "\nOSExtras.currentWorkingDirectory was assigned: " + 190 BYELLOW + PN_FS + RESET + '\n' 191 ); 192 193 // osr = gsutil.CP(copyDirs, PN_GCS, "-r"); 194 builder.cloudSync.copyOtherPackageDirsToCloudDir(ose, copyDirs, PN_GCS); 195 Util.HALT_ON_ERROR(osr); 196 } 197 198 String[] makePublicArr = aclCommandB.build().toArray(String[]::new); 199 200 // My Cute little hack for the day. This will make Stage 8 a lot faster. 201 // Well, this isn't considered a hack anymore, because it works pretty well. 202 // 203 // NOTE: Even if "Make-Public" isn't executed on a directory because that GCP Bucket 204 // directory has been assigned "Bucket-Level Permissions", it will stll be necessary 205 // to run the "Set Max Age" (Stage 8 Stuff), if the user has requested it! Therefore 206 // we cannot just 'discard' the 'makePublicArr' when RUN_MAKE_PUBLIC is false. 207 208 builder.stage8GCSDirs = makePublicArr; 209 210 // REMEMBER: if this is ever invoked on a bucket that has bucket-level 211 // permissions, instead of object level permissions, THIS WOULD CRASH. 212 // 213 // NOTE: the content of the 'aclCommandB' Stream.Builder are just wholly ignored and 214 // discarded (eventually), by the garbage-collector if the Storage-Bucket has been 215 // assigned Bucket-Level permissions instead of Object-Level Permissions. 216 217 if (builder.RUN_MAKE_PUBLIC) 218 { 219 // Print these so they are legible 220 logAndScreen.append(BGREEN + "\nMake Copied Files Public:\n\n" + RESET); 221 for (String gcsDir : makePublicArr) logAndScreen.append('\t' + gcsDir + "\n"); 222 logAndScreen.append('\n'); 223 224 // Now do the actual "Make Public" Command 225 // osr = gsutil.MP(makePublicArr); 226 osr = builder.cloudSync.makePublicDirArr(makePublicArr); 227 Util.HALT_ON_ERROR(osr); 228 } 229 230 logAndScreen.append(BGREEN + "\nClean Up:\n" + RESET); 231 osr = shell.RM(builder.LOCAL_JAVADOC_DIR, "-r"); 232 Util.HALT_ON_ERROR(osr); 233 234 builder.logs.write_S05_LOG(logOnly.toString()); 235 builder.cloudSync.endStage05(); 236 builder.timers.endStage05(); 237 } 238}