Skip to content

[clang-doc] switched from using relative to absolute paths #93281

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

Merged
merged 13 commits into from
Jul 25, 2024

Conversation

PeterChou1
Copy link
Contributor

@PeterChou1 PeterChou1 commented May 24, 2024

fixes #92867

This patches changes the way clang-doc index navigation works, previously it was based a relative path approach, this approach is error prone and lead to wrong paths for the anchor tag. The new navigation way is based on absolute paths and should work and be less confusing codewise.
Because the differences with serving over a http server and viewing via file system I also added export a RootPath variable to the index_json.js file

@llvmbot
Copy link
Member

llvmbot commented May 24, 2024

@llvm/pr-subscribers-clang-tools-extra

Author: None (PeterChou1)

Changes

issue: #92867

I solved the problem by making the js use absolute path instead relative I think this also makes it more permanent since there is no need to compute relative path anymore


Full diff: https://github.com/llvm/llvm-project/pull/93281.diff

1 Files Affected:

  • (modified) clang-tools-extra/clang-doc/assets/index.js (+35-37)
diff --git a/clang-tools-extra/clang-doc/assets/index.js b/clang-tools-extra/clang-doc/assets/index.js
index a5ac90f2e06e7..fe35e706cc98d 100644
--- a/clang-tools-extra/clang-doc/assets/index.js
+++ b/clang-tools-extra/clang-doc/assets/index.js
@@ -1,48 +1,46 @@
-// Append using posix-style a file name or directory to Base
-function append(Base, New) {
-  if (!New)
-    return Base;
-  if (Base)
-    Base += "/";
-  Base += New;
-  return Base;
-}
-
-// Get relative path to access FilePath from CurrentDirectory
-function computeRelativePath(FilePath, CurrentDirectory) {
-  var Path = FilePath;
-  while (Path) {
-    if (CurrentDirectory == Path)
-      return FilePath.substring(Path.length + 1);
-    Path = Path.substring(0, Path.lastIndexOf("/"));
-  }
-
-  var Dir = CurrentDirectory;
-  var Result = "";
-  while (Dir) {
-    if (Dir == FilePath)
-      break;
-    Dir = Dir.substring(0, Dir.lastIndexOf("/"));
-    Result = append(Result, "..")
+function genLink(Ref) {
+  var Path = `${window.location.protocol}//${window.location.host}/${Ref.Path}`;
+  if (Ref.RefType !== "namespace") {
+    if (Ref.Path === "") {
+      Path = `${Path}${Ref.Name}.html`;
+    }
+    else {
+      Path = `${Path}/${Ref.Name}.html`;
+    }
   }
-  Result = append(Result, FilePath.substring(Dir.length))
-  return Result;
-}
-
-function genLink(Ref, CurrentDirectory) {
-  var Path = computeRelativePath(Ref.Path, CurrentDirectory);
-  if (Ref.RefType == "namespace")
-    Path = append(Path, "index.html");
-  else
-    Path = append(Path, Ref.Name + ".html")
 
-    ANode = document.createElement("a");
+  ANode = document.createElement("a");
   ANode.setAttribute("href", Path);
   var TextNode = document.createTextNode(Ref.Name);
   ANode.appendChild(TextNode);
   return ANode;
 }
 
+function genHTMLOfIndex(Index, CurrentDirectory, IsOutermostList) {
+  // Out will store the HTML elements that Index requires to be generated
+  var Out = [];
+  if (Index.Name) {
+    var SpanNode = document.createElement("span");
+    var TextNode = document.createTextNode(Index.Name);
+    SpanNode.appendChild(genLink(Index));
+    Out.push(SpanNode);
+  }
+  if (Index.Children.length == 0)
+    return Out;
+  // Only the outermost list should use ol, the others should use ul
+  var ListNodeName = IsOutermostList ? "ol" : "ul";
+  var ListNode = document.createElement(ListNodeName);
+  for (Child of Index.Children) {
+    var LiNode = document.createElement("li");
+    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory, false);
+    for (Node of ChildNodes)
+      LiNode.appendChild(Node);
+    ListNode.appendChild(LiNode);
+  }
+  Out.push(ListNode);
+  return Out;
+}
+
 function genHTMLOfIndex(Index, CurrentDirectory, IsOutermostList) {
   // Out will store the HTML elements that Index requires to be generated
   var Out = [];

Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

I'm not completely sure we want to use absolute paths, but since this mostly seems related to URLs and not file system paths, its probably fine.

Please add some tests for this. It's preferable if we can pre-commit tests with the existing behavior, and then can easily see how this patch modifies the old/undesirable behavior.

Lastly, please update the title:

and update the description to describe what this fixes and how, and links to the GitHub issue using fixes or something equivalent from https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue

@ilovepi ilovepi requested a review from petrhosek May 24, 2024 17:26
@PeterChou1 PeterChou1 changed the title clang-doc switched from using relative to absolute paths [clang-doc] switched from using relative to absolute paths May 24, 2024
Copy link

github-actions bot commented Jun 29, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@PeterChou1 PeterChou1 force-pushed the clang-doc-abs-path branch from 48ceff1 to be0fb1a Compare June 29, 2024 09:16
Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

This is almost there. I've left a few minor comments, but I'd like to see better testing here. I'm awfully surprised we don't need to update any test lines, other than the 1 JS check. It would really help to see how the output is changing, if that was captured in the tests.

@@ -7,6 +7,7 @@
// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=HTML-RECTANGLE
// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=HTML-CIRCLE

// JSON-INDEX: var RootPath = "{{.*}}";
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a URL, right? if so, is there a reason it wouldn't match, regardless of platform? I'm a bit surprised this is the only change required to the tests, so I'm wondering if we're doing a good job checking things in our existing HTML tests.

Copy link
Contributor Author

@PeterChou1 PeterChou1 Jun 30, 2024

Choose a reason for hiding this comment

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

This isn't a url, this variable is a path to the directory where clang-doc is built from. I wanted the html to still render properly when viewed via the local filesystem so I added this export variable.
Most the changes that is reflected in this patch can only be seen once the browser loads the page and javascript generates the sidebar with the indexes, I don't think its possible to see the changes reflected unless we incorporate some sort javascript test framework. Another approach could be to just generate the indexes via the c++ html generator than we be able to see the changes.
I've added some test that test the different behaviour when we generate clang-doc via a relative path or an absolute one.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, then I'm not 100% sure we want to replace all the \ w/ /. I know you mentioned browser behavior, but I'm not 100% certain that's a great motivation. When I thought it was a URL, there's obviously no issue, but, for a file system path, I'm hesitant to say with confidence that there's no downside.

Also, given the test updates, IDK if this check is particularly useful. I don't see much difference in the check as is, and just

// JSON-INDEX: var RootPath =

Comment on lines 1 to 2
// RUN: rm -rf %t
// RUN: mkdir %t
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Can be one line w/ &&

// RUN: echo "CHECK: var RootPath = \"%/t/docs\";" > %t/check.txt
// RUN: cp "%s" "%t/test.cpp"
Copy link
Contributor

Choose a reason for hiding this comment

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

I see you're trying to work around the path inconsistency issues, but that's just an end-around our testing practices, and we shouldn't be doing it. Tests server as documentation, and generating a test w/ CHECK lines undermines that pretty significantly. IMO if the test isn't useful w/ the regular expression, it isn't useful. As it stands I also can't reason about how the behavior here is changing as a result of this patch, so I don' think this is a particularly good/useful check.

If possible, it would be good to add these tests in another patch(e.g. pre-commit them testing the current behavior), and then update these to make them pass. That requires either stacking the PR using spr, or just managing the github PRs carefully yourself. Either is fine.

// RUN: mkdir %t
// RUN: echo "CHECK: var RootPath = \"%/t/docs\";" > %t/check.txt
// RUN: cp "%s" "%t/test.cpp"
// RUN: clang-doc --format=html --executor=standalone -p %t %t/test.cpp --output=%t/docs
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: clang-doc --format=html --executor=standalone -p %t %t/test.cpp --output=%t/docs
// RUN: clang-doc --format=html --executor=standalone %s --output=%t

I don't think you need -p, and I don't see a good reason why you need a subdirectory for docs.

// RUN: echo "CHECK: var RootPath = \"%/t/docs\";" > %t/check.txt
// RUN: cp "%s" "%t/test.cpp"
// RUN: clang-doc --format=html --executor=standalone -p %t %t/test.cpp --output=%t/docs
// RUN: FileCheck %t/check.txt -input-file=%t/docs/index_json.js
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck %t/check.txt -input-file=%t/docs/index_json.js
// RUN: FileCheck %s -input-file=%t/index_json.js --check-prefix=SOME_PREFIX

@ilovepi
Copy link
Contributor

ilovepi commented Jul 10, 2024

any progress here?

@PeterChou1
Copy link
Contributor Author

any progress here?

I wanted to merge the test cases prs so we could view the regressions from the tests

@PeterChou1 PeterChou1 force-pushed the clang-doc-abs-path branch from da5b1c1 to 02a1c5a Compare July 24, 2024 22:48
Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

LGTM, but can we improve the check for RootPath somehow? I feel like there should be something we can match there.

// RUN: FileCheck %s -input-file=%t/index_json.js -check-prefix=JSON-INDEX
// RUN: rm -rf %t

// JSON-INDEX: var RootPath = "{{.*}}";
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to make this check more meaningful? Can we match nothing in the path itself?

@ilovepi
Copy link
Contributor

ilovepi commented Jul 24, 2024

Hmm, seems like tests are failing. PTAL.

@@ -0,0 +1,7 @@
// RUN: rm -rf %t && mkdir %t
// RUN: cp "%s" "%t/test.cpp"
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like I missed this. Please don’t copy the test file around. To be blunt this pattern has been brought up in multiple PRs and even in previous incarnations of this one. Use the same conventions we’ve insisted on in other tests here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, the reason why I kept using this pattern is because I copied the same test setups in the original test for clang-doc here and here

@PeterChou1 PeterChou1 merged commit 91450f1 into llvm:main Jul 25, 2024
7 checks passed
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
fixes #92867

This patches changes the way clang-doc index navigation works,
previously it was based a relative path approach, this approach is error
prone and lead to wrong paths for the anchor tag. The new navigation way
is based on absolute paths and should work and be less confusing
codewise.
Because the differences with serving over a http server and viewing via
file system I also added export a RootPath variable to the index_json.js
file

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250723
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang-Doc side bar not navigating correctly
3 participants