11use std:: env;
2- use std:: fs:: { self , File } ;
3- use std:: io:: { self , BufReader } ;
2+ use std:: fs;
3+ use std:: io;
44use std:: path:: PathBuf ;
55
6- use flate2:: write:: GzEncoder ;
7- use flate2:: Compression ;
8-
96fn main ( ) {
107 println ! ( "cargo:rerun-if-changed=versions.env" ) ;
118
@@ -15,9 +12,6 @@ fn main() {
1512 let mut pgvector_version = String :: new ( ) ;
1613 let mut pgvector_tag = String :: new ( ) ;
1714 let mut pgvector_repo = String :: new ( ) ;
18- let mut pgbouncer_version = String :: new ( ) ;
19- let mut pgbouncer_tag = String :: new ( ) ;
20- let mut pgbouncer_repo = String :: new ( ) ;
2115
2216 for line in versions_env. lines ( ) {
2317 let line = line. trim ( ) ;
@@ -30,9 +24,6 @@ fn main() {
3024 "PGVECTOR_VERSION" => pgvector_version = value. trim ( ) . to_string ( ) ,
3125 "PGVECTOR_COMPILED_TAG" => pgvector_tag = value. trim ( ) . to_string ( ) ,
3226 "PGVECTOR_COMPILED_REPO" => pgvector_repo = value. trim ( ) . to_string ( ) ,
33- "PGBOUNCER_VERSION" => pgbouncer_version = value. trim ( ) . to_string ( ) ,
34- "PGBOUNCER_COMPILED_TAG" => pgbouncer_tag = value. trim ( ) . to_string ( ) ,
35- "PGBOUNCER_COMPILED_REPO" => pgbouncer_repo = value. trim ( ) . to_string ( ) ,
3627 _ => { }
3728 }
3829 }
@@ -42,16 +33,12 @@ fn main() {
4233 println ! ( "cargo:rustc-env=PGVECTOR_VERSION={}" , pgvector_version) ;
4334 println ! ( "cargo:rustc-env=PGVECTOR_COMPILED_TAG={}" , pgvector_tag) ;
4435 println ! ( "cargo:rustc-env=PGVECTOR_COMPILED_REPO={}" , pgvector_repo) ;
45- println ! ( "cargo:rustc-env=PGBOUNCER_VERSION={}" , pgbouncer_version) ;
46- println ! ( "cargo:rustc-env=PGBOUNCER_COMPILED_TAG={}" , pgbouncer_tag) ;
47- println ! ( "cargo:rustc-env=PGBOUNCER_COMPILED_REPO={}" , pgbouncer_repo) ;
4836
4937 let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
5038
51- // Bundle PostgreSQL, pgvector, and pgbouncer
39+ // Bundle PostgreSQL and pgvector
5240 bundle_postgresql ( & pg_version, & out_dir) ;
5341 bundle_pgvector ( & pg_version, & pgvector_tag, & pgvector_repo, & out_dir) ;
54- bundle_pgbouncer ( & pgbouncer_tag, & pgbouncer_repo, & out_dir) ;
5542}
5643
5744fn bundle_postgresql ( pg_version : & str , out_dir : & PathBuf ) {
@@ -82,102 +69,37 @@ fn bundle_postgresql(pg_version: &str, out_dir: &PathBuf) {
8269 }
8370 } ;
8471
85- let is_windows = target. contains ( "windows" ) ;
86- let download_ext = if is_windows { "zip" } else { "tar.gz" } ;
87- let download_filename = format ! ( "postgresql-{}-{}.{}" , pg_version, pg_target, download_ext) ;
72+ let ext = if target. contains ( "windows" ) {
73+ "zip"
74+ } else {
75+ "tar.gz"
76+ } ;
77+ let filename = format ! ( "postgresql-{}-{}.{}" , pg_version, pg_target, ext) ;
8878 let url = format ! (
8979 "https://github.com/theseus-rs/postgresql-binaries/releases/download/{}/{}" ,
90- pg_version, download_filename
80+ pg_version, filename
9181 ) ;
9282
93- let download_path = out_dir. join ( & download_filename ) ;
83+ let bundle_path = out_dir. join ( & filename ) ;
9484
9585 // Download if not already cached
96- if !download_path . exists ( ) {
86+ if !bundle_path . exists ( ) {
9787 eprintln ! (
9888 "Downloading PostgreSQL {} for {}..." ,
9989 pg_version, pg_target
10090 ) ;
101- download_file ( & url, & download_path ) . expect ( "Failed to download PostgreSQL bundle" ) ;
102- eprintln ! ( "Downloaded to {}" , download_path . display( ) ) ;
91+ download_file ( & url, & bundle_path ) . expect ( "Failed to download PostgreSQL bundle" ) ;
92+ eprintln ! ( "Downloaded to {}" , bundle_path . display( ) ) ;
10393 } else {
104- eprintln ! ( "Using cached PostgreSQL bundle: {}" , download_path . display( ) ) ;
94+ eprintln ! ( "Using cached PostgreSQL bundle: {}" , bundle_path . display( ) ) ;
10595 }
10696
107- // For Windows, convert zip to tar.gz so the runtime code can use the same extraction logic
108- let final_bundle_path = if is_windows {
109- let targz_filename = format ! ( "postgresql-{}-{}.tar.gz" , pg_version, pg_target) ;
110- let targz_path = out_dir. join ( & targz_filename) ;
111-
112- if !targz_path. exists ( ) {
113- eprintln ! ( "Converting zip to tar.gz for unified extraction..." ) ;
114- convert_zip_to_targz ( & download_path, & targz_path)
115- . expect ( "Failed to convert zip to tar.gz" ) ;
116- eprintln ! ( "Converted to {}" , targz_path. display( ) ) ;
117- } else {
118- eprintln ! ( "Using cached converted bundle: {}" , targz_path. display( ) ) ;
119- }
120- targz_path
121- } else {
122- download_path
123- } ;
124-
12597 println ! (
12698 "cargo:rustc-env=POSTGRESQL_BUNDLE_PATH={}" ,
127- final_bundle_path . display( )
99+ bundle_path . display( )
128100 ) ;
129101}
130102
131- /// Convert a zip archive to tar.gz format
132- fn convert_zip_to_targz ( zip_path : & PathBuf , targz_path : & PathBuf ) -> io:: Result < ( ) > {
133- let zip_file = File :: open ( zip_path) ?;
134- let reader = BufReader :: new ( zip_file) ;
135- let mut archive = zip:: ZipArchive :: new ( reader)
136- . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidData , e) ) ?;
137-
138- let targz_file = File :: create ( targz_path) ?;
139- let encoder = GzEncoder :: new ( targz_file, Compression :: default ( ) ) ;
140- let mut tar_builder = tar:: Builder :: new ( encoder) ;
141-
142- for i in 0 ..archive. len ( ) {
143- let mut file = archive. by_index ( i)
144- . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidData , e) ) ?;
145-
146- let name = file. name ( ) . to_string ( ) ;
147-
148- if file. is_dir ( ) {
149- // Add directory entry
150- let mut header = tar:: Header :: new_gnu ( ) ;
151- header. set_path ( & name) ?;
152- header. set_size ( 0 ) ;
153- header. set_mode ( 0o755 ) ;
154- header. set_entry_type ( tar:: EntryType :: Directory ) ;
155- header. set_cksum ( ) ;
156- tar_builder. append ( & header, io:: empty ( ) ) ?;
157- } else {
158- // Add file entry
159- let mut header = tar:: Header :: new_gnu ( ) ;
160- header. set_path ( & name) ?;
161- header. set_size ( file. size ( ) ) ;
162- // Preserve executable permissions for binaries
163- if name. ends_with ( ".exe" ) || name. ends_with ( ".dll" ) || name. contains ( "/bin/" ) {
164- header. set_mode ( 0o755 ) ;
165- } else {
166- header. set_mode ( 0o644 ) ;
167- }
168- header. set_entry_type ( tar:: EntryType :: Regular ) ;
169- header. set_cksum ( ) ;
170-
171- let mut contents = Vec :: new ( ) ;
172- io:: copy ( & mut file, & mut contents) ?;
173- tar_builder. append ( & header, contents. as_slice ( ) ) ?;
174- }
175- }
176-
177- tar_builder. finish ( ) ?;
178- Ok ( ( ) )
179- }
180-
181103fn bundle_pgvector ( pg_version : & str , pgvector_tag : & str , pgvector_repo : & str , out_dir : & PathBuf ) {
182104 let target = env:: var ( "TARGET" ) . unwrap ( ) ;
183105
@@ -243,80 +165,6 @@ fn bundle_pgvector(pg_version: &str, pgvector_tag: &str, pgvector_repo: &str, ou
243165 ) ;
244166}
245167
246- fn bundle_pgbouncer ( pgbouncer_tag : & str , pgbouncer_repo : & str , out_dir : & PathBuf ) {
247- let target = env:: var ( "TARGET" ) . unwrap ( ) ;
248-
249- // Map Rust target to pgbouncer platform name
250- // Expected format from pgbouncer_compiled: pgbouncer-<platform>.tar.gz
251- let pgbouncer_platform = match target. as_str ( ) {
252- "aarch64-apple-darwin" => "aarch64-apple-darwin" ,
253- "x86_64-apple-darwin" => "x86_64-apple-darwin" ,
254- "x86_64-unknown-linux-gnu" => "x86_64-unknown-linux-gnu" ,
255- "x86_64-unknown-linux-musl" => "x86_64-unknown-linux-musl" ,
256- "aarch64-unknown-linux-gnu" => "aarch64-unknown-linux-gnu" ,
257- "aarch64-unknown-linux-musl" => "aarch64-unknown-linux-musl" ,
258- "x86_64-pc-windows-msvc" => {
259- eprintln ! ( "Warning: pgbouncer not available for Windows, skipping bundle" ) ;
260- let marker = out_dir. join ( "pgbouncer_bundle.tar.gz" ) ;
261- fs:: write ( & marker, b"" ) . expect ( "Failed to create empty pgbouncer marker" ) ;
262- println ! (
263- "cargo:rustc-env=PGBOUNCER_BUNDLE_PATH={}" ,
264- marker. display( )
265- ) ;
266- return ;
267- }
268- _ => {
269- eprintln ! (
270- "Warning: Unknown target {}, pgbouncer will not be bundled" ,
271- target
272- ) ;
273- let marker = out_dir. join ( "pgbouncer_bundle.tar.gz" ) ;
274- fs:: write ( & marker, b"" ) . expect ( "Failed to create empty pgbouncer marker" ) ;
275- println ! (
276- "cargo:rustc-env=PGBOUNCER_BUNDLE_PATH={}" ,
277- marker. display( )
278- ) ;
279- return ;
280- }
281- } ;
282-
283- let filename = format ! ( "pgbouncer-{}.tar.gz" , pgbouncer_platform) ;
284- let url = format ! (
285- "https://github.com/{}/releases/download/{}/{}" ,
286- pgbouncer_repo, pgbouncer_tag, filename
287- ) ;
288-
289- let bundle_path = out_dir. join ( & filename) ;
290-
291- // Download if not already cached
292- if !bundle_path. exists ( ) {
293- eprintln ! (
294- "Downloading pgbouncer for {}..." ,
295- pgbouncer_platform
296- ) ;
297- match download_file ( & url, & bundle_path) {
298- Ok ( _) => eprintln ! ( "Downloaded to {}" , bundle_path. display( ) ) ,
299- Err ( e) => {
300- eprintln ! ( "Warning: Failed to download pgbouncer: {}. Pooling will not be available." , e) ;
301- let marker = out_dir. join ( "pgbouncer_bundle.tar.gz" ) ;
302- fs:: write ( & marker, b"" ) . expect ( "Failed to create empty pgbouncer marker" ) ;
303- println ! (
304- "cargo:rustc-env=PGBOUNCER_BUNDLE_PATH={}" ,
305- marker. display( )
306- ) ;
307- return ;
308- }
309- }
310- } else {
311- eprintln ! ( "Using cached pgbouncer bundle: {}" , bundle_path. display( ) ) ;
312- }
313-
314- println ! (
315- "cargo:rustc-env=PGBOUNCER_BUNDLE_PATH={}" ,
316- bundle_path. display( )
317- ) ;
318- }
319-
320168fn download_file ( url : & str , dest : & PathBuf ) -> io:: Result < ( ) > {
321169 // Use curl for downloading (available on all CI platforms)
322170 let status = std:: process:: Command :: new ( "curl" )
0 commit comments