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

Use dprint for internal formatting #6682

Merged
merged 39 commits into from
Jul 14, 2020

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Jul 7, 2020

Previously: 17.5s
Now: 5s (~2.2s of that is dprint)
With Rustfmt dprint plugin: 3.75s (didn't use this because I wouldn't recommend using that until I start making automatic builds for rustfmt)

Todo:

By the way, the markdown plugin now also formats code blocks based on the code block tag, so if there's a typescript or ts code block it will request formatting a .ts file from the CLI, which will then pick up the plugin that supports .ts files and format the code block using that. This also works for js and json code blocks (also supports rust code blocks if using the rustfmt plugin, which this is not).

Closes #4307

.dprintrc.json Outdated Show resolved Hide resolved
command.append(source_files.pop())
if len(" ".join(command)) > max_command_length:
break
run(command, shell=False, quiet=True)
Copy link
Member Author

Choose a reason for hiding this comment

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

If we were to maintain this functionality, then I think this code would have to know which files are ignored/excluded. See my comments here and let me know if I'm wrong: dprint/dprint#258

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, see my comments here about possibly adding "--git-staged" to dprint: dprint/dprint#255 (don't want to do it)

I think perhaps we should consider removing this git staged functionality from this script? It runs decently fast now as-is.

tools/format.py Outdated Show resolved Hide resolved
@dsherret dsherret marked this pull request as ready for review July 7, 2020 20:31
if: matrix.config.kind == 'lint'
with:
path: ~/.cache/dprint
key: ${{ runner.os }}-dprint-plugins-${{ hashFiles('.dprintrc.json') }}
Copy link
Member Author

Choose a reason for hiding this comment

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

I think this should be matrix.config.os actually...

Copy link
Member

Choose a reason for hiding this comment

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

The plugins are wasm files? What are these? Can they go in third_party/prebuilt? I don't like this added complexity to the CI...

Copy link
Member Author

Choose a reason for hiding this comment

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

When running the first time it needs to download the .wasm files, compile them for the platform, and save the result. This takes anywhere between 2-10s per plugin. After doing this, plugins load quite quickly in about 5-45ms.

So the cache contains the result of downloading & compiling and enables the quick startup times. If we don't want this here, we could move the .wasm files to third_party and apparently compiling is going to be sped up significantly in the next major release of wasmer (I have yet to test it out though I do have access to it). The plugins themselves are between 3-5mb each.

I think it's less complexity and maintenance in the long run to just keep this here though... It's a one time thing we don't have to worry about after and updating the plugins is easy because the urls just need to be changed in the config file.

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather have them in third_party than add another root directory.

Alternatively can we opt out of the wasm business and use prettier for markdown? Not super keen on introducing another wasm runtime just for formatting markdown.

Copy link
Member Author

@dsherret dsherret Jul 8, 2020

Choose a reason for hiding this comment

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

I'm not sure what you mean by root directory? The cached compiled plugins are stored in ~/.cache/dprint.

The specific wasm runtime used is an implementation detail that's hidden in the binary. Regardless of what runtime is chosen internally, some caching would be necessary to improve startup times (again, getting it down to 5-45ms to load a plugin).

All the plugins are wasm modules including the typescript formatting. The CLI has no knowledge of the plugins unless they're specified in the configuration file (see the "plugins" array). This allows upgrading plugins by bumping the version url in the config file rather than having to update the CLI binary and also allows for multiple projects to use different versions of plugins that use the same CLI. Since they're wasm modules, they run sandboxed and are portable across systems.

I will work on this issue to support importing plugins from a file path and the compile times should be reasonable for the CI in order to remove this, but I think storing the plugins in third_party is a higher maintenance cost than what's currently done here.

Copy link
Member

Choose a reason for hiding this comment

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

Ok thanks for clarifying. Sounds reasonable.

Sure let's go with this added complication to the CI. Maybe add a comment explaining a bit why this is necessary?

Not sure the if: matrix.config.kind == 'lint' helps. Maybe remove that line?

Copy link
Member Author

@dsherret dsherret Jul 9, 2020

Choose a reason for hiding this comment

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

Sounds good!

By the way, I was thinking about this more and if I parallelize plugin downloading and compiling internally within dprint (right now it downloads and compiles the plugins one after the other) it actually might not add too much time to the CI. I'll try it out with and without and report back with how long they took. It may be that it's not worth the added complexity here in order to save a few seconds. Work will be done in dprint/dprint#222

Edit: Oh wait, I bet these actions are only running with one core. Anyway, I'll see how it goes.

Copy link
Member

Choose a reason for hiding this comment

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

Edit: Oh wait, I bet these actions are only running with one core. Anyway, I'll see how it goes.

2 core, 7 GB of RAM, 14 GB of disk: https://docs.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources

Copy link
Member Author

Choose a reason for hiding this comment

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

Investigated. 6s format + 1s cache restore with, 13 seconds without, but without probably has higher variability based on download speeds.

I think I'll just remove this to reduce complexity as adding a few seconds to the lint action isn't so bad. Let me know if I should restore this.

tools/third_party.py Outdated Show resolved Hide resolved
Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

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

Exciting development!

command = ["node", script, "--write", "--loglevel=error", "--"]
while len(source_files) > 0:
command.append(source_files.pop())
if len(" ".join(command)) > max_command_length:
Copy link
Member Author

@dsherret dsherret Jul 12, 2020

Choose a reason for hiding this comment

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

Interestingly, this max_command_length was being hit so there were 240 files not being formatted in Deno's codebase.

(I was wondering why I was getting a bunch of files that looked like they'd never been run through a formatter before.)

Copy link
Member Author

@dsherret dsherret Jul 13, 2020

Choose a reason for hiding this comment

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

I misread the code here so it's not 240 files, but it is a handful of files as if it pops from source_files and exceeds max_command_length then that popped file is not formatted. Nope. I can't read code. Not sure why some files were being missed.

@ry
Copy link
Member

ry commented Jul 13, 2020

I tried this out and it's working well! Very nice.

@bartlomieju bartlomieju added the build build system or continuous integration related label Jul 14, 2020
Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

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

Looks good David. Can we land this, or do you want to finish the last item on your check list?

@dsherret
Copy link
Member Author

@ry oh sorry, I was waiting on the go ahead for that. Yeah, I'll merge, do that last item then we should be good!

@dsherret
Copy link
Member Author

@ry this is good to merge

Copy link
Member

@ry ry 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 David!

@ry ry merged commit cde4dbb into denoland:master Jul 14, 2020
@dsherret dsherret deleted the dprintInternalFormatting branch July 14, 2020 19:24
@David-Else
Copy link

@dsherret Reading above it seems that Deno should be able to format code blocks in markdown , but deno fmt test.md gives me:

test.md

# Modern Typescript with Examples Cheat Sheet
   Line 1, column 1: Unexpected token `#`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, ` for template literal, (, or an identifier

  # Modern Ty
  ~

On the very first # heading, never mind the actual code blocks.

If it is supported, is this file feasible? It works great in Prettier at the moment.

https://raw.githubusercontent.com/David-Else/modern-typescript-with-examples-cheat-sheet/master/README.md

I am using deno 1.3.2, thanks!

caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 21, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Feb 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build build system or continuous integration related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate from prettier to dprint for internal formatting
5 participants