8000 feat(respec2html): intercept and replace ReSpec with in-tree build by foolip · Pull Request #2702 · speced/respec · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(respec2html): intercept and replace ReSpec with in-tree build #2702

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

Closed
wants to merge 1 commit into from

Conversation

foolip
Copy link
Contributor
@foolip foolip commented Jan 7, 2020

No description provided.

@foolip
Copy link
Contributor Author
foolip commented Jan 7, 2020

This is in a draft state, but I want feedback so submitting as a non-draft PR. The purpose of this would be to avoid a repeat of what happened in w3c/reffy#205 by pinning the version of ReSpec used by Reffy.

This approach isn't perfect as ReSpec could be served from elsewhere, most plausibly a local copy for the spec.

Is there a better way to achieve the same goal? If this approach is generally reasonable, should it be behind a flag and how should it be tested?

@foolip foolip force-pushed the respecDocWriter-intercept branch from 0e2d1c6 to 708269e Compare January 7, 2020 12:26
// Intercept requests for ReSpec and serve it from the local build instead.
// https://github.com/tidoust/reffy/pull/212
await page.setRequestInterception(true);
page.on("request", async function callback(request) {
Copy link
Collaborator
@saschanaz saschanaz Jan 7, 2020

Choose a reason for hiding this comment

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

@sidvishnoi, I believe your netlify work does similar work to load the spec with a specified build, am I right?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, but in a service worker. https://respec-preview.netlify.com/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is that https://github.com/w3c/respec/blob/develop/tools/netlify.js? Where's the logic to replace the ReSpec version?

Are there changes to ReSpec itself that could be made to make this kind of replacing more robust? I'm thinking maybe having the script load but do nothing, or post a message saying "please inject your own ReSpec now"?

Copy link
Member

Choose a reason for hiding this comment

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

Using a regex to replace commonly used ReSpec scripts: https://github.com/sidvishnoi/respec-preview/blob/master/sw.js

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, that's not far from what I'm doing, both hostname and the first part of the pathname need to match exactly. My version would also match anything else that's in the build/ directory, but I don't know that it's needed. The code I have now would only replace the first request so I expect it's actually broken in some cases.

@sidvishnoi
Copy link
Member

The purpose of this would be to avoid a repeat of what happened in w3c/reffy#205 by pinning the version of ReSpec used by Reffy.

While it certainly wasn't a good experience with ReSpec changes breaking Reffy, I'm not sure this approach of locking down ReSpec version is good idea. Do you plan to lock down to a major version or minor version?
We already put efforts to make sure breaking changes are not breaking things without being warned (we generally create issues/PR for affected stuff before release). FWIW, w3c@7faae15 wasn't even a breaking change. (Relevant xkcd)

If still desired, this change should be behind a flag though.

@saschanaz
Copy link
Collaborator
saschanaz commented Jan 8, 2020

If still desired, this change should be behind a flag though.

I think this should be by default, as that's what we expect for a versioned package. Ignoring its own version by default is a weird behavior.

This is one of my purpose in #2187, although no recent progress there.

@foolip
Copy link
Contributor Author
foolip commented Jan 8, 2020

Do you plan to lock down to a major version or minor version?

The version used will be bumped automatically with PRs like w3c/reffy#216, so it'll be updated continuously. Like most version pinning, the purpose would be to have control over when the dependency changes, so that one can deal with the change before it affects the master branch / production.

That being said, I'd defer to @tidoust on how important it is to pin the ReSpec version.

@sidvishnoi
Copy link
Member

Makes sense. I was concerned as specs are using latest versions, and if tools are using a different version than the spec, it might lead to inconsistencies. For example, we made some change in ReSpec and the spec reflected it (by changing markup etc.), but it was incompatible with ReSpec version being used at Reffy and other tools.

@foolip
Copy link
Contributor Author
foolip commented Jan 8, 2020

Specs that are using https://www.w3.org/Tools/respec/respec-w3c are betting that there won't be any backwards incompatible changes, but may of course be quick to use new features once released. I suspect that the risk of breakage due to that is pretty low, however, as long as updates in Reffy lag behind only a few days.

@sidvishnoi
Copy link
Member

Tried to make tests pass and simplified profile finding logic a bit

    // Intercept requests for ReSpec and serve it from the local build instead.
    // https://github.com/tidoust/reffy/pull/212
    if (!new URL(src).hostname.includes("localhost")) { // this line prevents tests:headless from failing
      await page.setRequestInterception(true);
      const respecProfileRegex = /((?:respec-w3c)(?:-common)?)/;

      /** @param {URL} url */
      const isRespecRequest = url => {
        return (
          url.hostname.includes("w3.org") &&
          respecProfileRegex.test(url.pathname)
        );
      };

      page.on("request", async function requestInterceptor(request) {
        const url = new URL(request.url());
        if (!isRespecRequest(url)) {
          await request.continue();
          return;
        }
        const profile = url.pathname.match(respecProfileRegex)[1];
        const localPath = path.join(__dirname, "..", "builds", `${profile}.js`);
        console.log(`Intercepted ${url} to respond with ${localPath}`);
        await request.respond({
          contentType: "text/javascript; charset=utf-8",
          body: await readFile(localPath),
        });
        // Workaround for https://github.com/puppeteer/puppeteer/issues/4208
        page.removeListener("request", requestInterceptor);
        await page.setRequestInterception(false);
      });
    }

@tidoust
Copy link
Contributor
tidoust commented Jan 9, 2020

@foolip noted:

That being said, I'd defer to @tidoust on how important it is to pin the ReSpec version.

Ah. I don't really know :)

In the short term, that seems useful to avoid situations where crawls generate invalid PRs against Web Platform Tests. I don't know what the right strategy is in the long run. That is, it might be better to check assumptions that Reffy has regarding document structure (e.g. how to find WebIDL extracts or identify informative sections in a ReSpec spec, how to identify informative sections, etc.) before a crawl runs and prevent PRs from being created when something breaks, instead of pinning down the version of ReSpec which requires a manual intervention each time there is a ReSpec update. And/Or, and that's perhaps even easier, we could simply run the WebIDL parser on the extracted WebIDL in Reffy (which we actually already do) and only submit PRs to Web Platform Tests when parsing succeeds.

As a side note, Reffy may stop using respecDocWriter altogether at some point: Reffy parses non ReSpec specs as well and since respecDocWriter needs Puppeteer, we could just as well use Puppeeter throughout and run our extraction logic there directly (instead of relying on JSDOM). That would make processing less convoluted and allow us to drop a few dependencies. I'd grab the code proposed here if we do that.

@foolip
Copy link
Contributor Author
foolip commented Jan 16, 2020

Thanks for the discussion everyone. It sounds from @tidoust like Reffy will likely move away from using this tool in favor of loading the spec in Puppeteer directly, in which case any support I add here will be unused.

I'm going to close this, but if anyone else using respec2html would like it, then you're free to cherry pick and continue working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0