ソースを参照

Fix: create parent dir before write

SukkaW 1 年間 前
コミット
fc3ae52baa

+ 3 - 4
Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts

@@ -1,6 +1,5 @@
 // @ts-check
 import path from 'path';
-import fsp from 'fs/promises';
 import { DOMESTICS } from '../Source/non_ip/domestic';
 import { DIRECTS, LANS } from '../Source/non_ip/direct';
 import { readFileIntoProcessedArray } from './lib/fetch-text-by-line';
@@ -10,6 +9,7 @@ import { SHARED_DESCRIPTION } from './lib/constants';
 import { createMemoizedPromise } from './lib/memo-promise';
 import * as yaml from 'yaml';
 import { appendArrayInPlace } from './lib/append-array-in-place';
+import { writeFile } from './lib/bun';
 
 export const getDomesticAndDirectDomainsRulesetPromise = createMemoizedPromise(async () => {
   const domestics = await readFileIntoProcessedArray(path.resolve(__dirname, '../Source/non_ip/domestic.conf'));
@@ -96,7 +96,7 @@ export const buildDomesticRuleset = task(typeof Bun !== 'undefined' ? Bun.main =
       ],
       path.resolve(__dirname, '../Modules/sukka_local_dns_mapping.sgmodule')
     ),
-    fsp.writeFile(
+    writeFile(
       path.resolve(__dirname, '../Internal/clash_nameserver_policy.yaml'),
       yaml.stringify(
         {
@@ -129,8 +129,7 @@ export const buildDomesticRuleset = task(typeof Bun !== 'undefined' ? Bun.main =
           )
         },
         { version: '1.1' }
-      ),
-      { encoding: 'utf-8' }
+      )
     )
   ]);
 });

+ 7 - 5
Build/build-internal-reverse-chn-cidr.ts

@@ -5,7 +5,7 @@ import { exclude, merge } from 'fast-cidr-tools';
 import { getChnCidrPromise } from './build-chn-cidr';
 import { NON_CN_CIDR_INCLUDED_IN_CHNROUTE, RESERVED_IPV4_CIDR } from './constants/cidr';
 
-import fsp from 'fs/promises';
+import { writeFile } from './lib/bun';
 
 export const buildInternalReverseChnCIDR = task(typeof Bun !== 'undefined' ? Bun.main === __filename : require.main === module, __filename)(async () => {
   const cidr = await getChnCidrPromise();
@@ -21,9 +21,11 @@ export const buildInternalReverseChnCIDR = task(typeof Bun !== 'undefined' ? Bun
     )
   );
 
-  return fsp.writeFile(
-    path.resolve(__dirname, '../Internal/reversed-chn-cidr.txt'),
-    reversedCidr.join('\n') + '\n',
-    { encoding: 'utf-8' }
+  const outputDir = path.resolve(__dirname, '../Internal');
+  const outputFile = path.join(outputDir, 'reversed-chn-cidr.txt');
+
+  return writeFile(
+    outputFile,
+    reversedCidr.join('\n') + '\n'
   );
 });

+ 2 - 1
Build/build-public.ts

@@ -7,6 +7,7 @@ import { fdir as Fdir } from 'fdir';
 import { sort } from './lib/timsort';
 
 import Trie from 'mnemonist/trie';
+import { writeFile } from './lib/bun';
 
 const rootPath = path.resolve(__dirname, '../');
 const publicPath = path.resolve(__dirname, '../public');
@@ -50,7 +51,7 @@ export const buildPublic = task(typeof Bun !== 'undefined' ? Bun.main === __file
     .traceChild('generate index.html')
     .traceAsyncFn(() => treeDir(publicPath).then(generateHtml));
 
-  return fsp.writeFile(path.join(publicPath, 'index.html'), html);
+  return writeFile(path.join(publicPath, 'index.html'), html);
 });
 
 const priorityOrder: Record<'default' | string & {}, number> = {

+ 2 - 2
Build/build-sgmodule-always-realip.ts

@@ -1,9 +1,9 @@
 import path from 'path';
-import fsp from 'fs/promises';
 import { task } from './trace';
 import { compareAndWriteFile } from './lib/create-file';
 import { DIRECTS, LANS } from '../Source/non_ip/direct';
 import * as yaml from 'yaml';
+import { writeFile } from './lib/bun';
 
 const HOSTNAMES = [
   // Network Detection, Captive Portal
@@ -61,7 +61,7 @@ export const buildAlwaysRealIPModule = task(typeof Bun !== 'undefined' ? Bun.mai
       ],
       path.resolve(__dirname, '../Modules/sukka_common_always_realip.sgmodule')
     ),
-    fsp.writeFile(
+    writeFile(
       path.resolve(__dirname, '../Internal/clash_fake_ip_filter.yaml'),
       yaml.stringify(
         {

+ 22 - 0
Build/lib/bun.ts

@@ -1,3 +1,7 @@
+import { dirname } from 'path';
+import fs from 'fs';
+import fsp from 'fs/promises';
+
 interface Peek {
   <T = undefined>(promise: T | Promise<T>): Promise<T> | T,
   status<T = undefined>(
@@ -11,3 +15,21 @@ noopPeek.status = () => 'unknown';
 export const peek: Peek = typeof Bun !== 'undefined'
   ? Bun.peek
   : noopPeek as Peek;
+
+interface Write {
+  (
+    destination: string,
+    input: NodeJS.TypedArray | string,
+  ): Promise<unknown>
+}
+
+export const writeFile: Write = typeof Bun !== 'undefined'
+  ? Bun.write
+  : (async (destination: string, input) => {
+    const dir = dirname(destination);
+
+    if (!fs.existsSync(dir)) {
+      await fsp.mkdir(dir, { recursive: true });
+    }
+    return fsp.writeFile(destination, input, { encoding: 'utf-8' });
+  });

+ 2 - 1
Build/lib/create-file.ts

@@ -8,6 +8,7 @@ import fsp from 'fs/promises';
 import { sort } from './timsort';
 import { fastStringArrayJoin } from './misc';
 import { readFileByLine } from './fetch-text-by-line';
+import { writeFile } from './bun';
 
 export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {
   let isEqual = true;
@@ -70,7 +71,7 @@ export async function compareAndWriteFile(span: Span, linesA: string[], filePath
 
   await span.traceChildAsync(`writing ${filePath}`, async () => {
     // if (linesALen < 10000) {
-    return fsp.writeFile(filePath, fastStringArrayJoin(linesA, '\n') + '\n');
+    return writeFile(filePath, fastStringArrayJoin(linesA, '\n') + '\n');
     // }
     // const writer = file.writer();