Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Moving the finished note to something other than _posts #410

Merged
merged 5 commits into from
Dec 20, 2024

Conversation

pedrobiqua
Copy link
Contributor

@pedrobiqua pedrobiqua commented Dec 18, 2024

Pull Request

Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bugfixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Currently, all finished notes are moved to the default _posts folder, which may cause disorganization and difficulty managing content, especially for users of static site generators like Jekyll.

Issue Number: #363

What is the new behavior?

This feature allows finished notes to be moved to a location other than the default _posts folder, improving organization and content management. It helps separate draft, published, or archived notes from ongoing posts, enhancing the workflow and structure of the content.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

This change provides better content organization and is fully backward-compatible, as it adds flexibility in where finished notes can be stored without affecting existing workflows. I ran the existing tests, and they passed successfully; however, I did not create new tests specifically for this feature.

Summary by CodeRabbit

  • New Features

    • Enhanced file handling logic for improved flexibility in moving processed files.
    • Introduced a new method to dynamically generate sub-paths within the Jekyll directory.
  • Documentation

    • Added comments to indicate potential refactoring points for future development.

… the finished note elsewhere

"Moving the finished note to a location other than the default `_posts` folder allows for better
organization and management of content, especially in static site generators like Jekyll. This helps
separate draft, published, or archived notes from ongoing posts, improving workflow and structure."

fix songkg7#363
Copy link
Contributor

coderabbitai bot commented Dec 18, 2024

Walkthrough

The pull request introduces modifications to the Jekyll conversion process, specifically in file handling logic. A new method targetSubPath is added to the JekyllSettings class, which enables dynamic path generation based on folder names. The convertToChirpy function in chirpy.ts now includes conditional logic for moving files, allowing more flexible file management by determining the appropriate destination path based on the source folder.

Changes

File Change Summary
src/jekyll/chirpy.ts Enhanced file moving logic with conditional path determination
src/jekyll/settings/JekyllSettings.ts Added targetSubPath(folder: string) method for dynamic path generation

Sequence Diagram

sequenceDiagram
    participant C as Chirpy Converter
    participant S as Jekyll Settings
    participant F as File System
    
    C->>S: Request target sub-path
    S-->>C: Return dynamic path
    C->>F: Move files to calculated path
Loading

Possibly related PRs

  • add a relative_url toggle for support Jekyll Liquid Filters #406: The changes in the main PR introduce a new interface LiquidFilterOptions in src/jekyll/chirpy.ts, which is utilized in the convertToChirpy function, indicating a direct connection to the modifications made in the ResourceLinkConverter class related to handling image URLs with a relative_url filter.

Suggested labels

chirpy, size/XXL

Poem

🐰 A rabbit's tale of paths so neat,
Where folders dance and files retreat.
Dynamic routes, a coding delight,
Jekyll's magic takes playful flight.
Conversion's journey, smooth and bright! 🚀


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91c4d61 and fbf1800.

📒 Files selected for processing (1)
  • src/jekyll/chirpy.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/jekyll/chirpy.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/jekyll/settings/JekyllSettings.ts (1)

79-81: Add input validation and documentation for consistency.

While the implementation is straightforward, consider these improvements:

  1. Add input validation to handle empty or invalid folder names
  2. Add JSDoc comments to match the documentation style of other methods

Consider updating the implementation like this:

+  /**
+   * Generates a target sub-path within the Jekyll directory
+   * @param folder - The folder name to append to the Jekyll path
+   * @returns The complete sub-path
+   * @throws {Error} If folder is empty or contains invalid characters
+   */
   targetSubPath(folder: string): string {
+    if (!folder || folder.trim().length === 0) {
+      throw new Error('Folder name cannot be empty');
+    }
+    if (folder.includes('..') || folder.includes('/')) {
+      throw new Error('Invalid folder name');
+    }
     return `${this._jekyllPath}/${folder}`;
   }
src/jekyll/chirpy.ts (1)

55-75: Consider adding unit tests for the new file movement logic.

The PR objectives mention that no tests were added for this feature. Given the complexity of path handling and file operations, unit tests would be valuable.

Would you like me to help create unit tests for:

  1. Path extraction logic
  2. File movement with different folder scenarios
  3. Error handling cases
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0b00d3 and dbf9f83.

📒 Files selected for processing (2)
  • src/jekyll/chirpy.ts (1 hunks)
  • src/jekyll/settings/JekyllSettings.ts (1 hunks)
🔇 Additional comments (1)
src/jekyll/chirpy.ts (1)

55-75: Verify similar file operations across the codebase.

Let's ensure consistent path handling across the codebase.

✅ Verification successful

Let me check the implementation of these file operations to ensure consistency.


Path handling is consistent across the codebase

The code review concern can be resolved as the investigation shows:

  • The moveFiles utility is consistently used across both Jekyll (Chirpy) and Docusaurus implementations
  • Path handling is properly abstracted in utils.ts using Node's path module for most operations
  • The specific path substring operation in the reviewed code is unique to that location and serves a specific purpose of folder name extraction

The changes in the review are safe and maintain consistency with the rest of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar file movement patterns
rg -l "moveFiles|vaultAbsolutePath" --type ts

# Look for potential path manipulation
ast-grep --pattern 'path.substring($$$)' --lang ts

Length of output: 253


Script:

#!/bin/bash
# Check implementation of moveFiles and vaultAbsolutePath
rg "moveFiles|vaultAbsolutePath" -A 5 --type ts

# Check path handling in other files
rg "path\." --type ts -A 2

Length of output: 4610

Comment on lines 56 to 61
// Where can I create this code block(create a function)?
const path:string = file.path;
const directory = path.substring(0, path.lastIndexOf("/"));
const folder = directory.substring(directory.lastIndexOf("/") + 1);
// end code block

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Extract path parsing logic into a dedicated function.

The comment indicates this should be a separate function. Let's help implement that.

Consider extracting this logic:

function extractFolderFromPath(path: string): string {
  const directory = path.substring(0, path.lastIndexOf("/"));
  return directory.substring(directory.lastIndexOf("/") + 1);
}

Comment on lines 62 to 75
if(folder !== plugin.obsidianPathSettings.readyFolder){
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}/${folder}`,
settings.targetSubPath(folder),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));

} else {
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}`,
settings.targetPath(),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Refactor duplicate notification logic and improve error handling.

The code has several issues to address:

  1. Duplicate success notifications
  2. Potential path traversal vulnerability
  3. Non-specific error handling

Consider this refactoring:

-      if(folder !== plugin.obsidianPathSettings.readyFolder){
-        await moveFiles(
-          `${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}/${folder}`,
-          settings.targetSubPath(folder),
-          settings.pathReplacer,
-        ).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
-
-      } else {
-        await moveFiles(
-          `${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}`,
-          settings.targetPath(),
-          settings.pathReplacer,
-        ).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
-      }
+      try {
+        const sourcePath = folder !== plugin.obsidianPathSettings.readyFolder
+          ? path.join(vaultAbsolutePath(plugin), plugin.obsidianPathSettings.readyFolder, folder)
+          : path.join(vaultAbsolutePath(plugin), plugin.obsidianPathSettings.readyFolder);
+        
+        const targetPath = folder !== plugin.obsidianPathSettings.readyFolder
+          ? settings.targetSubPath(folder)
+          : settings.targetPath();
+        
+        await moveFiles(sourcePath, targetPath, settings.pathReplacer);
+        new Notice('Moved files to Chirpy successfully.', 5000);
+      } catch (error) {
+        console.error('Failed to move files:', error);
+        new Notice(`Failed to move files: ${error.message}`, 5000);
+      }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(folder !== plugin.obsidianPathSettings.readyFolder){
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}/${folder}`,
settings.targetSubPath(folder),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
} else {
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}`,
settings.targetPath(),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
}
try {
const sourcePath = folder !== plugin.obsidianPathSettings.readyFolder
? path.join(vaultAbsolutePath(plugin), plugin.obsidianPathSettings.readyFolder, folder)
: path.join(vaultAbsolutePath(plugin), plugin.obsidianPathSettings.readyFolder);
const targetPath = folder !== plugin.obsidianPathSettings.readyFolder
? settings.targetSubPath(folder)
: settings.targetPath();
await moveFiles(sourcePath, targetPath, settings.pathReplacer);
new Notice('Moved files to Chirpy successfully.', 5000);
} catch (error) {
console.error('Failed to move files:', error);
new Notice(`Failed to move files: ${error.message}`, 5000);
}

@pull-request-size pull-request-size bot added size/S and removed size/M labels Dec 18, 2024
@pedrobiqua
Copy link
Contributor Author

Hello @songkg7,

I implemented the new functionality from issue #363 , and when testing it locally, everything seems to be working fine. However, when running the tests in the pull request, I received the following errors related to ESLint and the JSON file format:

Errors found in JAVASCRIPT_ES
Errors found in JSON
Errors found in JSON_PRETTIER
Errors found in TYPESCRIPT_ES

I couldn't identify the exact cause of these errors, as the local tests don't point to any issues and everything seems to be in line with the configured rules. Also, I didn't edit any files related to ESLint. Could you help me understand what might be happening or if there is any additional configuration that should be applied to resolve these errors in the tests?

Thank you in advance for your help.

@songkg7
Copy link
Owner

songkg7 commented Dec 20, 2024

Hello @songkg7,

I implemented the new functionality from issue #363 , and when testing it locally, everything seems to be working fine. However, when running the tests in the pull request, I received the following errors related to ESLint and the JSON file format:

Errors found in JAVASCRIPT_ES
Errors found in JSON
Errors found in JSON_PRETTIER
Errors found in TYPESCRIPT_ES

I couldn't identify the exact cause of these errors, as the local tests don't point to any issues and everything seems to be in line with the configured rules. Also, I didn't edit any files related to ESLint. Could you help me understand what might be happening or if there is any additional configuration that should be applied to resolve these errors in the tests?

Thank you in advance for your help.

There was a recent eslint update, and it hasn't been working since. I don't think these settings are needed yet. I'll disable it and reactivate it later if I feel I need it.

@songkg7
Copy link
Owner

songkg7 commented Dec 20, 2024

Thanks for your contribution! 👍

I'll review it soon.

songkg7
songkg7 previously approved these changes Dec 20, 2024
Copy link
Owner

@songkg7 songkg7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Comment on lines 56 to 74
// Where can I create this code block(create a function)?
const path: string = file.path;
const directory = path.substring(0, path.lastIndexOf('/'));
const folder = directory.substring(directory.lastIndexOf('/') + 1);
// end code block

if (folder !== plugin.obsidianPathSettings.readyFolder) {
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}/${folder}`,
settings.targetSubPath(folder),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
} else {
await moveFiles(
`${vaultAbsolutePath(plugin)}/${plugin.obsidianPathSettings.readyFolder}`,
settings.targetPath(),
settings.pathReplacer,
).then(() => new Notice('Moved files to Chirpy successfully.', 5000));
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that chirpy.ts hasn't yet adopted functional programming, so there doesn't appear to be a suitable place for functions to fit naturally. Create a new class, such as a PathDecider class, which determines where to move files based on certain options, might be a better solution.

as follow:

const targetPath = new PathDecicder().decide(option)

However, one of my goals is to refactor this into a function-base structure, similar to docusaurus.ts. So instead of introducing more classes, I think it's fine to apply the current approach for now and refactor it into a functional style later.

That said, the decision is up to you! :)

If it's okay to wrap up the work at this point, I'll proceed with merging and closing the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you'll be doing a refactoring later, I believe it's not necessary for now, and I think this proposed solution is excellent to avoid rework in the future. Congratulations on the code! :)

I'll remove the comments in the next commit.

src/jekyll/chirpy.ts Outdated Show resolved Hide resolved
Copy link

codecov bot commented Dec 20, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.23%. Comparing base (2fe9d98) to head (d6f3838).
Report is 3 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #410   +/-   ##
=======================================
  Coverage   94.23%   94.23%           
=======================================
  Files          12       12           
  Lines         243      243           
  Branches       33       33           
=======================================
  Hits          229      229           
  Misses         13       13           
  Partials        1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@songkg7
Copy link
Owner

songkg7 commented Dec 20, 2024

you can ignore codecov :)

@pedrobiqua pedrobiqua requested a review from songkg7 December 20, 2024 11:56
Copy link
Owner

@songkg7 songkg7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Thanks for your contribution.

@songkg7 songkg7 merged commit fd437a9 into songkg7:main Dec 20, 2024
9 checks passed
@songkg7 songkg7 removed the in review label Dec 20, 2024
@songkg7 songkg7 linked an issue Dec 20, 2024 that may be closed by this pull request
@songkg7 songkg7 added the chirpy Related to Jekyll Chirpy theme label Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chirpy Related to Jekyll Chirpy theme size/S
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Moving the finished note to something other than _posts
2 participants