@@ -29,7 +29,7 @@ def digest(data):
2929
3030def read_url (url , allow_absent = False ):
3131 try :
32- request = Request (url , headers = {"User-Agent" : "MMD-Maven-Release/1.0" })
32+ request = Request (url , headers = {"User-Agent" : "MMD-Maven-Release/1.0" , "Cache-Control" : "no-cache" })
3333 with urlopen (request , timeout = 30 ) as response :
3434 require (response .status == 200 , f"Unexpected HTTP status for { url } " )
3535 return response .read ()
@@ -91,26 +91,39 @@ def jar_names(manifest, version):
9191 return [stem + suffix for suffix in (".jar" , "-sources.jar" , "-javadoc.jar" )]
9292
9393
94+ def pom_digest (data ):
95+ # Gradle writes native line endings. Jar checks always use the exact bytes.
96+ return digest (data .replace (b"\r \n " , b"\n " ))
97+
98+
9499def destination_state (manifest , version , release , work , verify_metadata = False ):
95100 jars = jar_names (manifest , version )
96101 sums = json .loads ((work / "verified.json" ).read_text (encoding = "ascii" ))
97102 require (sums [jars [0 ]] == release ["mainSha256" ], "Prepared release does not match the manifest" )
98103 pom = jars [0 ].removesuffix (".jar" ) + ".pom"
99- sums [pom ] = digest ((work / "gradle/publications/mavenJava/pom-default.xml" ).read_bytes ())
104+ sums [pom ] = pom_digest ((work / "gradle/publications/mavenJava/pom-default.xml" ).read_bytes ())
100105 directory = f"{ MAVEN } /{ manifest ['groupId' ].replace ('.' , '/' )} /{ manifest ['artifactId' ]} "
101106 present = 0
102107 for name , sha in sums .items ():
103108 if name in jars :
104109 require (digest ((work / name ).read_bytes ()) == sha , f"Prepared file changed: { name } " )
105110 remote = read_url (f"{ directory } /{ version } /{ name } " , allow_absent = True )
106111 if remote is not None :
107- require (digest (remote ) == sha , f"Maven already contains different bytes: { name } " )
112+ actual = pom_digest (remote ) if name == pom else digest (remote )
113+ require (actual == sha , f"Maven already contains different bytes: { name } " )
108114 present += 1
109- require (present in (0 , len (sums )), "Maven version is partially populated; refusing automatic overwrite" )
110- if verify_metadata and present :
111- metadata = ElementTree .fromstring (read_url (f"{ directory } /maven-metadata.xml" ))
112- require (version in [node .text for node in metadata .findall ("versioning/versions/version" )],
113- "Published version is missing from Maven metadata" )
115+ if verify_metadata :
116+ # After a successful write, a public cache can expose only part of the release.
117+ # This path only reads; preflight still refuses to write to a partial version.
118+ if present != len (sums ):
119+ return "pending"
120+ document = read_url (f"{ directory } /maven-metadata.xml" , allow_absent = True )
121+ if document is None or version not in [
122+ node .text for node in ElementTree .fromstring (document ).findall ("versioning/versions/version" )
123+ ]:
124+ return "pending"
125+ else :
126+ require (present in (0 , len (sums )), "Maven version is partially populated; refusing automatic overwrite" )
114127 return "present" if present else "absent"
115128
116129
@@ -126,7 +139,7 @@ def main():
126139 require (mode == "check" or state == "absent" , "Destination is not empty" )
127140 print (state )
128141 elif mode == "verify" :
129- for delay in (0 , 2 , 5 , 10 ):
142+ for delay in (0 , 2 , 5 , 10 , 20 , 30 ):
130143 time .sleep (delay )
131144 if destination_state (manifest , version , release , work , verify_metadata = True ) == "present" :
132145 print (f"MMD Maven verified: { manifest ['groupId' ]} :{ manifest ['artifactId' ]} :{ version } " )
0 commit comments