Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

(Archived) Adopt TypeScript #1497

Closed
wants to merge 12 commits into from
Closed

(Archived) Adopt TypeScript #1497

wants to merge 12 commits into from

Conversation

artem-zakharchenko
Copy link
Contributor

@artem-zakharchenko artem-zakharchenko commented Sep 16, 2019

🚀 Why this change?

  • Adds Prettier
  • Introduces basic TypeScript stack to Dredd
  • Adjusts source code and tests to use ES6 syntax
  • Provides a minimum of types annotations to basic utility functions

📝 Related issues and Pull Requests

✅ What didn't I forget?

  • To write docs (not applicable, except contribution docs)
  • To write tests
  • To put Conventional Changelog prefixes in front of all my commits and run npm run lint
  • Adjust CircleCI
  • Adjust AppVeyor
  • Remove Rollup and related dependencies, because the build is performed by TypeScript compiler

// This is to allow a convention for exporting functions solely for
// the purpose of the unit tests, see
// https://github.com/apiaryio/dredd-transactions/pull/179#discussion_r206852270
'no-underscore-dangle': 'off',

'import/prefer-default-export': 'off',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allows export const a = 'anything' exports from files.

  • Makes internals easier to export for testing
  • Doesn't pollute the default export

@artem-zakharchenko artem-zakharchenko force-pushed the 1186-future branch 6 times, most recently from 8d15e7a to 1682d97 Compare September 23, 2019 10:28
@artem-zakharchenko artem-zakharchenko force-pushed the 1186-future branch 11 times, most recently from 37cc40a to 3c2d7ad Compare September 23, 2019 12:49
@artem-zakharchenko artem-zakharchenko force-pushed the 1186-future branch 2 times, most recently from 9164de5 to c94e583 Compare September 24, 2019 13:30
@artem-zakharchenko
Copy link
Contributor Author

CircleCI build is passing. Switching to configure AppVeyor to include build step in the CI.

@artem-zakharchenko artem-zakharchenko changed the title Adds TypeScript Adopt TypeScript Sep 24, 2019
@artem-zakharchenko
Copy link
Contributor Author

@kylef, could you please review?

Mainly CI configs and build setup, but I'd be thankful for a few files I've migrated to TypeScript too. Note that as of now Dredd won't emit any type definitions because that's incompatible with allowJs option that enables js/ts codebase. We would need to rewrite all existing modules to TypeScript for it to emit definition files, it seems.

Copy link
Member

@kylef kylef left a comment

Choose a reason for hiding this comment

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

Filing initial review, I have not look at the .ts and .js files yet in the diff and only the surrounding configuration changes. Working on that next but I think it will take a bit of time and I don't think I'll get it done today.

For future, i'd consider breaking down the PR into separate sections:

  • Prettifier
    • Initial PR could have little diff if there was prettifier config to make existing code style, then you could incrementally make separate PRs changing rules to their defaults.
  • TypeScript

.circleci/config.yml Outdated Show resolved Hide resolved
.eslintrc.js Show resolved Hide resolved
Copy link
Member

@kylef kylef left a comment

Choose a reason for hiding this comment

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

Reviewed up until lib/configUtils.js

lib/CLI.js Outdated Show resolved Hide resolved
lib/CLI.js Outdated Show resolved Hide resolved
lib/CLI.js Outdated Show resolved Hide resolved
lib/Dredd.js Outdated Show resolved Hide resolved
this.beforeEachValidation = this.beforeEachValidation.bind(this)
this.afterEach = this.afterEach.bind(this)
this.log = this.log.bind(this)
;({ logs: this.logs, logger: this.logger } = options)
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't seem like the semi-colons are removed in the other files I've reviewed so far, why are they removed from other lines in this file and inserted at the start of this line instead of the end of the prior line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. I will align semicolons consistency and remove them from the source code altogether.
  2. Because ({ logs: this.logs, logger: this.logger } = options) is not a valid expression per formatting tools, so it appends an explicit semicolon in no-semi mode to let it be evaluated properly (and not the part of the previous expression).

Copy link
Contributor

Choose a reason for hiding this comment

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

That's black sorcery. Can we replace all expressions starting with a semicolon with some boring JavaScript code?

this.logs = options.logs
this.logger = options.logger

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, sure. Moreover, we can replace them in the original code as one of the first PRs:

({ logs: this.logs, logger: this.logger } = options);

lib/childProcess.js Outdated Show resolved Hide resolved
Copy link
Contributor

@honzajavorek honzajavorek 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 unable to review the PR. I went through tens of files, but it's so tedious I give up. Even the GitHub UI is responding slowly. This needs to be broken down into smaller PRs and rolled out incrementally.

E.g. there are codebase-wide changes, such as removing the semicolons. Such change can be perfectly done as a single PR titled "Remove semicolons from the codebase", where all content is automated and cognitively easy-to-review (despite the huge amount of changes made). Having that as a separate change removes tens of files from the diffs on any subsequent PR representing the TS migration and makes reviewing easier as I don't have to question my mind "is this line changed only because of a semicolon or does it contain additional refactoring?" 100% of time. I used semicolons as a blatant example, but I can see many parts of the changes in the PR, which can be separated out, issued as an easy-to-review PR, and released as an easy-to-fix-if-shit-happened increment. Such steps can be introducing of Prettier (without any manual edits, those sent as a separate commit or PR), change from requires to imports, etc. Especially manual refactorings made on the code should be sent separately as those should stand out and be reviewed carefully. The way it is now they're sunk in reformats made by Prettier. If some files are rewritten to TS and some are not, the rewritten ones should be sent as separate, incremental PRs.

I know I haven't been the best example in the past in issuing nice, small changes, but we need to start somewhere. I'll be the bad guy today and please, do revenge on my PRs in the future if they're too big.

jobs:
build:
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it need to be tested separately if it's a part of all the other jobs?

Copy link
Contributor

Choose a reason for hiding this comment

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

Besides, this job isn't included in the workflow, so it isn't currently being ran.

image: circleci/python:3.6-node

- &test-steps
steps:
- checkout
- npm-install
- run: npm run build
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the build be an explicit step or should it be implicitly included as something like pretest script?

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've tried to perform a build once and store it, but since its quite fast, we've decided with @kylef that such setup may be an overkill (attaching a workspace with the build takes multiple times longer than the build itself). I'm okay to revisit this, if you find it necessary.

@@ -0,0 +1,2 @@
# Prevent publishing source code to NPM
lib
Copy link
Contributor

Choose a reason for hiding this comment

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

});
}
if (typeof options === 'function') {
;[options, callback] = [{}, options]
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the purpose of the semicolon 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.

To support initially invalid JavaScript syntax. I kept an intention to do as less changes to the existing code base as possible.

this.beforeEachValidation = this.beforeEachValidation.bind(this)
this.afterEach = this.afterEach.bind(this)
this.log = this.log.bind(this)
;({ logs: this.logs, logger: this.logger } = options)
Copy link
Contributor

Choose a reason for hiding this comment

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

That's black sorcery. Can we replace all expressions starting with a semicolon with some boring JavaScript code?

this.logs = options.logs
this.logger = options.logger

@artem-zakharchenko
Copy link
Contributor Author

artem-zakharchenko commented Sep 30, 2019

Thanks for attempts, @honzajavorek. I understand your pain and would like to address it. I'm fine with splitting this PR into multiple, but you need to be aware of certain implications, and that some steps of these changes cannot be rolled out separately.

"is this line changed only because of a semicolon or does it contain additional refactoring?"

Very easy: no, this pull request contains 0 refactoring done in JavaScript files. My bad if I haven't communicated this properly, I've commented this to one of the Kyle's points, but this should've been attached in the PR's description.

If some files are rewritten to TS and some are not, the rewritten ones should be sent as separate, incremental PRs.

Sounds like a good idea. I'm for it.

E.g. there are codebase-wide changes, such as removing the semicolons. Such change can be perfectly done as a single PR titled "Remove semicolons from the codebase"

Well, not really. Semicolons are preserved in the source code because it is the code run by Node. The older versions of Node cannot cope with semicolons' absence, so you cannot remove them from the source code unless you introduce a build step that would ensure them.


Pull requests pipeline

I can suggest the next sequence of Pull request to be made:

But beware that certain changes will be big, you cannot break down related changes (i.e. you can't introduce TS and change testing setup in two separate pull requests, the build simply won't pass).

@honzajavorek
Copy link
Contributor

👍 makes sense. If we could have big PRs at least consisting of commits each containing one kind-of-atomic change (like semicolons), that would also make the review easier. This PR contained some back-and-forth changes in the commits, which discouraged me to go commit-by-commit.

@artem-zakharchenko
Copy link
Contributor Author

@honzajavorek, yeah, that's true. It was a discovery road for me, so some things went back and forth. Next pull request will be cleaner based on the knowledge I've gather during this implementation.

@honzajavorek
Copy link
Contributor

I completely understand, my PRs usually look very similar 🙂 When they grow big, I roll up my sleeves and dive into breaking them down and rebasing into something smaller.

When I was alone in the team, @kylef was always nice to never be too harsh about my big PRs, but he got me positively motivated by naturally procrastinating reviews on them. I knew that small PRs will get through faster 😄

@artem-zakharchenko artem-zakharchenko mentioned this pull request Oct 1, 2019
3 tasks
@artem-zakharchenko artem-zakharchenko changed the title Adopt TypeScript (Archived) Adopt TypeScript Oct 3, 2019
@artem-zakharchenko
Copy link
Contributor Author

Closed in favor of #1530

@artem-zakharchenko artem-zakharchenko deleted the 1186-future branch October 3, 2019 12:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants