From 89946cb5c45598f3eeb68470f83265e5b7d6c4dd Mon Sep 17 00:00:00 2001 From: Zuoling Rong Date: Fri, 2 May 2025 02:25:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B9=A6=E7=AD=BE=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E7=94=9F=E6=88=90=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89=E7=9A=84=20`bookmarks.user?= =?UTF-8?q?.yml`=20=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 62 ++++++++++++++++++++++++++----- README.md | 16 +++++--- bookmarks/README.md | 5 ++- src/bookmark-processor.js | 71 +++++++++++++++++++++++++++++++----- src/generator.js | 68 ++++++++++++++-------------------- 5 files changed, 155 insertions(+), 67 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d1697f9..7031058 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -53,21 +53,51 @@ jobs: - name: Process bookmark file if: steps.check_bookmark_files.outputs.found == 'true' - run: node src/bookmark-processor.js + run: | + echo "Processing bookmark files..." + node src/bookmark-processor.js + + - name: Debug directory contents + if: steps.check_bookmark_files.outputs.found == 'true' + run: | + echo "Current directory contents:" + ls -la + echo "Does bookmarks.user.yml exist?" + if [ -f bookmarks.user.yml ]; then + echo "YES - bookmarks.user.yml exists" + cat bookmarks.user.yml | head -n 10 + else + echo "NO - bookmarks.user.yml does not exist" + fi - - name: Commit bookmarks.yml changes + - name: Commit bookmarks.user.yml changes if: steps.check_bookmark_files.outputs.found == 'true' run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action (Bookmarks)" - # 检查 bookmarks.yml 是否真的被修改了 - if ! git diff --quiet bookmarks.yml; then - echo "bookmarks.yml changed, committing..." - git add bookmarks.yml - git commit -m "Update bookmarks.yml from imported bookmarks" - # 不需要push,因为构建步骤会使用当前工作区的内容 + + # Check if the file exists + if [ -f bookmarks.user.yml ]; then + # Check if file is already tracked by git + if git ls-files --error-unmatch bookmarks.user.yml 2>/dev/null; then + echo "bookmarks.user.yml exists and is tracked by git" + # Check if it has changes + if ! git diff --quiet bookmarks.user.yml; then + echo "bookmarks.user.yml has changes, committing..." + git add bookmarks.user.yml + git commit -m "Update bookmarks.user.yml from imported bookmarks" + else + echo "No changes to bookmarks.user.yml" + fi + else + echo "bookmarks.user.yml exists but is not tracked by git (new file)" + git add bookmarks.user.yml + git commit -m "Add bookmarks.user.yml from imported bookmarks" + fi else - echo "No changes to bookmarks.yml" + echo "ERROR: bookmarks.user.yml does not exist! Bookmark processing may have failed." + echo "Current directory contents:" + ls -la fi - name: Clean up processed bookmark files @@ -97,6 +127,20 @@ jobs: # 使用 GITHUB_TOKEN 推送 if: steps.check_bookmark_files.outputs.found == 'true' run: | + echo "Checking git status before pushing..." + git status + + echo "Checking bookmarks.user.yml existence before pushing..." + if [ -f bookmarks.user.yml ]; then + echo "bookmarks.user.yml exists with content:" + ls -la bookmarks.user.yml + echo "First 5 lines:" + head -n 5 bookmarks.user.yml + else + echo "WARNING: bookmarks.user.yml does not exist before pushing!" + fi + + echo "Pushing changes to repository..." git push "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" HEAD:${{ github.ref_name }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index b442fb8..1600e8e 100644 --- a/README.md +++ b/README.md @@ -206,14 +206,15 @@ npm run dev - 系统会扫描 `bookmarks` 目录,查找最新的HTML书签文件 - 解析书签文件中的链接和文件夹结构 - 自动为书签分配适当的图标 - - 生成 `bookmarks.yml` 配置文件 + - 生成 `bookmarks.user.yml` 配置文件(而不是直接修改 `bookmarks.yml`) - 处理完成后会自动清空 `bookmarks` 目录(防止重复处理) - 重新构建并部署网站 4. **注意事项** - 每次只处理一个书签文件,如有多个文件,系统会选择最新的那个 - 书签导入是构建时的一次性操作,不会在浏览器中保存或同步您的书签 - - 如果想要更新书签,可以直接编辑 `bookmarks.yml`,或重新导出书签文件并重新导入 + - 如果想要更新书签,可以直接编辑 `bookmarks.user.yml`,或重新导出书签文件并重新导入 + - 系统会优先使用 `bookmarks.user.yml`,如果同时存在 `bookmarks.yml`,它们的内容会被合并(用户配置优先) ### 自动化工作流程详解 @@ -226,7 +227,7 @@ MeNav使用单一的GitHub Actions工作流处理书签导入与网站部署, 2. **书签处理步骤**: - 自动检测 `bookmarks` 目录中的HTML文件 - 使用 `bookmark-processor.js` 脚本处理书签文件 - - 生成/更新 `bookmarks.yml` 配置文件 + - 生成/更新 `bookmarks.user.yml` 配置文件 - 提交更改(如有)并保存至仓库 - 自动清理已处理的HTML书签文件 @@ -241,10 +242,10 @@ MeNav使用单一的GitHub Actions工作流处理书签导入与网站部署, ### 书签配置自定义 -处理后生成的 `bookmarks.yml` 文件可以手动编辑以进一步自定义: +处理后生成的 `bookmarks.user.yml` 文件可以手动编辑以进一步自定义: ```yaml -# 自动生成的书签配置示例 +# 自动生成的书签配置示例(用户自定义版本) title: 我的书签 subtitle: 从浏览器导入的书签收藏 categories: @@ -265,7 +266,10 @@ categories: - 重新组织书签分类结构 - 添加或删除特定书签 -**提示**: 尽管自动处理会清理原始HTML文件,但修改后的 `bookmarks.yml` 会被保留,您可以随时手动编辑它来更新书签内容。 +**提示**: +- 尽管自动处理会清理原始HTML文件,但修改后的 `bookmarks.user.yml` 会被保留,您可以随时手动编辑它来更新书签内容 +- 如果项目中同时存在 `bookmarks.yml` 和 `bookmarks.user.yml`,系统会合并两者的内容,以 `bookmarks.user.yml` 中的配置为优先 +- 这种设计允许您在更新源仓库时保留自己的书签配置 ### 模板说明 diff --git a/bookmarks/README.md b/bookmarks/README.md index b01973d..0880d7a 100644 --- a/bookmarks/README.md +++ b/bookmarks/README.md @@ -18,11 +18,12 @@ git push ``` -4. GitHub Actions将自动处理书签文件,生成`bookmarks.yml`,并重新构建站点 +4. GitHub Actions将自动处理书签文件,生成`bookmarks.user.yml`,并重新构建站点 ## 注意事项 - 仅支持标准HTML格式的书签文件 - 每次只会处理目录中最新的一个书签文件 - 处理完成后,书签文件会被自动清除,以防止重复处理 -- 已导入的书签可以在生成的`bookmarks.yml`文件中查看和编辑 \ No newline at end of file +- 已导入的书签可以在生成的`bookmarks.user.yml`文件中查看和编辑 +- 系统会优先使用`bookmarks.user.yml`的配置,如果存在`bookmarks.yml`,会自动合并两者的内容(用户配置优先) \ No newline at end of file diff --git a/src/bookmark-processor.js b/src/bookmark-processor.js index ce9e881..ceee76c 100644 --- a/src/bookmark-processor.js +++ b/src/bookmark-processor.js @@ -2,10 +2,12 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); -// 书签文件夹路径 -const BOOKMARKS_DIR = path.join(__dirname, '..', 'bookmarks'); -// 输出配置文件路径 -const OUTPUT_FILE = path.join(__dirname, '..', 'bookmarks.yml'); +// 书签文件夹路径 - 使用相对路径 +const BOOKMARKS_DIR = 'bookmarks'; +// 输出配置文件路径 - 使用相对路径 +const OUTPUT_FILE = 'bookmarks.user.yml'; +// 默认书签配置文件路径 - 使用相对路径 +const DEFAULT_BOOKMARKS_FILE = 'bookmarks.yml'; // 图标映射,根据URL关键字匹配合适的图标 const ICON_MAPPING = { @@ -191,9 +193,10 @@ function generateBookmarksYaml(bookmarks) { // 添加注释 const yamlWithComment = -`# 自动生成的书签配置文件 - 请勿手动编辑 +`# 自动生成的书签配置文件 - 用户自定义版本 # 由bookmark-processor.js生成于 ${new Date().toISOString()} # 若要更新,请将新的书签HTML文件放入bookmarks/目录 +# 注意:此文件会覆盖bookmarks.yml中的同名配置 ${yamlString}`; @@ -206,8 +209,8 @@ ${yamlString}`; // 更新现有config.yml中的导航,添加书签页面 function updateConfigWithBookmarks() { - const configFile = path.join(__dirname, '..', 'config.yml'); - const userConfigFile = path.join(__dirname, '..', 'config.user.yml'); + const configFile = 'config.yml'; + const userConfigFile = 'config.user.yml'; // 优先使用用户配置文件,如果存在 const targetConfigFile = fs.existsSync(userConfigFile) ? userConfigFile : configFile; @@ -245,6 +248,10 @@ function updateConfigWithBookmarks() { // 主函数 async function main() { + console.log('Starting bookmark processing...'); + console.log(`Current working directory: ${process.cwd()}`); + console.log(`Output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`); + // 获取最新的书签文件 const bookmarkFile = getLatestBookmarkFile(); if (!bookmarkFile) { @@ -254,21 +261,67 @@ async function main() { try { // 读取文件内容 + console.log(`Reading bookmark file: ${bookmarkFile}`); const htmlContent = fs.readFileSync(bookmarkFile, 'utf8'); // 解析书签 const bookmarks = parseBookmarks(htmlContent); console.log(`Found ${bookmarks.categories.length} categories with bookmarks`); + if (bookmarks.categories.length === 0) { + console.error('ERROR: No bookmark categories found in the HTML file. Processing aborted.'); + return; + } + console.log('Categories found:'); + bookmarks.categories.forEach(cat => { + console.log(`- ${cat.name}: ${cat.sites.length} sites`); + }); // 生成YAML const yaml = generateBookmarksYaml(bookmarks); - if (yaml) { + if (!yaml) { + console.error('ERROR: Failed to generate YAML from bookmarks. Processing aborted.'); + return; + } + + // 显示将要写入的YAML前几行 + console.log('Generated YAML preview (first 5 lines):'); + console.log(yaml.split('\n').slice(0, 5).join('\n') + '\n...'); + + try { + // 确保目标目录存在 + const outputDir = path.dirname(OUTPUT_FILE); + if (!fs.existsSync(outputDir) && outputDir !== '.') { + console.log(`Creating output directory: ${outputDir}`); + fs.mkdirSync(outputDir, { recursive: true }); + } + // 保存YAML文件 + console.log(`Writing to: ${OUTPUT_FILE}`); fs.writeFileSync(OUTPUT_FILE, yaml, 'utf8'); - console.log(`Saved bookmarks configuration to ${OUTPUT_FILE}`); + + // 验证文件是否确实被创建 + if (fs.existsSync(OUTPUT_FILE)) { + const stats = fs.statSync(OUTPUT_FILE); + console.log(`Successfully saved bookmarks configuration to ${OUTPUT_FILE}`); + console.log(`Verified file exists: ${OUTPUT_FILE}`); + console.log(`File size: ${stats.size} bytes`); + console.log(`File permissions: ${stats.mode.toString(8)}`); + + // 列出当前目录内容以确认 + console.log('Current directory contains:'); + fs.readdirSync('.').forEach(file => { + console.log(`- ${file}`); + }); + } else { + console.error(`ERROR: File was not created: ${OUTPUT_FILE}`); + process.exit(1); + } // 更新导航 updateConfigWithBookmarks(); + } catch (writeError) { + console.error(`ERROR writing file ${OUTPUT_FILE}:`, writeError); + process.exit(1); } } catch (error) { console.error('Error processing bookmark file:', error); diff --git a/src/generator.js b/src/generator.js index b76e4ca..907b73a 100644 --- a/src/generator.js +++ b/src/generator.js @@ -17,40 +17,45 @@ function escapeHtml(unsafe) { // 读取配置文件 function loadConfig() { - let config = {}; + let config = null; - // 读取默认配置 - try { - const defaultConfigFile = fs.readFileSync('config.yml', 'utf8'); - config = yaml.load(defaultConfigFile); - } catch (e) { - console.error('Error loading default config file:', e); - process.exit(1); - } - - // 尝试读取用户配置并合并 try { + // 优先尝试读取用户配置 if (fs.existsSync('config.user.yml')) { const userConfigFile = fs.readFileSync('config.user.yml', 'utf8'); - const userConfig = yaml.load(userConfigFile); - // 深度合并配置,用户配置优先 - config = mergeConfigs(config, userConfig); + config = yaml.load(userConfigFile); console.log('Using user configuration from config.user.yml'); - } else { + } + // 如果没有用户配置,则使用默认配置 + else { + const defaultConfigFile = fs.readFileSync('config.yml', 'utf8'); + config = yaml.load(defaultConfigFile); console.log('No user configuration found, using default config.yml'); } } catch (e) { - console.error('Error loading user config file:', e); - console.log('Falling back to default configuration'); + console.error('Error loading configuration file:', e); + process.exit(1); } - // 尝试读取书签配置并合并 + // 尝试读取书签配置 try { - if (fs.existsSync('bookmarks.yml')) { + let bookmarksConfig = null; + + // 优先尝试读取用户书签配置 + if (fs.existsSync('bookmarks.user.yml')) { + const userBookmarksFile = fs.readFileSync('bookmarks.user.yml', 'utf8'); + bookmarksConfig = yaml.load(userBookmarksFile); + console.log('Using user bookmarks configuration from bookmarks.user.yml'); + } + // 如果没有用户书签配置,则尝试读取默认书签配置 + else if (fs.existsSync('bookmarks.yml')) { const bookmarksFile = fs.readFileSync('bookmarks.yml', 'utf8'); - const bookmarksConfig = yaml.load(bookmarksFile); - - // 添加书签页面配置 + bookmarksConfig = yaml.load(bookmarksFile); + console.log('Using default bookmarks configuration from bookmarks.yml'); + } + + // 添加书签页面配置 + if (bookmarksConfig) { config.bookmarks = bookmarksConfig; // 确保导航中有书签页面 @@ -63,8 +68,6 @@ function loadConfig() { active: false }); } - - console.log('Loaded bookmarks configuration from bookmarks.yml'); } } catch (e) { console.error('Error loading bookmarks configuration:', e); @@ -73,23 +76,6 @@ function loadConfig() { return config; } -// 深度合并配置对象 -function mergeConfigs(defaultConfig, userConfig) { - if (!userConfig) return defaultConfig; - - const merged = { ...defaultConfig }; - - for (const key in userConfig) { - if (typeof userConfig[key] === 'object' && !Array.isArray(userConfig[key])) { - merged[key] = mergeConfigs(defaultConfig[key] || {}, userConfig[key]); - } else { - merged[key] = userConfig[key]; - } - } - - return merged; -} - // 生成导航菜单 function generateNavigation(navigation) { return navigation.map(nav => `