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

shell: TypeScript workflow demo #21265

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

mvollmer
Copy link
Member

@mvollmer mvollmer commented Nov 14, 2024

This is how I imagine working when bringing more TypeScript to Cockpit:

  • Some files are fully typed and tsc is fully happy with them. In this PR, that's pkg/shell/util.tsx.
  • Some files are quickly renamed to .ts or tsx and made "relaxed clean" without thinking hard about that. The idea is that the types provided by the "strict clean" files will help find bugs in those hastily converted files. In this PR this is state.tsx and we found two bugs in it already.
  • Then I would add more types to the "relaxed clean files, based on what I think is most helpful to its clients, until they are "strict clean". In this PR this would be fully typing ShellState and getting shell.jsx relaxed-clean. (This is happening in the shell-typing-2 branch, not here.)
  • And so on.

The idea is that I can do some typing work (in non-trivial files) that I find relevant and not too scary to take on, and then merge something that I know will be kept from regressing.

@mvollmer mvollmer force-pushed the shell-typing branch 2 times, most recently from cf7aa37 to d0ec28a Compare November 14, 2024 13:18
@mvollmer mvollmer changed the title shell: Some cleanups, some bug fixes, some TypeScript shell: Some cleanups, some TypeScript Nov 14, 2024
@mvollmer
Copy link
Member Author

state.tsx should cause a lot of typing errors, of which only one is interesting:

Property 'pathframe_change' does not exist on type 'Location'.

@mvollmer mvollmer force-pushed the shell-typing branch 3 times, most recently from 001b8a0 to 0aef6ae Compare November 14, 2024 15:18
@mvollmer mvollmer added the no-test For doc/workflow changes, or experiments which don't need a full CI run, label Nov 14, 2024
@mvollmer mvollmer force-pushed the shell-typing branch 3 times, most recently from e85ea9b to 605fbf1 Compare November 15, 2024 10:34
@mvollmer mvollmer changed the title shell: Some cleanups, some TypeScript shell: TypeScript workflow demo Nov 15, 2024
@mvollmer mvollmer marked this pull request as draft November 15, 2024 10:34
@mvollmer mvollmer mentioned this pull request Nov 15, 2024
1 task
@mvollmer mvollmer force-pushed the shell-typing branch 3 times, most recently from 008922d to a33cc13 Compare November 15, 2024 11:54
@mvollmer
Copy link
Member Author

state.tsx should cause a lot of typing errors, of which only one is interesting:

Aha, and after rebasing this on top of #20826, we get one more:

Type 'never[]' has no properties in common with type 'DBusCallOptions'.

Well done, TypeScript!

Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

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

Thanks @mvollmer! I'm excited about the general direction. I have a few questions and suggestions.

test/typecheck Show resolved Hide resolved
test/typecheck Outdated Show resolved Hide resolved
test/typecheck Outdated Show resolved Hide resolved
test/typecheck Show resolved Hide resolved
test/static-code Show resolved Hide resolved
pkg/lib/cockpit.d.ts Show resolved Hide resolved
pkg/shell/util.jsx Show resolved Hide resolved
pkg/shell/util.tsx Show resolved Hide resolved
pkg/lib/cockpit.d.ts Outdated Show resolved Hide resolved
pkg/shell/machines/machines.js Outdated Show resolved Hide resolved
@mvollmer mvollmer force-pushed the shell-typing branch 2 times, most recently from f9a1316 to 12fd679 Compare November 21, 2024 10:41
@mvollmer mvollmer force-pushed the shell-typing branch 4 times, most recently from 61d3f8b to c1bdb5b Compare November 27, 2024 10:25
@martinpitt
Copy link
Member

martinpitt commented Nov 27, 2024

not ok 10 /static-code/test-typescript
# pkg/shell/state.tsx(55,87): error TS2559: Type 'never[]' has no properties in common with type 'DBusCallOptions'.
# pkg/shell/state.tsx(428,39): error TS2339: Property 'pathframe_change' does not exist on type 'Location'.

@mvollmer
Copy link
Member Author

not ok 10 /static-code/test-typescript
# pkg/shell/state.tsx(55,87): error TS2559: Type 'never[]' has no properties in common with type 'DBusCallOptions'.
# pkg/shell/state.tsx(428,39): error TS2339: Property 'pathframe_change' does not exist on type 'Location'.

Yes! :-) That's the point of this PR. We have to fix them. of course. What do you think of the rest now?

@mvollmer mvollmer removed the no-test For doc/workflow changes, or experiments which don't need a full CI run, label Nov 27, 2024
Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

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

Cheers! This is coming along nicely.

test/static-code Show resolved Hide resolved
pkg/lib/cockpit.d.ts Show resolved Hide resolved
pkg/shell/util.tsx Show resolved Hide resolved
pkg/shell/util.tsx Outdated Show resolved Hide resolved
pkg/lib/cockpit.d.ts Show resolved Hide resolved
Instead of running tsc directly.
To reduce the complexity of the Shell slightly.

The build_href function is special in that it constructs a string for
a Location object without including the configured URL root of this
Cockpit instance.

The only point of this is to create strings that can be passed to
ShellState.jump. They also show up in href attributes, but they never
really should.

So, let's never pass a string to ShellState.jump and just pass the
Location object directly.
The conection string functions are moved to machines/machines so that
util can use types from machines/machines without causing a dependency
cycle.

CompiledComponents has been rewritten as a proper class. This is the
Right Thing(tm) for TypeScript.
The "state" file now participates in type checking, but we still allow
the "any" type.  TypeScript will automatically infer "any" in many
places and shut up.  Later we can add more types, which will mean a
rewrite of ShellState as a proper class.
@mvollmer mvollmer marked this pull request as ready for review November 28, 2024 09:58
Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

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

Thanks! This looks nice to me now, and I'm looking forward to reaping a lot more benefits from our pkg/lib and cockpit.js typing efforts. Thanks!

But @jelly may also have an opinion here, so I'd also let him review that if he wants to.

Comment on lines +148 to +152
<a className="pf-v5-c-nav__section-title nav-item"
href={encode_location(g.action.target)}
onClick={ ev => {
this.props.jump(g.action.target);
ev.preventDefault();
Copy link
Contributor

Choose a reason for hiding this comment

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

These 5 added lines are not executed by any test.

Comment on lines +154 to +155
{g.action.label}
</a>
Copy link
Contributor

Choose a reason for hiding this comment

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

These 2 added lines are not executed by any test.

@@ -356,10 +363,10 @@ export const PageNav = ({ state }) => {
if (current_machine_manifest_items.items.apps && groups.length === 3)
groups[0].action = {
label: _("Edit"),
path: build_href({
target: {
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

host: current_machine.address,
path: current_machine_manifest_items.items.apps.path
})
path: current_machine_manifest_items.items.apps.path,
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

@@ -75,26 +79,23 @@ export function ShellState() {

machines.addEventListener("ready", on_ready);

machines.addEventListener("removed", (ev, machine) => {
machines.addEventListener("removed", (_, machine) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

export function encode_location(location: Location): string {
const shell_embedded = window.location.pathname.indexOf(".html") !== -1;
if (shell_embedded)
return window.location.toString();
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

section,
label: cockpit.gettext(info.label) || prop,
label: info.label ? cockpit.gettext(info.label) : prop,
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

const compiled = new CompiledComponents(manifests);
compiled.load("tools");
compiled.load("dashboard");
compiled.load("menu");
return compiled;
}

function component_checksum(machine, path) {
function component_checksum(machine: Machine, path: string): string | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

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

This added line is not executed by any test.

@martinpitt
Copy link
Member

@jelly gentle review ping?

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.

3 participants