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

Fix last updated time misleading, only show when file content change or otherwise when it first created #1023

Merged
merged 5 commits into from
Oct 14, 2018

Conversation

fiennyangeln
Copy link
Contributor

Motivation

Fix #1015

Have you read the Contributing Guidelines on pull requests?

Yes

Test Plan

  1. run `git log --follow --summary [some file relative path]
  2. see the result and capture the last date where commit is about content change not rename / move
  3. Run the localhost for v1 (cd v1 && yarn start), check in the site

Related PRs

No

@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Oct 8, 2018
@docusaurus-bot
Copy link
Contributor

docusaurus-bot commented Oct 8, 2018

Deploy preview for docusaurus-preview ready!

Built with commit b38dd21

https://deploy-preview-1023--docusaurus-preview.netlify.com

Copy link
Contributor

@yangshun yangshun left a comment

Choose a reason for hiding this comment

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

This looks awesome @fiennyangeln! I have some minor comments but we're good to land this after they're addressed.

const timeSpan = spawn
.sync('git', ['log', '-1', '--format=%ct', filepath])
.stdout.toString('utf-8');
// To differentiate between content change and file renaming / moving, use --summary
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for only noticing this now, but we should add a try/catch around the code within getGitLastUpdated and return null in the catch case something blows up (for instance, git is not installed on the device, or if the repository is a Mercurial-based one).

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually im hoping we remove cross-spawn dependency and use existing shelljs to call the bash command.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@endiliey yeah i see some v2 code uses shell.exec()

Copy link
Contributor

Choose a reason for hiding this comment

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

V1 too. Check v1/lib/publish-pages.js

@@ -38,10 +38,37 @@ function idx(target, keyPaths) {
);
}

function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)$/.test(str);
Copy link
Contributor

Choose a reason for hiding this comment

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

Use this regex instead: ^\d+$, which is simpler. This regex means the line only contains integers. Check out https://regex101.com/r/mp3HYD/2/

Copy link
Contributor

Choose a reason for hiding this comment

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

It should be noted that above (fienny's PR) allow an optional + at the beginning of string

Yangshun's recommended regex doesnt allow that.

If the optional + is intended, use /^\+?\d+$/

Copy link
Contributor

@endiliey endiliey Oct 9, 2018

Choose a reason for hiding this comment

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

Wondering if there is normal and abnormal integer from the function naming.

isInt is fine o.o

Copy link
Contributor

Choose a reason for hiding this comment

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

The numbers are timestamps, why do we need the +? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yangshun yup i dont think we need the +

.split('\n')
.filter(String);

const timeSpan = records.find(
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks right, but could you test on a file that only has one commit?

Could you also test on files that have 0 commits, aka newly-created files that haven't been checked into Git yet. I suspect we this part might crash.

We don't want the page to blow up for any newly-created pages else they wouldn't be able to preview it.

Copy link
Contributor Author

@fiennyangeln fiennyangeln Oct 10, 2018

Choose a reason for hiding this comment

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

We currently have test that check for file with only one commit, non existing and those with no git timestamp in here v1/lib/core/__tests__/utils.test.js

.filter(String);

const timeSpan = records.find(
(item, index, arr) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rewrite this part as such to make the logic clearer:

const timeSpan = records.find((item, index, arr) => {
  const isTimestamp = isNormalInteger(item);
  const isLastItem = index + 2 <= arr.length; // Note: Let's use  <= instead of === to be safer.
  const nextItemIsTimestamp = isNormalInteger(arr[index + 1]);
  return isTimestamp && (isLastItem || nextItemIsTimestamp);
});

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 think if we use <= it will return true for all element except the last

Copy link
Contributor

@endiliey endiliey left a comment

Choose a reason for hiding this comment

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

See review

- Uses shelljs instead of cross-spawn
- Make logic clearer
@fiennyangeln fiennyangeln force-pushed the fix/last-updated-time branch 3 times, most recently from c10ef21 to d0eab47 Compare October 10, 2018 16:09
Copy link
Contributor

@JoelMarcey JoelMarcey left a comment

Choose a reason for hiding this comment

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

After a quick chat with @endiliey and @yangshun, we probably don't want to execute git commands in directly within the unit tests.

@yangshun - I like the mocking idea. Could you provide a suggestion to @fiennyangeln on how to do that?

const tempFilePath2 = path.join(__dirname, '__fixtures__', '.temp2');
fs.writeFileSync(tempFilePath2, 'Lorem ipsum :)');

shell.exec(`git add ${tempFilePath2}`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't execute shell commands in tests. Use Jest mocking to mock out the entire shell module and the methods that your method calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay!!! Will try it :D

@yangshun
Copy link
Contributor

@JoelMarcey Have left some comments 😄

Thanks for your patience @fiennyangeln!

I initially try to mock the whole shelljs. But it returns error
shell.exec is not a function when i try to provide the mockResolvedValue
I think it is because of the inner code of shelljs who run a forEach to
require each of its method which make it a promise. I tried moving the
jest.mock inside beforeAll and also adding babel-dynamic-import but it did
not solve the problem. In the end, I decided to just mock shelljs.exec since
it is the only function used anyway
@fiennyangeln
Copy link
Contributor Author

I initially try to mock the whole shelljs. But it returns error shell.exec is not a function when i try to provide the mockResolvedValue. I think it is because of the inner code of shelljs who run a forEach to
require each of its method which make it a promise. I tried moving the jest.mock inside beforeAll and also adding babel-dynamic-import but it did not solve the problem. In the end, I decided to just mock shelljs.exec since it is the only function used anyway

@fiennyangeln
Copy link
Contributor Author

@yangshun please review :D

Copy link
Contributor

@yangshun yangshun left a comment

Choose a reason for hiding this comment

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

LGTM. @fiennyangeln Thanks for fixing! There are some small improvements that can be made but I'll address them 😄

@yangshun yangshun merged commit a39677c into facebook:master Oct 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Signed Facebook CLA
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants