@@ -7,19 +7,16 @@ import chalk from "chalk";
77import ora from "ora" ;
88
99const NEW_CLI_INSTALL_URL = "https://cli.sfcompute.com" ;
10- const MIGRATION_GUIDE_URL =
11- "https://docs.sfcompute.com/preview/guides/migrating-from-nodes" ;
10+ const MIGRATION_GUIDE_URL = "https://sfcompute.com/migrate" ;
1211
1312export function showMigrateBanner ( ) {
14- const message = `We've rewritten sf in Rust — faster, with new commands
15- like 'sf availability', 'sf capacities', and 'sf orders'.
13+ const message = `We've rewritten the sf CLI in Rust.
1614
17- Migrating also opts you into our public preview, which
18- lets you resell unused compute back on our orderbook
19- and earn credits.
15+ List idle capacity on the orderbook to
16+ recoup up to 20% of your spend.
2017
21- Run 'sf migrate' to install it . Your current sf will
22- be moved to 'sf-old' so you can keep using it .
18+ Run 'sf migrate' to switch . Your current
19+ CLI stays as 'sf-old'.
2320
2421Docs: ${ MIGRATION_GUIDE_URL }
2522Hide: SF_CLI_DISABLE_MIGRATE_BANNER=1` ;
@@ -33,74 +30,69 @@ Hide: SF_CLI_DISABLE_MIGRATE_BANNER=1`;
3330 ) ;
3431}
3532
36- async function fetchInstallScript ( ) : Promise < string | null > {
37- const spinner = ora ( "Downloading install script" ) . start ( ) ;
38- try {
39- const response = await fetch ( NEW_CLI_INSTALL_URL ) ;
40- if ( ! response . ok ) {
41- spinner . fail ( "Failed to download install script." ) ;
42- return null ;
43- }
44- const script = await response . text ( ) ;
45- spinner . succeed ( ) ;
46- return script ;
47- } catch ( err ) {
48- spinner . fail ( "Failed to download install script." ) ;
49- console . error ( err ) ;
50- return null ;
51- }
52- }
53-
54- async function runInstallScript ( script : string ) : Promise < boolean > {
55- const bashProcess = spawn ( "bash" , [ ] , {
56- stdio : [ "pipe" , "inherit" , "inherit" ] ,
57- env : process . env ,
58- } ) ;
59-
60- // Without an error listener, spawn failures (ENOENT/EACCES on bash) emit
61- // an unhandled 'error' event and crash the CLI instead of returning false.
62- const spawnError = new Promise < Error > ( ( resolve ) => {
63- bashProcess . once ( "error" , resolve ) ;
64- } ) ;
65-
66- try {
67- bashProcess . stdin . write ( script ) ;
68- bashProcess . stdin . end ( ) ;
69- } catch {
70- // If stdin is already torn down (e.g. spawn failed synchronously), the
71- // 'error' event handler below will surface the real reason.
72- }
73-
74- const result = await Promise . race ( [
75- new Promise < { kind : "close" ; code : number | null } > ( ( resolve ) => {
76- bashProcess . once ( "close" , ( code ) => resolve ( { kind : "close" , code } ) ) ;
77- } ) ,
78- spawnError . then ( ( err ) => ( { kind : "error" as const , err } ) ) ,
79- ] ) ;
80-
81- if ( result . kind === "error" ) {
82- console . error ( chalk . red ( `Failed to run bash: ${ result . err . message } ` ) ) ;
83- return false ;
84- }
85-
86- return result . code === 0 ;
87- }
88-
89- export async function handleMigrate ( ) : Promise < boolean > {
90- const script = await fetchInstallScript ( ) ;
91- if ( ! script ) return false ;
92-
93- console . log ( chalk . cyan ( "\nInstalling the new Rust sf CLI...\n" ) ) ;
94- const ok = await runInstallScript ( script ) ;
95- if ( ! ok ) {
96- console . error ( chalk . red ( "\nMigration failed." ) ) ;
97- return false ;
98- }
99-
100- console . log (
101- boxen (
102- chalk . cyan (
103- `You're on the new sf.
33+ export function registerMigrate ( program : Command ) {
34+ return program
35+ . command ( "migrate" )
36+ . description ( "Install the new Rust-based sf CLI" )
37+ . action ( async ( ) => {
38+ const spinner = ora ( "Downloading install script" ) . start ( ) ;
39+ let script : string ;
40+ try {
41+ const response = await fetch ( NEW_CLI_INSTALL_URL ) ;
42+ if ( ! response . ok ) {
43+ spinner . fail ( "Failed to download install script." ) ;
44+ process . exit ( 1 ) ;
45+ }
46+ script = await response . text ( ) ;
47+ spinner . succeed ( ) ;
48+ } catch ( err ) {
49+ spinner . fail ( "Failed to download install script." ) ;
50+ console . error ( err ) ;
51+ process . exit ( 1 ) ;
52+ }
53+
54+ console . log ( chalk . cyan ( "\nInstalling the new Rust sf CLI...\n" ) ) ;
55+
56+ const bashProcess = spawn ( "bash" , [ ] , {
57+ stdio : [ "pipe" , "inherit" , "inherit" ] ,
58+ env : process . env ,
59+ } ) ;
60+
61+ // Without an error listener, spawn failures (ENOENT/EACCES on bash) emit
62+ // an unhandled 'error' event and crash the CLI instead of exiting cleanly.
63+ const spawnError = new Promise < Error > ( ( resolve ) => {
64+ bashProcess . once ( "error" , resolve ) ;
65+ } ) ;
66+
67+ try {
68+ bashProcess . stdin . write ( script ) ;
69+ bashProcess . stdin . end ( ) ;
70+ } catch {
71+ // If stdin is already torn down (e.g. spawn failed synchronously), the
72+ // 'error' event handler below will surface the real reason.
73+ }
74+
75+ const result = await Promise . race ( [
76+ new Promise < { kind : "close" ; code : number | null } > ( ( resolve ) => {
77+ bashProcess . once ( "close" , ( code ) => resolve ( { kind : "close" , code } ) ) ;
78+ } ) ,
79+ spawnError . then ( ( err ) => ( { kind : "error" as const , err } ) ) ,
80+ ] ) ;
81+
82+ if ( result . kind === "error" ) {
83+ console . error ( chalk . red ( `Failed to run bash: ${ result . err . message } ` ) ) ;
84+ process . exit ( 1 ) ;
85+ }
86+
87+ if ( result . code !== 0 ) {
88+ console . error ( chalk . red ( "\nMigration failed." ) ) ;
89+ process . exit ( 1 ) ;
90+ }
91+
92+ console . log (
93+ boxen (
94+ chalk . cyan (
95+ `You're on the new sf.
10496
10597Your previous CLI is still available as 'sf-old'.
10698
@@ -109,23 +101,14 @@ Next steps:
109101 sf availability
110102
111103Migration guide: ${ MIGRATION_GUIDE_URL } ` ,
112- ) ,
113- {
114- padding : 1 ,
115- borderColor : "cyan" ,
116- borderStyle : "round" ,
117- } ,
118- ) ,
119- ) ;
120- return true ;
121- }
122-
123- export function registerMigrate ( program : Command ) {
124- return program
125- . command ( "migrate" )
126- . description ( "Install the new Rust-based sf CLI" )
127- . action ( async ( ) => {
128- const success = await handleMigrate ( ) ;
129- process . exit ( success ? 0 : 1 ) ;
104+ ) ,
105+ {
106+ padding : 1 ,
107+ borderColor : "cyan" ,
108+ borderStyle : "round" ,
109+ } ,
110+ ) ,
111+ ) ;
112+ process . exit ( 0 ) ;
130113 } ) ;
131114}
0 commit comments