From 26a66e8f457b03a3f018448af2c0d7957827a4b6 Mon Sep 17 00:00:00 2001 From: damithc Date: Wed, 4 Sep 2024 18:37:40 +0800 Subject: [PATCH] Site Update. [skip ci] --- README.html | 2 +- README.page-vue-render.js | 2 +- about.html | 2 +- about.page-vue-render.js | 2 +- conventions/csharp.html | 2 +- conventions/csharp.page-vue-render.js | 2 +- conventions/css.html | 2 +- conventions/css.page-vue-render.js | 2 +- conventions/files.html | 2 +- conventions/files.page-vue-render.js | 2 +- conventions/git.html | 2 +- conventions/git.page-vue-render.js | 2 +- conventions/github.html | 2 +- conventions/github.page-vue-render.js | 2 +- conventions/html.html | 2 +- conventions/html.page-vue-render.js | 2 +- conventions/java/basic.html | 2 +- conventions/java/basic.page-vue-render.js | 2 +- conventions/java/index.html | 2 +- conventions/java/index.page-vue-render.js | 2 +- conventions/java/intermediate.html | 2 +- .../java/intermediate.page-vue-render.js | 2 +- conventions/java/logging.html | 2 +- conventions/java/logging.page-vue-render.js | 2 +- conventions/javascript.html | 2 +- conventions/javascript.page-vue-render.js | 2 +- conventions/markdown.html | 2 +- conventions/markdown.page-vue-render.js | 2 +- guidelines/PRs-reviewing.html | 2 +- guidelines/PRs-reviewing.page-vue-render.js | 2 +- guidelines/PRs.html | 2 +- guidelines/PRs.page-vue-render.js | 2 +- guidelines/codeOfConduct.html | 2 +- guidelines/codeOfConduct.page-vue-render.js | 2 +- guidelines/commits.html | 2 +- guidelines/commits.page-vue-render.js | 2 +- guidelines/labels.html | 2 +- guidelines/labels.page-vue-render.js | 2 +- index.html | 2 +- index.page-vue-render.js | 2 +- tutorials/ab3.html | 2 +- tutorials/ab3.page-vue-render.js | 2 +- tutorials/ab3AddRemark.html | 2 +- tutorials/ab3AddRemark.page-vue-render.js | 2 +- tutorials/ab3RemovingFields.html | 2 +- .../ab3RemovingFields.page-vue-render.js | 2 +- tutorials/ab3TracingCode.html | 2 +- tutorials/ab3TracingCode.page-vue-render.js | 2 +- tutorials/checkstyle.html | 2 +- tutorials/checkstyle.page-vue-render.js | 2 +- tutorials/codecov.html | 12 +++++++----- tutorials/codecov.page-vue-render.js | 13 +++++-------- tutorials/githubActions.html | 2 +- tutorials/githubActions.page-vue-render.js | 2 +- tutorials/gradle.html | 2 +- tutorials/gradle.page-vue-render.js | 2 +- tutorials/images/codecov/coverage-example.png | Bin 69521 -> 44032 bytes tutorials/images/codecov/select-repo.png | Bin 0 -> 73235 bytes tutorials/intellijCodeStyle.html | 2 +- .../intellijCodeStyle.page-vue-render.js | 2 +- tutorials/intellijDebugger.html | 2 +- tutorials/intellijDebugger.page-vue-render.js | 2 +- tutorials/intellijImportGradleProject.html | 2 +- ...llijImportGradleProject.page-vue-render.js | 2 +- tutorials/intellijJdk.html | 2 +- tutorials/intellijJdk.page-vue-render.js | 2 +- tutorials/intellijUsefulSettings.html | 2 +- .../intellijUsefulSettings.page-vue-render.js | 2 +- tutorials/jar.html | 2 +- tutorials/jar.page-vue-render.js | 2 +- tutorials/javaFx.html | 2 +- tutorials/javaFx.page-vue-render.js | 2 +- tutorials/javaFxPart1.html | 4 ++-- tutorials/javaFxPart1.page-vue-render.js | 4 ++-- tutorials/javaFxPart2.html | 2 +- tutorials/javaFxPart2.page-vue-render.js | 2 +- tutorials/javaFxPart3.html | 2 +- tutorials/javaFxPart3.page-vue-render.js | 2 +- tutorials/javaFxPart4.html | 2 +- tutorials/javaFxPart4.page-vue-render.js | 2 +- tutorials/javaFxPart5.html | 2 +- tutorials/javaFxPart5.page-vue-render.js | 2 +- tutorials/javaInstallationMac.html | 2 +- .../javaInstallationMac.page-vue-render.js | 2 +- tutorials/jekyll.html | 2 +- tutorials/jekyll.page-vue-render.js | 2 +- tutorials/junit.html | 2 +- tutorials/junit.page-vue-render.js | 2 +- tutorials/markbind-forked-sites.html | 2 +- .../markbind-forked-sites.page-vue-render.js | 2 +- tutorials/markbind.html | 2 +- tutorials/markbind.page-vue-render.js | 2 +- tutorials/netlify.html | 2 +- tutorials/netlify.page-vue-render.js | 2 +- tutorials/plantUml.html | 2 +- tutorials/plantUml.page-vue-render.js | 2 +- tutorials/savingPdf.html | 2 +- tutorials/savingPdf.page-vue-render.js | 2 +- tutorials/sourcetree.html | 2 +- tutorials/sourcetree.page-vue-render.js | 2 +- tutorials/textUiTesting.html | 2 +- tutorials/textUiTesting.page-vue-render.js | 2 +- tutorials/vscode.html | 2 +- tutorials/vscode.page-vue-render.js | 2 +- 104 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 tutorials/images/codecov/select-repo.png diff --git a/README.html b/README.html index 13f2ce3d..b5e06bba 100644 --- a/README.html +++ b/README.html @@ -14,7 +14,7 @@

Guides for SE student projects »

Go to the main website [http://se-education.org/guides]

+

Guides for SE student projects »

Go to the main website [http://se-education.org/guides]

diff --git a/README.page-vue-render.js b/README.page-vue-render.js index a22cd972..384ebbb3 100644 --- a/README.page-vue-render.js +++ b/README.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('p',[_v("Go to the main website ["),_c('a',{attrs:{"href":"http://se-education.org/guides"}},[_v("http://se-education.org/guides")]),_v("]")]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/about.html b/about.html index af455c10..965c0b95 100644 --- a/about.html +++ b/about.html @@ -16,7 +16,7 @@ Search this site

Guides for SE student projects »

About Us

This is a sub-project of the se-education.org.

Contact

Suggestions, questions, and bug reports can be posted in our issue tracker.

Alternatively, contact project mentor Damith C. Rajapakse. -

License

This work is released under the MIT OSS license.

Contributing

PRs to improve/add content are welcome.

This website uses MarkBind documentation tool. This document has some guidance on how to use it when updating contents.

Follow the Markdown style guide in your PR.

Acknowledgements

The favicon.ico is based on an icon made by Dave Gandy from www.flaticon.com

+

License

This work is released under the MIT OSS license.

Contributing

PRs to improve/add content are welcome.

This website uses MarkBind documentation tool. This document has some guidance on how to use it when updating contents.

Follow the Markdown style guide in your PR.

Acknowledgements

The favicon.ico is based on an icon made by Dave Gandy from www.flaticon.com

diff --git a/about.page-vue-render.js b/about.page-vue-render.js index 646f8d2c..f9d07d89 100644 --- a/about.page-vue-render.js +++ b/about.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"about-us"}},[_v("About Us"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#about-us","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is a sub-project of the "),_c('a',{attrs:{"href":"https://se-education.org"}},[_v("se-education.org")]),_v(".\n"),_c('span',{attrs:{"id":"contact-info"}})]),_v(" "),_c('h2',{attrs:{"id":"contact"}},[_v("Contact"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#contact","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Suggestions, questions, and bug reports can be posted in "),_c('a',{attrs:{"href":"https://github.com/se-edu/guides/issues"}},[_v("our issue tracker")]),_v(".")]),_v(" "),_c('p',[_v("Alternatively, contact project mentor "),_c('a',{attrs:{"href":"https://www.comp.nus.edu.sg/~damithch"}},[_v("Damith C. Rajapakse")]),_v(".\n")]),_v(" "),_c('h2',{attrs:{"id":"license"}},[_v("License"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#license","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This work is released under the "),_c('a',{attrs:{"href":"https://opensource.org/licenses/MIT"}},[_v("MIT OSS license")]),_v(".")]),_v(" "),_c('h2',{attrs:{"id":"contributing"}},[_v("Contributing"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#contributing","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("PRs to improve/add content are welcome.")]),_v(" "),_c('p',[_v("This website uses MarkBind documentation tool. "),_c('a',{attrs:{"href":"/guides/tutorials/markbind.html"}},[_v("This document")]),_v(" has some guidance on how to use it when updating contents.")]),_v(" "),_c('p',[_v("Follow the "),_c('a',{attrs:{"href":"/guides/conventions/markdown.html"}},[_v("Markdown style guide")]),_v(" in your PR.")]),_v(" "),_c('h2',{attrs:{"id":"acknowledgements"}},[_v("Acknowledgements"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#acknowledgements","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("The "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("favicon.ico")]),_v(" is based on an icon made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/dave-gandy"}},[_v("Dave Gandy")]),_v(" from www.flaticon.com")]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/csharp.html b/conventions/csharp.html index de63bef2..adc3d66e 100644 --- a/conventions/csharp.html +++ b/conventions/csharp.html @@ -471,7 +471,7 @@ -

References

+

References

diff --git a/conventions/csharp.page-vue-render.js b/conventions/csharp.page-vue-render.js index 18092461..6f710092 100644 --- a/conventions/csharp.page-vue-render.js +++ b/conventions/csharp.page-vue-render.js @@ -269,6 +269,6 @@ with(this){return _c('h2',{attrs:{"id":"references"}},[_v("References"),_c('a',{ with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"https://msdn.microsoft.com/en-us/library/ff926074.aspx"}},[_v("C# Coding Conventions (C# Programming Guide)")]),_v(" -- From Microsoft")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"http://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdf"}},[_v("C# Coding Style Guide")]),_v(" -- By Mike Krüger")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/dennisdoomen/CSharpGuidelines"}},[_v("CSharpGuidelines")]),_v(" -- From Aviva Solutions")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/css.html b/conventions/css.html index 292971bb..59bcbabb 100644 --- a/conventions/css.html +++ b/conventions/css.html @@ -217,7 +217,7 @@ -

Attribute Formatting

General Details

Resources

+

Attribute Formatting

General Details

Resources

diff --git a/conventions/css.page-vue-render.js b/conventions/css.page-vue-render.js index 639ede88..6d284d9f 100644 --- a/conventions/css.page-vue-render.js +++ b/conventions/css.page-vue-render.js @@ -146,6 +146,6 @@ with(this){return _c('h2',{attrs:{"id":"resources"}},[_v("Resources"),_c('a',{st with(this){return _c('ul',[_c('li',[_c('p',[_v("Highly Recommended")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://google.github.io/styleguide/htmlcssguide.xml"}},[_v("Google CSS Style Guide")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"http://learn.shayhowe.com/html-css/writing-your-best-code/#css-coding-practices"}},[_v("Writing Your Best Code - CSS Coding Practices")])])])]),_v(" "),_c('li',[_c('p',[_v("Other Readings")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://code.tutsplus.com/tutorials/30-css-best-practices-for-beginners--net-6741"}},[_v("30 CSS Best Practices For Beginners")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://css-tricks.com/css-style-guides"}},[_v("A list of CSS style guides")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"http://isobar-idev.github.io/code-standards/"}},[_v("Isobar coding standards")])])])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/files.html b/conventions/files.html index af46bacb..6754b8a9 100644 --- a/conventions/files.html +++ b/conventions/files.html @@ -16,7 +16,7 @@ Search this site

Guides for SE student projects »

Conventions for file/folder naming

Files/Folders

  • General rule: aim for local consistency i.e., follow the conventions/patterns followed by other files/folders in the neighborhood.
    • If the project uses a framework that has a specific file naming convention, follow that instead.

  • If there is no existing pattern to follow: -
    • Use camelCase whenever possible. e.g. formatsAndConventions.md
    • If the name has multiple phrases, use - to separate phrases. e.g. codingStyle-javaBasic.html

  • Try to user common prefixes so that similar files appear together when sorted by name.
    Good codingStyle-java.html, codingStyle-html.html
    Bad: javaCodingStyle.html, htmlCodingStyle.html

  • Prefer plurals if the file/folder contains multiple items of same type e.g. docs instead of doc

+

diff --git a/conventions/files.page-vue-render.js b/conventions/files.page-vue-render.js index 5c0239a9..009c0d46 100644 --- a/conventions/files.page-vue-render.js +++ b/conventions/files.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"conventions-for-file-folder-naming"}},[_v("Conventions for file/folder naming"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#conventions-for-file-folder-naming","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h2',{attrs:{"id":"files-folders"}},[_v("Files/Folders"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#files-folders","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('strong',[_v("General rule: aim for "),_c('em',[_v("local consistency")])]),_v(" i.e., follow the conventions/patterns followed by other files/folders in the neighborhood.\n"),_c('ul',[_c('li',[_v("If the project uses a framework that has a specific file naming convention, follow that instead.")])])])]),_v(" "),_c('p'),_v(" "),_c('ul',[_c('li',[_v("If there is no existing pattern to follow:\n"),_c('ul',[_c('li',[_v("Use camelCase whenever possible. e.g. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("formatsAndConventions.md")])]),_v(" "),_c('li',[_v("If the name has multiple phrases, use - to separate phrases. e.g. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("codingStyle-javaBasic.html")])])])])]),_v(" "),_c('p'),_v(" "),_c('ul',[_c('li',[_c('p',[_v("Try to user common prefixes so that similar files appear together when sorted by name."),_c('br'),_v(" "),_c('span',{staticStyle:{"color":"green"}},[_c('span',[_c('strong',[_c('span',{staticClass:"fas fa-thumbs-up",attrs:{"aria-hidden":"true"}}),_v(" Good")])])]),_v(" "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("codingStyle-java.html")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("codingStyle-html.html")]),_c('br'),_v(" "),_c('span',{staticStyle:{"color":"red"}},[_c('span',[_c('strong',[_c('span',{staticClass:"fas fa-thumbs-down",attrs:{"aria-hidden":"true"}}),_v(" Bad")])])]),_v(": "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("javaCodingStyle.html")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("htmlCodingStyle.html")])])]),_v(" "),_c('li',[_c('p',[_v("Prefer plurals if the file/folder contains multiple items of same type e.g. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("docs")]),_v(" instead of "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("doc")])])])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/git.html b/conventions/git.html index 07813552..4c02f458 100644 --- a/conventions/git.html +++ b/conventions/git.html @@ -128,7 +128,7 @@ -

Refer to the article How to Write a Git Commit Message for more advice on writing good commit messages.

Branch names

Follow these rules to improve consistency:

+

Refer to the article How to Write a Git Commit Message for more advice on writing good commit messages.

Branch names

Follow these rules to improve consistency:

diff --git a/conventions/git.page-vue-render.js b/conventions/git.page-vue-render.js index c50376a4..4519b4ef 100644 --- a/conventions/git.page-vue-render.js +++ b/conventions/git.page-vue-render.js @@ -83,6 +83,6 @@ with(this){return _c('h2',{attrs:{"id":"branch-names"}},[_v("Branch names"),_c(' with(this){return _c('div',{attrs:{"id":"branch-names-format"}},[_c('p',[_v("Follow these rules to improve consistency:")]),_v(" "),_c('ul',[_c('li',[_v("Use a meaningful name consisting of some relevant keywords, in the "),_c('em',[_v("kebab case")]),_v(" format e.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("refactor-ui-tests")]),_v(".")]),_v(" "),_c('li',[_v("If the branch is related to an issue, use the format "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("issueNumber-some-keywords-from-issue-title")]),_v(" e.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("1234-ui-freeze-error")])])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/github.html b/conventions/github.html index 97f52dc0..dfa51154 100644 --- a/conventions/github.html +++ b/conventions/github.html @@ -45,7 +45,7 @@

PR merge commit

When merging a PR branch to the main branch, use one of these formats for the subject line of the merge commit.

Pick one option and use it consistently in the entire code base.

Rationale: This format allows easy traceability among a merge commit, the issue it fixes, and the PR that fixed it. Having the issue name tells us what the commit is about without having to look it up in GitHub issue tracker.

Issues

+e.g. Error alert email has very long subject (#6580)

Pick one option and use it consistently in the entire code base.

Rationale: This format allows easy traceability among a merge commit, the issue it fixes, and the PR that fixed it. Having the issue name tells us what the commit is about without having to look it up in GitHub issue tracker.

Issues

diff --git a/conventions/github.page-vue-render.js b/conventions/github.page-vue-render.js index e1973e87..6c517daf 100644 --- a/conventions/github.page-vue-render.js +++ b/conventions/github.page-vue-render.js @@ -71,6 +71,6 @@ with(this){return _c('h2',{attrs:{"id":"issues"}},[_v("Issues"),_c('a',{staticCl with(this){return _c('li',[_c('p',[_c('strong',[_v("Issue title should be concise yet descriptive.")]),_v(" For example, instead of "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Newbie question, please help")]),_v(", use "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("How do I set up git to ignore test files?")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/html.html b/conventions/html.html index 998a838d..19b9025f 100644 --- a/conventions/html.html +++ b/conventions/html.html @@ -376,7 +376,7 @@ -

+

diff --git a/conventions/html.page-vue-render.js b/conventions/html.page-vue-render.js index 8b43993a..1693ab06 100644 --- a/conventions/html.page-vue-render.js +++ b/conventions/html.page-vue-render.js @@ -191,6 +191,6 @@ with(this){return _c('div',{staticClass:"col-sm-auto"},[_c('span',{staticStyle:{ with(this){return _c('code',{pre:true,attrs:{"class":"no-line-numbers hljs html"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-tag"}},[_v("<"),_c('span',{pre:true,attrs:{"class":"hljs-name"}},[_v("a")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-attr"}},[_v("target")]),_v("="),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"_blank\"")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-attr"}},[_v("href")]),_v("="),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"https://example.com\"")]),_v(">")]),_v("Example.com"),_c('span',{pre:true,attrs:{"class":"hljs-tag"}},[_v("")]),_v("\n")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/java/basic.html b/conventions/java/basic.html index d38abd08..9ce1485b 100644 --- a/conventions/java/basic.html +++ b/conventions/java/basic.html @@ -800,7 +800,7 @@ -

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

+

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

diff --git a/conventions/java/basic.page-vue-render.js b/conventions/java/basic.page-vue-render.js index 5c28791b..1da956e6 100644 --- a/conventions/java/basic.page-vue-render.js +++ b/conventions/java/basic.page-vue-render.js @@ -374,6 +374,6 @@ with(this){return _c('h2',{attrs:{"id":"contributors"}},[_v("Contributors"),_c(' with(this){return _c('ul',[_c('li',[_v("Nimantha Baranasuriya - Initial draft")]),_v(" "),_c('li',[_v("Dai Thanh - Further tweaks")]),_v(" "),_c('li',[_v("Tong Chun Kit - Further tweaks")]),_v(" "),_c('li',[_v("Barnabas Tan - Converted from Google Docs to Markdown Document")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/java/index.html b/conventions/java/index.html index 71ee7e70..a6b2b81b 100644 --- a/conventions/java/index.html +++ b/conventions/java/index.html @@ -1201,7 +1201,7 @@ -

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

+

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

diff --git a/conventions/java/index.page-vue-render.js b/conventions/java/index.page-vue-render.js index d6a51971..9ec3b30c 100644 --- a/conventions/java/index.page-vue-render.js +++ b/conventions/java/index.page-vue-render.js @@ -569,6 +569,6 @@ with(this){return _c('h2',{attrs:{"id":"contributors"}},[_v("Contributors"),_c(' with(this){return _c('ul',[_c('li',[_v("Nimantha Baranasuriya - Initial draft")]),_v(" "),_c('li',[_v("Dai Thanh - Further tweaks")]),_v(" "),_c('li',[_v("Tong Chun Kit - Further tweaks")]),_v(" "),_c('li',[_v("Barnabas Tan - Converted from Google Docs to Markdown Document")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/java/intermediate.html b/conventions/java/intermediate.html index 89b1b531..dc915b52 100644 --- a/conventions/java/intermediate.html +++ b/conventions/java/intermediate.html @@ -1106,7 +1106,7 @@ -

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

+

References

  1. Oracle's Java Style Guide https://www.oracle.com/docs/tech/java/codeconventions.pdf
  2. Google's Java Style Guide https://google.github.io/styleguide/javaguide.html

Contributors

diff --git a/conventions/java/intermediate.page-vue-render.js b/conventions/java/intermediate.page-vue-render.js index d39ac8f0..250c6c4f 100644 --- a/conventions/java/intermediate.page-vue-render.js +++ b/conventions/java/intermediate.page-vue-render.js @@ -506,6 +506,6 @@ with(this){return _c('h2',{attrs:{"id":"contributors"}},[_v("Contributors"),_c(' with(this){return _c('ul',[_c('li',[_v("Nimantha Baranasuriya - Initial draft")]),_v(" "),_c('li',[_v("Dai Thanh - Further tweaks")]),_v(" "),_c('li',[_v("Tong Chun Kit - Further tweaks")]),_v(" "),_c('li',[_v("Barnabas Tan - Converted from Google Docs to Markdown Document")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/java/logging.html b/conventions/java/logging.html index 019c4efd..05094153 100644 --- a/conventions/java/logging.html +++ b/conventions/java/logging.html @@ -14,7 +14,7 @@

Guides for SE student projects »

Java logging conventions

We recommend using java.util.logging package for logging.

Logging Levels

  • SEVERE: A critical problem detected which may cause the termination of the application.
  • WARNING: Can continue, but with caution.
  • INFO: Information showing the noteworthy actions by the App.
  • FINE: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size.

+

Guides for SE student projects »

Java logging conventions

We recommend using java.util.logging package for logging.

Logging Levels

  • SEVERE: A critical problem detected which may cause the termination of the application.
  • WARNING: Can continue, but with caution.
  • INFO: Information showing the noteworthy actions by the App.
  • FINE: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size.

diff --git a/conventions/java/logging.page-vue-render.js b/conventions/java/logging.page-vue-render.js index b5e332d9..af47054e 100644 --- a/conventions/java/logging.page-vue-render.js +++ b/conventions/java/logging.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"java-logging-conventions"}},[_v("Java logging conventions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#java-logging-conventions","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("We recommend using "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("java.util.logging")]),_v(" package for logging.")]),_v(" "),_c('p',[_c('strong',[_v("Logging Levels")])]),_v(" "),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("SEVERE")]),_v(": A critical problem detected which may cause the termination of the application.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("WARNING")]),_v(": Can continue, but with caution.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("INFO")]),_v(": Information showing the noteworthy actions by the App.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("FINE")]),_v(": Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size.")])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/javascript.html b/conventions/javascript.html index 40363c17..048e9ee0 100644 --- a/conventions/javascript.html +++ b/conventions/javascript.html @@ -14,7 +14,7 @@

Guides for SE student projects »

JavaScript coding standard

  • Indentation: Use 2 spaces (not tabs, not 4 spaces)
  • Maximum line length: soft limit = 110, hard limit = 120
  • For everything else, follow the Airbnb coding standard.

+

Guides for SE student projects »

JavaScript coding standard

  • Indentation: Use 2 spaces (not tabs, not 4 spaces)
  • Maximum line length: soft limit = 110, hard limit = 120
  • For everything else, follow the Airbnb coding standard.

diff --git a/conventions/javascript.page-vue-render.js b/conventions/javascript.page-vue-render.js index d09fb53a..2c30d318 100644 --- a/conventions/javascript.page-vue-render.js +++ b/conventions/javascript.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"javascript-coding-standard"}},[_v("JavaScript coding standard"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#javascript-coding-standard","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('strong',[_v("Indentation")]),_v(": Use "),_c('mark',[_v("2 spaces")]),_v(" (not tabs, not 4 spaces)")]),_v(" "),_c('li',[_c('strong',[_v("Maximum line length")]),_v(": soft limit = 110, "),_c('mark',[_v("hard limit = 120")])]),_v(" "),_c('li',[_v("For everything else, follow the "),_c('a',{attrs:{"href":"https://github.com/airbnb/javascript/blob/master/README.md"}},[_c('strong',[_v("Airbnb coding standard")])]),_v(".")])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/conventions/markdown.html b/conventions/markdown.html index 445e911b..2730b1fb 100644 --- a/conventions/markdown.html +++ b/conventions/markdown.html @@ -277,7 +277,7 @@ -

+

diff --git a/conventions/markdown.page-vue-render.js b/conventions/markdown.page-vue-render.js index ecaecf43..64383b58 100644 --- a/conventions/markdown.page-vue-render.js +++ b/conventions/markdown.page-vue-render.js @@ -125,6 +125,6 @@ with(this){return _c('div',{staticClass:"col-sm-auto"},[_c('span',{staticStyle:{ with(this){return _c('code',{pre:true,attrs:{"class":"hljs markdown"}},[_c('span',[_v("He "),_c('span',{pre:true,attrs:{"class":"hljs-emphasis"}},[_v("*really*")]),_v(" meant it.\n")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/guidelines/PRs-reviewing.html b/guidelines/PRs-reviewing.html index f4a18a35..617d4802 100644 --- a/guidelines/PRs-reviewing.html +++ b/guidelines/PRs-reviewing.html @@ -21,7 +21,7 @@ Option 1: This separation of X from Y is good (or correct or wrong or bad)
Option 2: I like how you separated X from Y (or didn't like or Not sure I like)
The second one is less judgemental and less likely to cause the author to become defensive.
  • Feel free to ask for more info from the author, to help you understand the code/design. For example, you can ask why the author chose to write the code in a specific way.
  • You can also suggest alternatives for the author to consider.
    -Combining this with the previous point, you can ask Any reason why you did it this way instead of that way?
  • Feel free to compliment the author when appropriate instead of focusing on negative things only.
    e.g., hey, I like how clean this bit of code is 👍
  • Say please, but don't say please. Beware of overusing 'please' as it can be interpreted as a condescending tone. For example, someone can interpret Please use better variable names as Please for the love of God can you use better variable names?. Instead, you can say Perhaps a more intuitive variable name here? which doesn't run any risk of misinterpretation.
  • No need to repeat the same comment many times. It's not the job of the reviewer to clean up after a sloppy author. If you notice the same problem in multiple places, after commenting an a few of them, you can simply say ... I noticed the same issue in several other places too.
  • Remember the other readers. PR comments can be read by people other than the reviewer and the author e.g., future programmers. Use regular English and avoid slang, colloquialisms, cultural references etc.
  • Further readings:

    Best practices for authors

    +Combining this with the previous point, you can ask Any reason why you did it this way instead of that way?
  • Feel free to compliment the author when appropriate instead of focusing on negative things only.
    e.g., hey, I like how clean this bit of code is 👍
  • Say please, but don't say please. Beware of overusing 'please' as it can be interpreted as a condescending tone. For example, someone can interpret Please use better variable names as Please for the love of God can you use better variable names?. Instead, you can say Perhaps a more intuitive variable name here? which doesn't run any risk of misinterpretation.
  • No need to repeat the same comment many times. It's not the job of the reviewer to clean up after a sloppy author. If you notice the same problem in multiple places, after commenting an a few of them, you can simply say ... I noticed the same issue in several other places too.
  • Remember the other readers. PR comments can be read by people other than the reviewer and the author e.g., future programmers. Use regular English and avoid slang, colloquialisms, cultural references etc.
  • Further readings:

    Best practices for authors

    diff --git a/guidelines/PRs-reviewing.page-vue-render.js b/guidelines/PRs-reviewing.page-vue-render.js index 0e6995c2..489f058b 100644 --- a/guidelines/PRs-reviewing.page-vue-render.js +++ b/guidelines/PRs-reviewing.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"best-practices-for-reviewing-prs"}},[_v("Best practices for reviewing PRs"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#best-practices-for-reviewing-prs","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"lead"},[_c('p',[_v("Reviewing PRs is not just about the code or the tools, "),_c('strong',[_v("the way you phrase your comments matters too")]),_v(", especially if you are a peer reviewer.")])]),_v(" "),_c('h2',{attrs:{"id":"best-practices-for-reviewers"}},[_v("Best practices for reviewers"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#best-practices-for-reviewers","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('strong',[_v("Add specific comments at relevant places of the code")]),_v(", rather than give one overall comment for the entire PR.\n"),_c('ul',[_c('li',[_v("It is typical for the comment to be added right below the code line it refers to."),_c('br'),_v("\nIt is possible to "),_c('a',{attrs:{"href":"https://twitter.com/natfriedman/status/1179097330097643521"}},[_v("mark multiple lines")]),_v(" as linked to the comment too.")]),_v(" "),_c('li',[_v("You can use Markdown (specifically, "),_c('a',{attrs:{"href":"https://guides.github.com/features/mastering-markdown/"}},[_v("GitHub-Flavored Markdown")]),_v(") in your comments.")])])]),_v(" "),_c('li',[_c('mark',[_c('strong',[_v("It's best to phrase comments as questions")])]),_v(", especially if you are a peer reviewer."),_c('br'),_v("\ne.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Should this be extracted out?")]),_v(" rather than "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Extract this out")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("This should be extracted out")]),_v(".")]),_v(" "),_c('li',[_c('strong',[_v("Say 'I like', not 'good/bad'")]),_v(". Consider these two alternatives:"),_c('br'),_v("\nOption 1: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("This separation of X from Y is good")]),_v(" (or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("correct")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("wrong")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("bad")]),_v(")"),_c('br'),_v("\nOption 2: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("I like how you separated X from Y")]),_v(" (or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("didn't like")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Not sure I like")]),_v(")"),_c('br'),_v("\nThe second one is less judgemental and less likely to cause the author to become defensive.")]),_v(" "),_c('li',[_c('strong',[_v("Feel free to ask for more info from the author")]),_v(", to help you understand the code/design. For example, you can ask why the author chose to write the code in a specific way.")]),_v(" "),_c('li',[_c('strong',[_v("You can also suggest alternatives for the author to consider.")]),_c('br'),_v("\nCombining this with the previous point, you can ask "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Any reason why you did it this way instead of that way?")])]),_v(" "),_c('li',[_c('strong',[_v("Feel free to compliment the author when appropriate")]),_v(" instead of focusing on negative things only."),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_v("e.g., "),_c('em',[_v("hey, I like how clean this bit of code is")]),_v(" 👍")])]),_v(" "),_c('li',[_c('strong',[_v("Say please, but don't say "),_c('em',[_v("please")])]),_v(". Beware of overusing 'please' as it can be interpreted as a condescending tone. For example, someone can interpret "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Please use better variable names")]),_v(" as "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Please for the love of God can you use better variable names?")]),_v(". Instead, you can say "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Perhaps a more intuitive variable name here?")]),_v(" which doesn't run any risk of misinterpretation.")]),_v(" "),_c('li',[_c('strong',[_v("No need to repeat the same comment "),_c('em',[_v("many")]),_v(" times")]),_v(". It's not the job of the reviewer to clean up after a sloppy author. If you notice the same problem in multiple places, after commenting an a few of them, you can simply say "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("... I noticed the same issue in several other places too")]),_v(".")]),_v(" "),_c('li',[_c('strong',[_v("Remember the "),_c('em',[_v("other")]),_v(" readers")]),_v(". PR comments can be read by people other than the reviewer and the author e.g., future programmers. Use regular English and avoid slang, colloquialisms, cultural references etc.")])]),_v(" "),_c('p',[_c('strong',[_c('strong',[_v("Further readings")])]),_v(":")]),_v(" "),_c('ul',[_c('li',[_v("Read the blog post "),_c('a',{attrs:{"href":"https://developers.redhat.com/blog/2019/07/08/10-tips-for-reviewing-code-you-dont-like/"}},[_c('strong',[_v("10 tips for reviewing code you don’t like")])]),_v(" - by David Lloyd (a Red Hat developer).")])]),_v(" "),_c('h2',{attrs:{"id":"best-practices-for-authors"}},[_v("Best practices for authors"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#best-practices-for-authors","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('strong',[_v("Don't get into arguments with reviewers.")]),_v(" If you disagree with the reviewer, you can explain your own view in a non-confrontational way without trying to prove your way is better.")]),_v(" "),_c('li',[_v("Thank reviewers for their inputs.")])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/guidelines/PRs.html b/guidelines/PRs.html index 28542b5b..d42386c5 100644 --- a/guidelines/PRs.html +++ b/guidelines/PRs.html @@ -17,7 +17,7 @@

    Guides for SE student projects »

    Guidelines for working with PRs

    Selecting what to work on

    • If submitting a PR for an existing issue,
      • It's best for first time contributors to start by fixing an issue specifically labelled for first timers e.g., d.FirstTimers, good first issue.
      • It's best to post in the issue to ask if it is OK for you to submit a PR for that issue and wait for approval.
      • Check the issue discussion thread to see if there are PRs for that issue. You can offer to PR for an issue that has stalled PRs i.e., there is a PRs submitted for that issue but the PR author seems to have stopped working on it.
    • If the issue list does not contain what you want to work on, post an issue first and wait for it to be acknowledged. Otherwise you could end up fixing something that does not need fixing.

    Scoping a PR

    General rule: try to keep PRs as small as possible because smaller PRs get merged faster.

    A PR should contain a single, standalone, and complete change to the code base, unless in exceptional cases where the PR is part of a bigger change.

    • Single means a PR should not try to fix more than one fix, unless there are multiple things that must be done together or not at all.

      Refrain from in the neighboring code unless the line in concern is already touched by the PR (i.e., the housekeeping does not increase the line count of the PR).

      Rationale: Imagine we decide to revert the PR for some reason. If a PR contains, unrelated changes or multiple independent changes, we will not be able to revert the offending change without losing the other changes as well.

      If you notice a need for housekeeping in the neighboring code as you do your PR, create an issue for it in the issue tracker.

    • Standalone means the PR should contain a meaningful change that moves the code base from one working state to another.

    • Complete means the PR should contain everything related to the change, including the following:

      • functional code
      • code comments
      • test cases
      • user docs and developer docs

    "This PR is just the code fix. I'll update tests and documentation in a separate PR" is not acceptable!

    However, it is fine to push the functional code first to get early feedback, as long as the rest is added to the same PR later.

    Submitting a PR

    When submitting PRs, follow the forking workflow. A summary of the steps is given below.

    Step 0 Do these steps if you haven't done them already:

    0.1 Fork the upstream repo.

    0.2 Clone the fork to your computer.

    0.3 Set up the dev environment as described in the project docs. Confirm the set up is correct.

    Step 1 Create a branch from the master branch, following the naming convention given.

    Step 2 Add your code to the branch while ensuring you follow these:

    • relevant coding standards (the full list is given here)
    • Commit message format

    • guidelines for commit organization

    • PR scoping guidelines given above

    Step 3 Sync your branch with the upstream master, if the master branch advances while you work on your code (i.e., pull upstream master, merge to your branch).

    Step 4 Create a PR when the code is ready, as follows:

    1. Run code style checks (if any) to ensure the code complies with the project standards.
    2. Push the branch to your fork.
    3. Create a draft PR from your fork to the upstream repo.
    4. Check the draft PR on GitHub to confirm the following:
      • it follows the PR format conventions
      • it does not contain any unintended changes.
      • it passes checks, if any.
    5. Remove the 'draft' status of the PR. Post a ready for review comment for good measure.

    Step 5 Revise as per reviews until the PR is merged.

    • Feel free to post a reminder comment if you don't get a review within 2-3 days.
    • When you receive a review,
      1. Revise the code as per the review.
      2. Push the new code to the branch in your fork.
      3. Post a comment to indicate the PR is ready for a new review.

    Reviewing a PR

    • Check for basic PR hygiene, and remind the PR author to rectify if necessary. -
      • contains a single, stand-alone, complete fix
      • relevant comments, dev/user docs, tests have been updated
      • PR title/description format is expected
      • doesn't contain unrelated changes

    • Before approving a PR, confirm that all your previous comments have been addressed.

    Merging PRs

    Follow the convention for Git branch merging, as given in the panel below.

    +

    Merging PRs

    Follow the convention for Git branch merging, as given in the panel below.

    diff --git a/guidelines/PRs.page-vue-render.js b/guidelines/PRs.page-vue-render.js index ff62e868..6c922c87 100644 --- a/guidelines/PRs.page-vue-render.js +++ b/guidelines/PRs.page-vue-render.js @@ -101,6 +101,6 @@ with(this){return _c('ul',[_c('li',[_c('strong',[_v("Before approving a PR, "),_ with(this){return _c('h2',{attrs:{"id":"merging-prs"}},[_v("Merging PRs"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#merging-prs","onclick":"event.stopPropagation()"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/guidelines/codeOfConduct.html b/guidelines/codeOfConduct.html index 823b5b80..a6ba348b 100644 --- a/guidelines/codeOfConduct.html +++ b/guidelines/codeOfConduct.html @@ -41,7 +41,7 @@ obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

    Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other -members of the project's leadership.

    +members of the project's leadership.

    diff --git a/guidelines/codeOfConduct.page-vue-render.js b/guidelines/codeOfConduct.page-vue-render.js index 3fa15bc7..fa890e2e 100644 --- a/guidelines/codeOfConduct.page-vue-render.js +++ b/guidelines/codeOfConduct.page-vue-render.js @@ -35,6 +35,6 @@ with(this){return _c('h2',{attrs:{"id":"enforcement"}},[_v("Enforcement"),_c('a' with(this){return _c('p',[_v("Instances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("seer[at]comp.nus.edu.sg")]),_v(". All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/guidelines/commits.html b/guidelines/commits.html index 50737493..43406afe 100644 --- a/guidelines/commits.html +++ b/guidelines/commits.html @@ -17,7 +17,7 @@

    Guides for SE student projects »

    Working with Git

    Organizing commits

    Commits in a branch or a PR is said to be well-organized if they have the following qualities:

    • Each commit contains a single logical change, and this change must stand on its own. i.e. each commit has a single responsibility, and that responsibility must be fully carried out.
      For example, if the commit message says Move delete() from Person class to Address class, the commit cannot contain the addition of delete() to Address class only; it should also contain the deletion of delete() from the Person class for it to be a complete implementation what is stated in the commit message.

    • Each commit has a well-written commit message i.e., it follows these guidelines.

    • Commits are ordered in a bottom-up fashion, each commit building on top of the previous one towards the end goal of the PR.

      Rationale: Reviewers should be able to review one commit at a time.

    • Ideally, a commit does not modify more than 100 lines of code.

      Rationale: Bigger commits are harder to review.

      "Ask a programmer to review 10 lines of code, he'll find 10 issues. Ask him to do 500 lines and he'll say it looks good." --[source]

      Commits containing mechanical changes (e.g. automated refactorings, cut-paste type code movements, file renames, etc.),

      • should include only one mechanical change per commit e.g., rename a single variable across the code base.
      • should not contain other non-mechanical changes, unless unavoidable.
      • can exceed 100 LoC.
      • should have the description of the change in the commit message (so that the results can be reproduced).
    • Every commit pass CI. when you merge a series of commits (without squashing), every commit in your push (not just the last commit) should pass CI.

      Rationale: Build-breaking commits in the version history hinder the ability to use git bisect for locating bugs.

    Here is an example PR of commits that are organized as described above.

    Refactor commits before pushing. It is unlikely that you can produce a series of commits that meet all the above criteria in the first try. In such cases, refactor commits until they meet the criteria. This S/O post describes how to refactor commits (even easier to do with visual tools such as SourceTree -- see this video).

    Merging branches

    When merging branch, the aim is to keep the version history neat so that it is easy to do things such as the following:

    • Find which commit introduced a bug using git bisect.
    • Undo a specific change by reverting a commit in the history without breaking anything else.
    • The default strategy is to do a squash-merge. This is suitable when the branch tackles one task but multiple commits that are not well-organized (as per the definition of 'well-organized' in the panel below).

    • Use a merge commit if the commits are well-organized, and the branch tackles only one task. In this case the commit message of the merge commit should explain the full task.

    • Use a rebase-merge if the commits are well-organized and each commit is an independent task (as opposed to steps or a bigger tasks).

    • In other cases, consider reorganizing/splitting the branch to match one of the above. -

    +

    diff --git a/guidelines/commits.page-vue-render.js b/guidelines/commits.page-vue-render.js index 27219994..ebd0b683 100644 --- a/guidelines/commits.page-vue-render.js +++ b/guidelines/commits.page-vue-render.js @@ -50,6 +50,6 @@ with(this){return _c('ul',[_c('li',[_c('strong',[_v("The default strategy is to with(this){return _c('ul',[_c('li',[_c('p',[_c('strong',[_v("Use a "),_c('em',[_v("merge commit")])]),_v(" if the commits are well-organized, and the branch tackles only one task. In this case the commit message of the merge commit should explain the full task.")])]),_v(" "),_c('li',[_c('p',[_c('strong',[_v("Use a "),_c('em',[_v("rebase-merge")])]),_v(" if the commits are well-organized and each commit is an independent task (as opposed to steps or a bigger tasks).")])]),_v(" "),_c('li',[_c('p',[_c('strong',[_v("In other cases")]),_v(", consider reorganizing/splitting the branch to match one of the above.\n")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/guidelines/labels.html b/guidelines/labels.html index c1bf015c..235dba8a 100644 --- a/guidelines/labels.html +++ b/guidelines/labels.html @@ -24,7 +24,7 @@ e.g. a request for help on setting up dev environment.

    Difficulty (d.)

    Effort (e.)

    This label can be used to indicate how much effort is expected for (or was spent on) an issue.

    e.1 is roughly equal to an hour of work, e.2 is two hours of work, and so on. Recommended values: 1,2,4,8,16,32

    Effort labels can be applied to PRs indicate effort for reviewing (by the main reviewer). Those applied for issues can indicate the effort for fixing the issue.

    Aspect (a-)

    Classifies the issues based on the non-functional aspect it tackles. Some examples:

    Label Description
    a-AccessControl Controlling access to user groups, authentication, privacy, anonymity
    a-CodeQuality Refactorings that are mainly to improve code/design quality
    a-Concurrency Things related to concurrent access, session control
    a-DevOps CI, release management, version control, dev docs
    a-Docs User docs, product website
    a-FaultTolerance Resilience to user errors, environmental problems
    a-Performance Speed of operation
    a-Persistence Saving data permanently
    a-Scalability Related to behavior at increasing loads
    a-Security Protection from security threats
    a-Testing Testing efficiency and robustness (as opposed to testing a specific feature)
    a-UIX User interface, User experience, Responsiveness

    Feature (f-)

    Classifies the issue based on the feature it involves. These labels depend on the project. e.g. f-Admin, f-Sessions, f-Delete

    Tech (t-)

    Classifies the issue based on the tool/technology it involves. Some examples given below.

    Label Description
    t-CSS CSS, Bootstrap
    t-HTML HTML, Browsers
    t-JS Javascript, JQuery
    t-JSTL JSTL, JSP, Servlets

    Special labels

    Other guidelines

    +
  • Use UpperCamelCase for label names; Keep group prefixes short and use lower case.
  • diff --git a/guidelines/labels.page-vue-render.js b/guidelines/labels.page-vue-render.js index c5d5c78b..885cafda 100644 --- a/guidelines/labels.page-vue-render.js +++ b/guidelines/labels.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"working-with-github-labels"}},[_v("Working with GitHub labels"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#working-with-github-labels","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"lead"},[_c('p',[_v("As a project grows, issue/PR labels can play an increasingly important role in managing a large number of issues/PRs. This document has some guidelines that can improve consistency across projects and help make the use of labels more productive.")])]),_v(" "),_c('p',[_v("Unless mentioned otherwise, "),_c('em',[_v("labels are applied to issues only")]),_v(" (not PRs).")]),_v(" "),_c('h2',{attrs:{"id":"label-groups"}},[_v("Label groups"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#label-groups","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("While GitHub does not have the concept of label groups, we can simulate label groups using systematic label naming.\ni.e. labels having the same prefix are considered part of a label group.")]),_v(" "),_c('p',[_v("There are two types of label groups:")]),_v(" "),_c('ul',[_c('li',[_c('strong',[_v("Exclusive groups")]),_v(": No more than one label from the group can be applied to an issue")]),_v(" "),_c('li',[_c('strong',[_v("Non-exclusive groups")]),_v(": Multiple labels from a group can be applied to an issue")])]),_v(" "),_c('p',[_c('em',[_v("Common label groups")]),_v(":")]),_v(" "),_c('ul',[_c('li',[_v("exclusive: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.")]),_v(" status, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.")]),_v(" priority, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.")]),_v(" category, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.")]),_v(" difficulty, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("e.")]),_v(" effort,")]),_v(" "),_c('li',[_v("non-exclusive: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-")]),_v(" aspect, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("f-")]),_v(" feature, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-")]),_v(" tech,")])]),_v(" "),_c('h2',{attrs:{"id":"common-labels"}},[_v("Common labels"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#common-labels","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"priority-p"}},[_v("Priority ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#priority-p","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.Critical")]),_v(": Would like to fix it ASAP and release as a hot patch.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.Urgent")]),_v(": Would like to handle in the very next release.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.High")]),_v(": Enhances user experience significantly, would like to do in the next few releases.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.Medium")]),_v(": Marginal impact on user experience.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.Low")]),_v(": Very little impact, unlikely to do in the near future.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("p.Zero")]),_v(": Unlikely to do, ever.")])]),_v(" "),_c('p',[_v("NOTE: An issue is considered as "),_c('em',[_v("accepted")]),_v(" when a priority label has been assigned.")]),_v(" "),_c('h3',{attrs:{"id":"status-s"}},[_v("Status ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#status-s","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Open issues\n"),_c('ul',[_c('li',[_v("No status: New issue yet to be triaged.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.OnHold")]),_v(": The work on the issue has been put on hold pending some other event.")])])]),_v(" "),_c('li',[_v("Open PR\n"),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.ToReview")]),_v(": Waiting for the review.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.Ongoing")]),_v(": The PR is being worked on.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.ToMerge")]),_v(": Main reviewer approved the changes.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.MergeApproved")]),_v(": Both main reviewer and the code quality reviewer has approved the merge. PR can be merged.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("s.OnHold")]),_v(": The work on the PR has been put on hold pending some other event.")])])])]),_v(" "),_c('h3',{attrs:{"id":"category-c"}},[_v("Category ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#category-c","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Changes to "),_c('em',[_v("functionality")]),_v(", categorized based on size\n"),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Enhancement")]),_v(": An enhancement to an existing functionality (not big enough to be considered as a user story).")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Story")]),_v(" : A user story."),_c('br'),_v("\nOR "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Feature")]),_v(": A new feature.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Epic")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Theme")]),_v(": A feature that be broken down into many user-stories/features.")])])]),_v(" "),_c('li',[_v("Other work\n"),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Bug")])]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Task")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Chore")]),_v(": Other work items such as updating documentation.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("c.Message")]),_v(": Issue used as a means of discussing something with the dev team."),_c('br'),_v("\ne.g. a request for help on setting up dev environment.")])])])]),_v(" "),_c('h3',{attrs:{"id":"difficulty-d"}},[_v("Difficulty ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#difficulty-d","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.Easy")]),_v(": For new contributors to do as their first PR. MUST be simple enough to be contained in one commit.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.Moderate")]),_v(": Moderate difficulty. Small localized change.")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.Hard")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("d.VeryHard")]),_v(": More difficult issues that are better left for committers or more senior developers.")])]),_v(" "),_c('h3',{attrs:{"id":"effort-e"}},[_v("Effort ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("e.")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#effort-e","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This label can be used to indicate how much effort is expected for (or was spent on) an issue.")]),_v(" "),_c('p',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("e.1")]),_v(" is roughly equal to an hour of work, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("e.2")]),_v(" is two hours of work, and so on. Recommended values: 1,2,4,8,16,32")]),_v(" "),_c('p',[_v("Effort labels can be applied to PRs indicate effort for reviewing (by the main reviewer). Those applied for issues can indicate\nthe effort for fixing the issue.")]),_v(" "),_c('h3',{attrs:{"id":"aspect-a"}},[_v("Aspect ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#aspect-a","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Classifies the issues based on the non-functional aspect it tackles. Some examples:")]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Label")]),_v(" "),_c('th',[_v("Description")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-AccessControl")])]),_v(" "),_c('td',[_v("Controlling access to user groups, authentication, privacy, anonymity")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-CodeQuality")])]),_v(" "),_c('td',[_v("Refactorings that are mainly to improve code/design quality")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Concurrency")])]),_v(" "),_c('td',[_v("Things related to concurrent access, session control")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-DevOps")])]),_v(" "),_c('td',[_v("CI, release management, version control, dev docs")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Docs")])]),_v(" "),_c('td',[_v("User docs, product website")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-FaultTolerance")])]),_v(" "),_c('td',[_v("Resilience to user errors, environmental problems")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Performance")])]),_v(" "),_c('td',[_v("Speed of operation")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Persistence")])]),_v(" "),_c('td',[_v("Saving data permanently")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Scalability")])]),_v(" "),_c('td',[_v("Related to behavior at increasing loads")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Security")])]),_v(" "),_c('td',[_v("Protection from security threats")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-Testing")])]),_v(" "),_c('td',[_v("Testing efficiency and robustness (as opposed to testing a specific feature)")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("a-UIX")])]),_v(" "),_c('td',[_v("User interface, User experience, Responsiveness")])])])])]),_v(" "),_c('h3',{attrs:{"id":"feature-f"}},[_v("Feature ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("f-")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#feature-f","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Classifies the issue based on the feature it involves. These labels depend on the project.\ne.g. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("f-Admin")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("f-Sessions")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("f-Delete")])]),_v(" "),_c('h3',{attrs:{"id":"tech-t"}},[_v("Tech ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-")]),_v(")"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tech-t","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Classifies the issue based on the tool/technology it involves. Some examples given below.")]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Label")]),_v(" "),_c('th',[_v("Description")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-CSS")])]),_v(" "),_c('td',[_v("CSS, Bootstrap")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-HTML")])]),_v(" "),_c('td',[_v("HTML, Browsers")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-JS")])]),_v(" "),_c('td',[_v("Javascript, JQuery")])]),_v(" "),_c('tr',[_c('td',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("t-JSTL")])]),_v(" "),_c('td',[_v("JSTL, JSP, Servlets")])])])])]),_v(" "),_c('h3',{attrs:{"id":"special-labels"}},[_v("Special labels"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#special-labels","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("good first issue")]),_v(": for first time contributors (note that "),_c('a',{attrs:{"href":"https://help.github.com/en/github/building-a-strong-community/encouraging-helpful-contributions-to-your-project-with-labels"}},[_v("GitHub treats this label in a special way")]),_v(")")]),_v(" "),_c('li',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("kudos")]),_v(": to appreciate good work done in a PR")])]),_v(" "),_c('h2',{attrs:{"id":"other-guidelines"}},[_v("Other guidelines"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#other-guidelines","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("When choosing label colors:\n"),_c('ul',[_c('li',[_v("Choose bright colors for labels that should get more attention. "),_c('a',{attrs:{"href":"https://github.com/oss-generic/process/labels?sort=name-asc%5BHere%5D"}},[_v("https://github.com/oss-generic/process/labels?sort=name-asc[Here]")]),_v(" are some sample labels with suitable colors.")]),_v(" "),_c('li',[_v("Label groups that represent a scale (e.g., difficulty, effort, severity) can be given increasingly darker shades of the same color ("),_c('a',{attrs:{"href":"https://github.com/oss-generic/process/labels?q=e."}},[_v("example")]),_v(")")])])]),_v(" "),_c('li',[_v("Use UpperCamelCase for label names; Keep group prefixes short and use lower case.")])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/index.html b/index.html index dd3fdc29..4b9441a9 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,7 @@
  • Intellij IDEA:
  • Sourcetree
  • Testing
  • GitHub Actions
  • Gradle
  • Project documentation: -
  • Conventions

    Coding standards, format conventions, style guides, ...

    Guidelines

    Best practices, processes, workflows, ...

    +

    Conventions

    Coding standards, format conventions, style guides, ...

    Guidelines

    Best practices, processes, workflows, ...

    diff --git a/index.page-vue-render.js b/index.page-vue-render.js index c1faa58c..ef450344 100644 --- a/index.page-vue-render.js +++ b/index.page-vue-render.js @@ -20,6 +20,6 @@ with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/conventions/c with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/guidelines/codeOfConduct.html"}},[_c('strong',[_v("Code of conduct")])]),_c('br')]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/guidelines/commits.html"}},[_c('strong',[_v("Working with Git")])])]),_v(" "),_c('li',[_c('strong',[_v("GitHub:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/guidelines/PRs.html"}},[_v("Working with "),_c('strong',[_v("PRs")])]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/guidelines/PRs-reviewing.html"}},[_v("Best practices for "),_c('strong',[_v("reviewing PRs")])])])])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/guidelines/labels.html"}},[_v("Working with "),_c('strong',[_v("labels")])])])])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/ab3.html b/tutorials/ab3.html index eda4ff1e..c18be7f5 100644 --- a/tutorials/ab3.html +++ b/tutorials/ab3.html @@ -14,7 +14,7 @@

    Guides for SE student projects »

    AddressBook-Level3 (AB3) Tutorials

    AddressBook-Level3 (AB3) is a brownfield project template used by SE courses. Given below are some tutorials to help students understand how to navigate and modify the existing AB3 codebase.

    • Tracing code - A tutorial on how to use Intellij IDEA to trace execution paths in AB3 code.
    • Adding a command - A tutorial on how to introduce a new user command to the AB3 code.
    • Removing fields - A tutorial on how to safely remove a field of the Person class.

    Authors:

    +

    Guides for SE student projects »

    AddressBook-Level3 (AB3) Tutorials

    AddressBook-Level3 (AB3) is a brownfield project template used by SE courses. Given below are some tutorials to help students understand how to navigate and modify the existing AB3 codebase.

    • Tracing code - A tutorial on how to use Intellij IDEA to trace execution paths in AB3 code.
    • Adding a command - A tutorial on how to introduce a new user command to the AB3 code.
    • Removing fields - A tutorial on how to safely remove a field of the Person class.

    Authors:

    diff --git a/tutorials/ab3.page-vue-render.js b/tutorials/ab3.page-vue-render.js index ee7c80cd..1011ea60 100644 --- a/tutorials/ab3.page-vue-render.js +++ b/tutorials/ab3.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"addressbook-level3-ab3-tutorials"}},[_v("AddressBook-Level3 (AB3) Tutorials"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#addressbook-level3-ab3-tutorials","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://se-education.org/addressbook-level3"}},[_v("AddressBook-Level3 (AB3)")]),_v(" is a brownfield project template used by SE courses. Given below are some tutorials to help students understand how to navigate and modify the existing AB3 codebase.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/ab3TracingCode.html"}},[_c('strong',[_v("Tracing code")])]),_v(" - A tutorial on how to use Intellij IDEA to trace execution paths in AB3 code.")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/ab3AddRemark.html"}},[_c('strong',[_v("Adding a command")])]),_v(" - A tutorial on how to introduce a new user command to the AB3 code.")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/ab3RemovingFields.html"}},[_c('strong',[_v("Removing fields")])]),_v(" - A tutorial on how to safely remove a field of the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Person")]),_v(" class.")])]),_v(" "),_c('hr'),_v(" "),_c('p',[_c('strong',[_v("Authors:")])]),_v(" "),_c('ul',[_c('li',[_v("Initial Version: Jeffry Lum")]),_v(" "),_c('li',[_v("Adapted to MarkBind: "),_c('a',{attrs:{"href":"https://github.com/tlylt"}},[_v("Liu Yongliang")])])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/ab3AddRemark.html b/tutorials/ab3AddRemark.html index 06361c7d..8453ba4f 100644 --- a/tutorials/ab3AddRemark.html +++ b/tutorials/ab3AddRemark.html @@ -344,7 +344,7 @@

    Writing tests

    Tests are crucial to ensuring that bugs don’t slip into the codebase unnoticed. This is especially true for large code bases where a change might lead to unintended behavior.

    Let’s verify the correctness of our code by writing some tests!

    Of course you can simply add the test cases manually, like you've been doing all along this tutorial. The result would be like the test cases in here. Alternatively, you can get the help of IntelliJ to generate the skeletons of the test cases, as explained in the next section.

    Automatically generating tests

    The goal is to write effective and efficient tests to ensure that RemarkCommand#execute() behaves as expected.

    The convention for test names is methodName_testScenario_expectedResult. An example would be -execute_filteredList_success.

    Let’s create a test for RemarkCommand#execute() to test that adding a remark works. On IntelliJ IDEA you can bring up the context menu and choose to Go To > Test or use the appropriate keyboard shortcut.

    Then, create a test for the execute method.

    Following convention, let’s change the name of the generated method to execute_addRemarkUnfilteredList_success.

    Let’s use the utility functions provided in CommandTestUtil. The functions ensure that commands produce the expected CommandResult and output the correct message. In this case, CommandTestUtil#assertCommandSuccess is the best fit as we are testing that a RemarkCommand will successfully add a Remark.

    You should end up with a test that looks something like this.

    Conclusion

    This concludes the tutorial for adding a new Command to AddressBook.

    Previous | ToC | What's next? Removing Fields

    +execute_filteredList_success.

    Let’s create a test for RemarkCommand#execute() to test that adding a remark works. On IntelliJ IDEA you can bring up the context menu and choose to Go To > Test or use the appropriate keyboard shortcut.

    Then, create a test for the execute method.

    Following convention, let’s change the name of the generated method to execute_addRemarkUnfilteredList_success.

    Let’s use the utility functions provided in CommandTestUtil. The functions ensure that commands produce the expected CommandResult and output the correct message. In this case, CommandTestUtil#assertCommandSuccess is the best fit as we are testing that a RemarkCommand will successfully add a Remark.

    You should end up with a test that looks something like this.

    Conclusion

    This concludes the tutorial for adding a new Command to AddressBook.

    Previous | ToC | What's next? Removing Fields

    diff --git a/tutorials/ab3AddRemark.page-vue-render.js b/tutorials/ab3AddRemark.page-vue-render.js index c3a8843e..9e521cea 100644 --- a/tutorials/ab3AddRemark.page-vue-render.js +++ b/tutorials/ab3AddRemark.page-vue-render.js @@ -287,6 +287,6 @@ with(this){return _c('p',[_v("This concludes the tutorial for adding a new "),_c with(this){return _c('p',[_c('a',{attrs:{"href":"/guides/tutorials/ab3TracingCode.html"}},[_c('span',{staticClass:"fas fa-arrow-left",attrs:{"aria-hidden":"true"}}),_v(" Previous")]),_v(" | "),_c('a',{attrs:{"href":"/guides/tutorials/ab3.html"}},[_c('span',{staticClass:"fas fa-arrow-up",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_v("ToC")])]),_v(" | "),_c('span',{staticClass:"badge rounded-pill bg-primary"},[_c('strong',[_c('span',{staticClass:"large"},[_v("What's next?")])])]),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/ab3RemovingFields.html"}},[_c('span',{staticClass:"fas fa-arrow-right",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_v("Removing Fields")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/ab3RemovingFields.html b/tutorials/ab3RemovingFields.html index ff9fbc1b..9b0f3fcc 100644 --- a/tutorials/ab3RemovingFields.html +++ b/tutorials/ab3RemovingFields.html @@ -82,7 +82,7 @@ -

    You can go through each individual json file and manually remove the address field.

    Previous | ToC

    +

    You can go through each individual json file and manually remove the address field.

    Previous | ToC

    diff --git a/tutorials/ab3RemovingFields.page-vue-render.js b/tutorials/ab3RemovingFields.page-vue-render.js index 68759f66..cca5f15b 100644 --- a/tutorials/ab3RemovingFields.page-vue-render.js +++ b/tutorials/ab3RemovingFields.page-vue-render.js @@ -101,6 +101,6 @@ with(this){return _c('p',[_v("You can go through each individual "),_c('code',{p with(this){return _c('p',[_c('a',{attrs:{"href":"/guides/tutorials/ab3AddRemark.html"}},[_c('span',{staticClass:"fas fa-arrow-left",attrs:{"aria-hidden":"true"}}),_v(" Previous")]),_v(" | "),_c('a',{attrs:{"href":"/guides/tutorials/ab3.html"}},[_c('span',{staticClass:"fas fa-arrow-up",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_v("ToC")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/ab3TracingCode.html b/tutorials/ab3TracingCode.html index 9c19195b..21a62d82 100644 --- a/tutorials/ab3TracingCode.html +++ b/tutorials/ab3TracingCode.html @@ -212,7 +212,7 @@ do you think will happen if we traced the following commands instead? What exceptions do you think will be thrown (if any), where will the exceptions be thrown and where will they be handled?

    1. redit 1 n/Alice Yu

    2. edit 0 n/Alice Yu

    3. edit 1 n/Alex Yeoh

    4. edit 1

    5. edit 1 n/アリス ユー

    6. edit 1 t/one t/two t/three t/one

  • What components will you have to modify to perform the following -enhancements to the application?

    1. Make command words case-insensitive

    2. Allow delete to remove more than one index at a time

    3. Save the address book in the CSV format instead

    4. Add a new command

    5. Add a new field to Person

    6. Add a new entity to the address book

  • ToC | What's next? Adding a Command

    +enhancements to the application?

    1. Make command words case-insensitive

    2. Allow delete to remove more than one index at a time

    3. Save the address book in the CSV format instead

    4. Add a new command

    5. Add a new field to Person

    6. Add a new entity to the address book

    ToC | What's next? Adding a Command

    diff --git a/tutorials/ab3TracingCode.page-vue-render.js b/tutorials/ab3TracingCode.page-vue-render.js index effa4465..7d4cab13 100644 --- a/tutorials/ab3TracingCode.page-vue-render.js +++ b/tutorials/ab3TracingCode.page-vue-render.js @@ -191,6 +191,6 @@ with(this){return _c('ol',[_c('li',[_c('p',[_v("In this tutorial, we traced the with(this){return _c('p',[_c('a',{attrs:{"href":"/guides/tutorials/ab3.html"}},[_c('span',{staticClass:"fas fa-arrow-up",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_v("ToC")])]),_v(" | "),_c('span',{staticClass:"badge rounded-pill bg-primary"},[_c('strong',[_c('span',{staticClass:"large"},[_v("What's next?")])])]),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/ab3AddRemark.html"}},[_c('span',{staticClass:"fas fa-arrow-right",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_v("Adding a Command")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/checkstyle.html b/tutorials/checkstyle.html index 6a30ec81..60cc86e7 100644 --- a/tutorials/checkstyle.html +++ b/tutorials/checkstyle.html @@ -39,7 +39,7 @@

    Some relevant Gradle tasks added by the CheckStyle plugin.

    For example, you can run gradlew checkstyleMain checkstyleTest to verify that all your code complies with the style rules.

    Using Checkstyle-IDEA plugin

    Prerequisite: The two config files checkstyle.xml and suppressions.xml are present (see the Configuring Checkstyle section above for more details on these two files).

    Given below are the steps to install the Checkstyle-IDEA plugin so that Intellij can alert you about code style problems as you write code.

    1. Install the Checkstyle-IDEA plugin as follows:

      1. File > Settings (Windows/Linux), or IntelliJ IDEA > Settings…​ (macOS)
      2. Select Plugins (on the left slide menu in the dialog that pops up)
      3. Select Marketplace (on to top center of the same dialog box)
      4. Find the plugin.
      5. Restart the IDE to complete the installation.
    2. Click File > Settings (Windows/Linux), or IntelliJ IDEA > Settings…​ (macOS)

    3. Click Tools > Checkstyle

    4. Set Scan Scope to Only Java sources (including tests), so that the plugin will run checkstyle for our test source codes as well

    5. Ensure that the Checkstyle version is set to the one used by the project.
      If your project uses Gradle, you can check the build.gradle file to find the correct version.
      checkstyle idea scan scope

    6. Click the + sign under Configuration File

    7. Enter an arbitrary description e.g. addressbook

    8. Select Use a local Checkstyle file

    9. Use the checkstyle configuration file found at config/checkstyle/checkstyle.xml

    10. Click Next > Finish

    11. Mark Active for the newly imported check configuration
      checkstyle idea configuration

    12. Click OK

    13. To verify the plugin is set up correctly, temporarily modify the code to violate a style rule (e.g., add an extra line break before an {) and run the Checkstyle check using the plugin.

    Troubleshooting

    Problem: When importing checkstyle.xml, Checkstyle-IDEA plugin complains that The Checkstyle rules file could not be parsed. …​ The file has been blacklisted for 60s.

    Problem: After setting up checkstyle.xml, Checkstyle-IDEA plugin does not seem to highlight the errors / real-time scanning seems broken.

    Resources

    +Apply, as checkstyle.xml is written for Gradle’s checkstyle.

    Problem: After setting up checkstyle.xml, Checkstyle-IDEA plugin does not seem to highlight the errors / real-time scanning seems broken.

    Resources

    diff --git a/tutorials/checkstyle.page-vue-render.js b/tutorials/checkstyle.page-vue-render.js index 088cf823..2559bc0a 100644 --- a/tutorials/checkstyle.page-vue-render.js +++ b/tutorials/checkstyle.page-vue-render.js @@ -77,6 +77,6 @@ with(this){return _c('h2',{attrs:{"id":"resources"}},[_v("Resources"),_c('a',{st with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"https://checkstyle.sourceforge.io/"}},[_v("Checkstyle home page")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docs.gradle.org/current/userguide/checkstyle_plugin.html"}},[_v("Gradle documentation for the Checkstyle plugin")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/codecov.html b/tutorials/codecov.html index 0517c2fa..deaf00de 100644 --- a/tutorials/codecov.html +++ b/tutorials/codecov.html @@ -14,11 +14,13 @@

    Guides for SE student projects »

    Using Codecov

    Codecov is an online service for generating test coverage reports.

    Setting up Codecov with GitHub actions

    Scenario: You have forked a project that already had support for using Codecov in the GitHub Actions CI pipeline. Now you want to set up your fork to work with Codecov as well.

    Given below are the steps for achieving the above, recommended to be done by someone who has admin access to the GitHub organization that contains the fork.

    1. Sign up for a Codecov account using your GitHub account.
    2. Authorize Codecov to access your repo: Go to this page, go to the Organization Access section, and click the button in front of your GitHub org's name.
      -If you don't have admin rights to the org in concern, you need to click on the button instead, and wait for an admin to approve the request.
    3. Sync your repo list in Codecov: Login to Codecov using your GitHub account. Ensure your org/fork is listed in the home page. If not, use the re-syncing link to sync Codecov data with GitHub (and refresh the page afterward). Try again if it doesn't work the first time, as syncing might take some time.
      -If the organization still fails to show up in the dropdown, you can also try the Add GitHub organization link at the bottom of the dropdown list. Doing so will allow you to install the Codecov integration on your GitHub organization, which is same as the next step.
    4. Install the Codecov integration on GitHub: Go to this page and click on the green button. In the next steps, choose the org and the fork you want to set up Codecov for (you can also use the All repositories option instead).
    5. Configure Codecov for the specific fork: Go to https://app.codecov.io/gh/{YOUR_ORG} (e.g., https://app.codecov.io/gh/my-team-org).
      -Choose the Setup repo> option for your fork, and follow the instructions for GitHub Actions. You will need to set up the CODECOV_TOKEN secret as instructed but there is no need to update the workflow YAML file (as the repo you forked already has a YAML file containing the given code).
    6. Check for coverage status: Go back to your Codecov home page. After the next time CI runs in your fork, you should see the code coverage percentage in front of your fork name. Here is an example: -
    7. Display the Codecov badge: If your fork has a badge showing the Codecov status (e.g, codecov), get the Markdown code for the Codecov badge provided in https://app.codecov.io/gh/{YOUR_ORG}/{YOUR_FORK}/settings/badge (e.g., https://app.codecov.io/gh/se-edu/addressbook-level3/settings/badge) and update the appropriate page in your fork.

    You can control if CI still passes even if Codecov task fails using the line
    fail_ci_if_error: true or fail_ci_if_error: false in .github/workflows/gradle.yml, under the section related to Codecov.

    +

    Guides for SE student projects »

    Using Codecov

    Codecov is an online service for generating test coverage reports.

    Setting up Codecov with GitHub actions

    Scenario: You have forked a project that already had support for using Codecov in the GitHub Actions CI pipeline. Now you want to set up your fork to work with Codecov as well.

    Given below are the steps for achieving the above, recommended to be done by someone who has admin access to the GitHub organization that contains the fork.

    1. Sign up for a Codecov account using your GitHub account.
    2. Install the Codecov integration on GitHub:: +
      1. Go to this page and click on the green button.
      2. In the next page, select your GitHub organization
      3. In the next page, choose the Only select repositories and choose your repo (you can also use the All repositories option instead). After that, click the .
    3. Sync your repo list in Codecov: Login to Codecov using your GitHub account. Ensure your org/fork is listed in the home page. If not, use the re-syncing link to sync Codecov data with GitHub (and refresh the page afterward).
      +If the organization still fails to show up in the dropdown, proceed to the next step anyway (it's likely the syncing is done but the UI is not showing it).
    4. Configure Codecov for the specific fork:
      1. Go to https://app.codecov.io/gh/{YOUR_ORG} (e.g., https://app.codecov.io/gh/my-team-org).
      2. Click the option for your fork, and follow the instructions for GitHub Actions.
        +You can skip the Step 1: Generate and upload coverage reports in your CI, as it is already set up in your repo.
        +But you still need to do steps 2 i.e., set up the CODECOV_TOKEN secret as instructed but there.
        +You can skip step 3 as well.
    5. Check for coverage status: Go back to your Codecov home page, choose the org and click on the repo name. After the next time CI runs in your fork, you should see the code coverage percentage in front of your fork name. Here is an example: +
    6. Display the Codecov badge: If your fork has a badge showing the Codecov status (e.g, codecov), get the Markdown code for the Codecov badge provided in https://app.codecov.io/gh/{YOUR_ORG}/{YOUR_FORK}/settings/badge (e.g., https://app.codecov.io/gh/se-edu/addressbook-level3/settings/badge) and update the appropriate page in your fork.

    You can control if CI still passes even if Codecov task fails using the line
    fail_ci_if_error: true or fail_ci_if_error: false in .github/workflows/gradle.yml, under the section related to Codecov.

    diff --git a/tutorials/codecov.page-vue-render.js b/tutorials/codecov.page-vue-render.js index be9c15d4..8f184b86 100644 --- a/tutorials/codecov.page-vue-render.js +++ b/tutorials/codecov.page-vue-render.js @@ -1,7 +1,7 @@ var pageVueRenderFn = function anonymous( ) { -with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":""}},[_c('navbar',{attrs:{"type":"dark"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"https://se-education.org","title":"SE-EDU"}},[_c('span',[_c('span',{staticClass:"fas fa-chevron-circle-left",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_c('strong',[_v("SE-EDU")])])])])]},proxy:true},{key:"right",fn:function(){return [_c('li',{staticClass:"nav-link"},[_c('form',{staticClass:"navbar-form"},[_c('searchbar',{attrs:{"data":searchData,"placeholder":"Search this site","on-hit":searchCallback,"menu-align-right":""}})],1)])]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/index.html"}},[_c('span',[_c('strong',[_v("Home")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/about.html"}},[_c('span',[_c('strong',[_v("About")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/se-edu/guides"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])])],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_c('p'),_m(1),_v(" "),_m(2),_v(" "),_m(3),_v(" "),_c('p',[_v("Scenario: You have forked a project that already had support for using Codecov in the GitHub Actions CI pipeline. Now you want to set up your fork to work with Codecov as well.")]),_v(" "),_c('p',[_v("Given below are the steps for achieving the above, recommended to be done by someone who has admin access to the GitHub organization that contains the fork.")]),_v(" "),_c('ol',[_m(4),_v(" "),_m(5),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_m(8),_v(" "),_c('li',[_c('strong',[_v("Check for coverage status:")]),_v(" Go back to "),_c('a',{attrs:{"href":"https://app.codecov.io/gh"}},[_v("your Codecov home page")]),_v(". After the next time CI runs in your fork, you should see the code coverage percentage in front of your fork name. Here is an example:\n"),_c('pic',{attrs:{"src":"/guides/tutorials/images/codecov/coverage-example.png"}})],1),_v(" "),_m(9)]),_v(" "),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_c('strong',[_v("You can control if CI still passes even if Codecov task fails")]),_v(" using the line"),_c('br'),_v(" "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("fail_ci_if_error: true")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("fail_ci_if_error: false")]),_v(" in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".github/workflows/gradle.yml")]),_v(", under the section related to Codecov.")])]),_c('p')],1),_v(" "),_c('overlay-source',{staticClass:"fixed-header-padding",attrs:{"id":"page-nav","tag-name":"nav","to":"page-nav"}},[_c('div',{staticClass:"nav-component slim-scroll"},[_c('overlay-source',{staticClass:"nav nav-pills flex-column my-0 small no-flex-wrap",attrs:{"id":"mb-page-nav","tag-name":"nav","to":"mb-page-nav"}},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#using-codecov"}},[_v("Using Codecov‎")]),_v(" "),_c('nav',{staticClass:"nav nav-pills flex-column my-0 nested no-flex-wrap"},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-codecov-with-github-actions"}},[_v("Setting up Codecov with GitHub actions‎")])])])],1)]),_v(" "),_c('scroll-top-button')],1),_v(" "),_m(10)])} +with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":""}},[_c('navbar',{attrs:{"type":"dark"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"https://se-education.org","title":"SE-EDU"}},[_c('span',[_c('span',{staticClass:"fas fa-chevron-circle-left",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_c('strong',[_v("SE-EDU")])])])])]},proxy:true},{key:"right",fn:function(){return [_c('li',{staticClass:"nav-link"},[_c('form',{staticClass:"navbar-form"},[_c('searchbar',{attrs:{"data":searchData,"placeholder":"Search this site","on-hit":searchCallback,"menu-align-right":""}})],1)])]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/index.html"}},[_c('span',[_c('strong',[_v("Home")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/about.html"}},[_c('span',[_c('strong',[_v("About")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/se-edu/guides"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])])],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_c('p'),_m(1),_v(" "),_m(2),_v(" "),_m(3),_v(" "),_c('p',[_v("Scenario: You have forked a project that already had support for using Codecov in the GitHub Actions CI pipeline. Now you want to set up your fork to work with Codecov as well.")]),_v(" "),_c('p',[_v("Given below are the steps for achieving the above, recommended to be done by someone who has admin access to the GitHub organization that contains the fork.")]),_v(" "),_c('ol',[_m(4),_v(" "),_c('li',[_c('strong',[_v("Install the Codecov integration on GitHub:")]),_v(":\n"),_c('ol',[_m(5),_v(" "),_c('li',[_v("In the next page, select your GitHub organization")]),_v(" "),_c('li',[_v("In the next page, choose the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Only select repositories")]),_v(" and choose your repo (you can also use the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("All repositories")]),_v(" option instead). After that, click the "),_c('button',{staticClass:"btn btn-success btn-sm",attrs:{"type":"button"}},[_v("Install")]),_v("."),_c('br'),_v(" "),_c('pic',{attrs:{"src":"/guides/tutorials/images/codecov/select-repo.png","width":"400"}})],1)])]),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_c('li',[_c('strong',[_v("Check for coverage status:")]),_v(" Go back to "),_c('a',{attrs:{"href":"https://app.codecov.io/gh"}},[_v("your Codecov home page")]),_v(", choose the org and click on the repo name. After the next time CI runs in your fork, you should see the code coverage percentage in front of your fork name. Here is an example:\n"),_c('pic',{attrs:{"src":"/guides/tutorials/images/codecov/coverage-example.png"}})],1),_v(" "),_m(8)]),_v(" "),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_c('strong',[_v("You can control if CI still passes even if Codecov task fails")]),_v(" using the line"),_c('br'),_v(" "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("fail_ci_if_error: true")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("fail_ci_if_error: false")]),_v(" in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".github/workflows/gradle.yml")]),_v(", under the section related to Codecov.")])]),_c('p')],1),_v(" "),_c('overlay-source',{staticClass:"fixed-header-padding",attrs:{"id":"page-nav","tag-name":"nav","to":"page-nav"}},[_c('div',{staticClass:"nav-component slim-scroll"},[_c('overlay-source',{staticClass:"nav nav-pills flex-column my-0 small no-flex-wrap",attrs:{"id":"mb-page-nav","tag-name":"nav","to":"mb-page-nav"}},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#using-codecov"}},[_v("Using Codecov‎")]),_v(" "),_c('nav',{staticClass:"nav nav-pills flex-column my-0 nested no-flex-wrap"},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-codecov-with-github-actions"}},[_v("Setting up Codecov with GitHub actions‎")])])])],1)]),_v(" "),_c('scroll-top-button')],1),_v(" "),_m(9)])} }; var pageVueStaticRenderFns = [function anonymous( ) { @@ -20,21 +20,18 @@ with(this){return _c('h2',{attrs:{"id":"setting-up-codecov-with-github-actions"} with(this){return _c('li',[_c('a',{attrs:{"href":"https://app.codecov.io/signup/"}},[_c('strong',[_v("Sign up for a Codecov account")])]),_v(" using your GitHub account.")])} },function anonymous( ) { -with(this){return _c('li',[_c('strong',[_v("Authorize Codecov to access your repo")]),_v(": Go to "),_c('a',{attrs:{"href":"https://github.com/settings/connections/applications/c68c81cbfd179a50784a"}},[_v("this page")]),_v(", go to the "),_c('span',{staticClass:"large"},[_v("Organization Access")]),_v(" section, and click the "),_c('button',{staticClass:"btn btn-outline-primary btn-sm",attrs:{"type":"button"}},[_v("grant")]),_v(" button in front of your GitHub org's name."),_c('br'),_v("\nIf you don't have admin rights to the org in concern, you need to click on the "),_c('button',{staticClass:"btn btn-outline-primary btn-sm",attrs:{"type":"button"}},[_v("request")]),_v(" button instead, and wait for an admin to approve the request.")])} +with(this){return _c('li',[_v("Go to "),_c('a',{attrs:{"href":"https://github.com/apps/codecov"}},[_v("this page")]),_v(" and click on the green "),_c('button',{staticClass:"btn btn-success btn-sm",attrs:{"type":"button"}},[_v("Install")]),_v(" button.")])} },function anonymous( ) { -with(this){return _c('li',[_c('strong',[_v("Sync your repo list in Codecov:")]),_v(" Login to "),_c('a',{attrs:{"href":"https://app.codecov.io"}},[_v("Codecov")]),_v(" using your GitHub account. Ensure your "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("org/fork")]),_v(" is listed in the home page. If not, use the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("re-syncing")]),_v(" link to sync Codecov data with GitHub (and refresh the page afterward). Try again if it doesn't work the first time, as syncing might take some time."),_c('br'),_v("\nIf the organization still fails to show up in the dropdown, you can also try the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Add GitHub organization")]),_v(" link at the bottom of the dropdown list. Doing so will allow you to install the Codecov integration on your GitHub organization, which is same as the next step.")])} +with(this){return _c('li',[_c('strong',[_v("Sync your repo list in Codecov:")]),_v(" Login to "),_c('a',{attrs:{"href":"https://app.codecov.io"}},[_v("Codecov")]),_v(" using your GitHub account. Ensure your "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("org/fork")]),_v(" is listed in the home page. If not, use the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("re-syncing")]),_v(" link to sync Codecov data with GitHub (and refresh the page afterward)."),_c('br'),_v("\nIf the organization still fails to show up in the dropdown, proceed to the next step anyway (it's likely the syncing is done but the UI is not showing it).")])} },function anonymous( ) { -with(this){return _c('li',[_c('strong',[_v("Install the Codecov integration on GitHub:")]),_v(" Go to "),_c('a',{attrs:{"href":"https://github.com/apps/codecov"}},[_v("this page")]),_v(" and click on the green "),_c('button',{staticClass:"btn btn-success btn-sm",attrs:{"type":"button"}},[_v("Install")]),_v(" button. In the next steps, choose the org and the fork you want to set up Codecov for (you can also use the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("All repositories")]),_v(" option instead).")])} -},function anonymous( -) { -with(this){return _c('li',[_c('strong',[_v("Configure Codecov for the specific fork:")]),_v(" Go to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/{YOUR_ORG}")]),_v(" (e.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/my-team-org")]),_v(")."),_c('br'),_v("\nChoose the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Setup repo>")]),_v(" option for your fork, and follow the instructions for GitHub Actions. You will need to set up the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("CODECOV_TOKEN")]),_v(" secret as instructed but there is "),_c('mark',[_v("no need to update the workflow YAML file")]),_v(" (as the repo you forked already has a YAML file containing the given code).")])} +with(this){return _c('li',[_c('strong',[_v("Configure Codecov for the specific fork:")]),_v(" "),_c('ol',[_c('li',[_v("Go to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/{YOUR_ORG}")]),_v(" (e.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/my-team-org")]),_v(").")]),_v(" "),_c('li',[_v("Click the "),_c('button',{staticClass:"btn btn-primary btn-sm",attrs:{"type":"button"}},[_v("Configure")]),_v(" option for your fork, and follow the instructions for GitHub Actions."),_c('br'),_v("\nYou can skip the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Step 1: Generate and upload coverage reports in your CI")]),_v(", as it is already set up in your repo."),_c('br'),_v("\nBut you still need to do steps 2 i.e., set up the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("CODECOV_TOKEN")]),_v(" secret as instructed but there."),_c('br'),_v("\nYou can skip step 3 as well.")])])])} },function anonymous( ) { with(this){return _c('li',[_c('strong',[_v("Display the Codecov badge:")]),_v(" If your fork has a badge showing the Codecov status (e.g, "),_c('a',{attrs:{"href":"https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg","alt":"codecov"}})]),_v("), get the Markdown code for the Codecov badge provided in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/{YOUR_ORG}/{YOUR_FORK}/settings/badge")]),_v(" (e.g., "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("https://app.codecov.io/gh/se-edu/addressbook-level3/settings/badge")]),_v(") and update the appropriate page in your fork.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/githubActions.html b/tutorials/githubActions.html index e9b19be1..5eec3b67 100644 --- a/tutorials/githubActions.html +++ b/tutorials/githubActions.html @@ -14,7 +14,7 @@

    Guides for SE student projects »

    Using GitHub Actions

    GitHub Actions is CI/CD tool integrated into GitHub.

    Setting up a custom workflow

    In the simplest case, setting up is a matter of adding a .yml file into the [root]\.github\workflows folder (example).

    GitHub Actions will run the workflow (as per the .yml file) every time certain project events are triggered (e.g., when a PR is updated, or the master branch is updated).

    Resources

    +

    Guides for SE student projects »

    Using GitHub Actions

    GitHub Actions is CI/CD tool integrated into GitHub.

    Setting up a custom workflow

    In the simplest case, setting up is a matter of adding a .yml file into the [root]\.github\workflows folder (example).

    GitHub Actions will run the workflow (as per the .yml file) every time certain project events are triggered (e.g., when a PR is updated, or the master branch is updated).

    Resources

    diff --git a/tutorials/githubActions.page-vue-render.js b/tutorials/githubActions.page-vue-render.js index 42d19e03..e1aa2d25 100644 --- a/tutorials/githubActions.page-vue-render.js +++ b/tutorials/githubActions.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"using-github-actions"}},[_v("Using GitHub Actions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#using-github-actions","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"lead"},[_c('p',[_c('a',{attrs:{"href":"https://github.com/features/actions"}},[_v("GitHub Actions")]),_v(" is CI/CD tool integrated into GitHub.")])]),_v(" "),_c('h2',{attrs:{"id":"setting-up-a-custom-workflow"}},[_v("Setting up a custom workflow"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#setting-up-a-custom-workflow","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In the simplest case, setting up is a matter of adding a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".yml")]),_v(" file into the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("[root]\\.github\\workflows")]),_v(" folder ("),_c('a',{attrs:{"href":"https://github.com/se-edu/duke/blob/full-template/.github/workflows/gradle.yml"}},[_v("example")]),_v(").")]),_v(" "),_c('p',[_v("GitHub Actions will run the workflow (as per the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".yml")]),_v(" file) every time certain project events are triggered (e.g., when a PR is updated, or the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("master")]),_v(" branch is updated).")]),_v(" "),_c('h2',{attrs:{"id":"resources"}},[_v("Resources"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resources","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://help.github.com/en/actions"}},[_v("GitHub Actions documentation")])])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/gradle.html b/tutorials/gradle.html index 30889942..9e89a0c4 100644 --- a/tutorials/gradle.html +++ b/tutorials/gradle.html @@ -124,7 +124,7 @@ -

    Resources


    Authors:

    +

    Resources


    Authors:

    diff --git a/tutorials/gradle.page-vue-render.js b/tutorials/gradle.page-vue-render.js index 4309fdc0..c24e67f2 100644 --- a/tutorials/gradle.page-vue-render.js +++ b/tutorials/gradle.page-vue-render.js @@ -35,6 +35,6 @@ with(this){return _c('p',[_v("There are several ways of integrating Gradle into with(this){return _c('p',[_c('strong',[_c('strong',[_v("Scenario 1:")])]),_v(" You are setting up a project that already has Gradle wrapper files.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/images/codecov/coverage-example.png b/tutorials/images/codecov/coverage-example.png index c3cbe07b309031f54b8d043a40a86bf5a2e97270..883c14dab68011fcaa4e56dcf8bc887353c8963f 100644 GIT binary patch literal 44032 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 z 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
    0KYYeCv%Cuwr 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

    x=2??T0r7OxgJ|BmszI$XzHhdks()?N#uJ| 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 OfV8B%METp#KK}<2Tf;K| diff --git a/tutorials/images/codecov/select-repo.png b/tutorials/images/codecov/select-repo.png new file mode 100644 index 0000000000000000000000000000000000000000..b3bec9314889d9aa2f40c55da8542d5bf3e05e90 GIT binary patch literal 73235 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

    6epun3qq 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%0Af^~#xlgN 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

    Guides for SE student projects »

    Intellij IDEA: Configuring the code style

    IntelliJ’s default style is mostly compliant with ours but it uses a different import order from ours but some tweaks may be needed.

    Legend: basic tweak | intermediate tweak | advanced tweak

    Tweak: switch-case style

    1. Go to FileSettings…​ (Windows/Linux), or IntelliJ IDEASettings…​ (macOS).
    2. Click on EditorCode styleJava (see the screenshot below).
    3. Click on the Wrapping and Braces tab and un-tick the Indent 'case' branches option (as shown in the screenshot above).

    Tweak: import order

    1. Go to FileSettings…​ (Windows/Linux), or IntelliJ IDEASettings…​ (macOS).
    2. Select EditorCode StyleJava.
    3. Click on the Imports tab to set the import order. -
      • For Class count to use import with '*' and Names count to use static import with '*': Set to 999 to prevent IntelliJ from contracting the import statements.
      • For Import Layout: The order is:

    Tweak: Auto-remove trailing spaces

    You can configure Intellij to automatically strip trailing white space in code lines, as follows:

    1. Go to Settings.
    2. On the left side of the dialog, click on Editor -> General.
    3. On the right side, scroll to the On Save section.
    4. Change Remove trailing spaces on: to Modified lines.

    More useful settings

    The tweaks given above are specific to code style. A few more useful settings (not related to the code style) can be found here.

    +
    • For Class count to use import with '*' and Names count to use static import with '*': Set to 999 to prevent IntelliJ from contracting the import statements.
    • For Import Layout: The order is:

    Tweak: Auto-remove trailing spaces

    You can configure Intellij to automatically strip trailing white space in code lines, as follows:

    1. Go to Settings.
    2. On the left side of the dialog, click on Editor -> General.
    3. On the right side, scroll to the On Save section.
    4. Change Remove trailing spaces on: to Modified lines.

    More useful settings

    The tweaks given above are specific to code style. A few more useful settings (not related to the code style) can be found here.

    diff --git a/tutorials/intellijCodeStyle.page-vue-render.js b/tutorials/intellijCodeStyle.page-vue-render.js index fa6f0f01..e73ad8a8 100644 --- a/tutorials/intellijCodeStyle.page-vue-render.js +++ b/tutorials/intellijCodeStyle.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"intellij-idea-configuring-the-code-style"}},[_v("Intellij IDEA: Configuring the code style"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#intellij-idea-configuring-the-code-style","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("IntelliJ’s default style is mostly compliant with "),_c('a',{attrs:{"href":"/guides/conventions/java"}},[_v("ours")]),_v(" but it uses a different import order from ours but some tweaks may be needed.")]),_v(" "),_c('p',[_c('strong',[_v("Legend")]),_v(": "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-danger"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_v(" basic tweak | "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-warning text-white"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_v(" intermediate tweak | "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-success"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_v(" advanced tweak")]),_v(" "),_c('h2',{attrs:{"id":"tweak-switch-case-style"}},[_v("Tweak: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("switch-case")]),_v(" style "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-danger"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tweak-switch-case-style","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ol',[_c('li',[_v("Go to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("File")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings…​")]),_v(" (Windows/Linux), or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IntelliJ IDEA")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings…​")]),_v(" (macOS).")]),_v(" "),_c('li',[_v("Click on "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Editor")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Code style")]),_v("→ "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Java")]),_v(" (see the screenshot below)."),_c('br'),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/images/intellij/codeStyle-switch.png","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"/guides/tutorials/images/intellij/codeStyle-switch.png","alt":""}})])]),_v(" "),_c('li',[_v("Click on the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Wrapping and Braces")]),_v(" tab and un-tick the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Indent 'case' branches")]),_v(" option (as shown in the screenshot above).")])]),_v(" "),_c('h2',{attrs:{"id":"tweak-import-order"}},[_v("Tweak: "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("import")]),_v(" order "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-warning text-white"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tweak-import-order","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ol',[_c('li',[_v("Go to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("File")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings…​")]),_v(" (Windows/Linux), or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("IntelliJ IDEA")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings…​")]),_v(" (macOS).")]),_v(" "),_c('li',[_v("Select "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Editor")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Code Style")]),_v(" → "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Java")]),_v(".")]),_v(" "),_c('li',[_v("Click on the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Imports")]),_v(" tab to set the import order.\n"),_c('ul',[_c('li',[_v("For "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Class count to use import with '*'")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Names count to use static import with '*'")]),_v(": Set to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("999")]),_v(" to prevent IntelliJ from contracting the import statements.")]),_v(" "),_c('li',[_v("For "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Import Layout")]),_v(": The order is:"),_c('br'),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/images/intellij/importOrder.png","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"/guides/tutorials/images/intellij/importOrder.png","alt":""}})])])])])]),_v(" "),_c('h2',{attrs:{"id":"tweak-auto-remove-trailing-spaces"}},[_v("Tweak: Auto-remove trailing spaces "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-warning text-white"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#tweak-auto-remove-trailing-spaces","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("You can configure Intellij to automatically strip trailing white space in code lines, as follows:")]),_v(" "),_c('ol',[_c('li',[_v("Go to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings")]),_v(".")]),_v(" "),_c('li',[_v("On the left side of the dialog, click on "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Editor")]),_v(" -> "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("General")]),_v(".")]),_v(" "),_c('li',[_v("On the right side, scroll to the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("On Save")]),_v(" section.")]),_v(" "),_c('li',[_v("Change "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Remove trailing spaces on:")]),_v(" to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Modified lines")]),_v(".")])]),_v(" "),_c('h2',{attrs:{"id":"more-useful-settings"}},[_v("More useful settings "),_c('span',[_c('span',{staticClass:"badge rounded-pill bg-success"},[_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}}),_c('span',{staticClass:"far fa-star",attrs:{"aria-hidden":"true"}})])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#more-useful-settings","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("The tweaks given above are specific to code style. A few more useful settings (not related to the code style) can be found "),_c('a',{attrs:{"href":"/guides/tutorials/intellijUsefulSettings.html"}},[_v("here")]),_v(".")]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/intellijDebugger.html b/tutorials/intellijDebugger.html index 76dd1bb7..3c297589 100644 --- a/tutorials/intellijDebugger.html +++ b/tutorials/intellijDebugger.html @@ -15,7 +15,7 @@

    Guides for SE student projects »

    Intellij IDEA: Using the debugger

    This tutorial covers basics of the Intellij IDEA's debugging features.

    • If you are new to using an IDE-based debugger, we recommend that you watch the following video (from LaunchCode) which gives a pretty good explanation of how to use the IntelliJ IDEA debugger.

      Debugging in IntelliJ


    • To recall how to use a specific feature, you can use the sections below.

    Setting breakpoints

    Purpose: A breakpoint is a line in the code at which the debugger will pause the execution.

    How: Click on the left gutter of the editor pane, at the line where you want to breakpoint. A red dot will appear to indicate the breakpoint.


    [image credit: Intelli]

    To remove the breakpoint, click the red dot again.

    Video segment 3.09 - 3.30 :

    More info from Intellij is here.

    Running the code in 'debugger mode'

    Purpose: To get Intellij to run the code in the debugger mode, so that the debugger can direct the execution flow as needed by the debugging.

    How: There are several ways. One of them is to click the icon in the gutter near the class with the main() method and select Debug.


    [image credit: Intelli]

    Video segment 3.53 - 4.00 :

    More info from Intellij is here.

    Examining the state of the suspended program

    Purpose: To examine variable values at a specific step of the execution.

    How: Use the Debugger tool window (the bottom part of the screenshot below). Ccurrent value of each variable is listed in the panel on the bottom right.


    [image credit: LaunchCode]

    Show execution point feature can be used to jump to the line of code that the debugger has stopped at (in case the line is not currently visible in the code editor):

    ShowExecutionPoint

    Video segment 4.41 - 6.06 :

    More info from Intellij is here.

    Stepping through code

    Purpose: Executes the current statement, and move to the next statement.

    How: Click the Step Over button in the debugger toolbar, as shown below.


    [image credit: se-edu]

    Video segment 7.30 - 7.55 :

    More info from Intellij is here.

    Stepping into a method

    Purpose: Suppose the current statement calls another method, and you are interested to see how the execution goes through that method. Here, you can step into that method.

    How: Click the Step Into button in the debugger toolbar, as shown below.


    [image credit: se-edu]

    Video segment 13.05 - 13.35 :

    When trying to step into a statement such as storage.saveAddressBook(model.getAddressBook()) which contains multiple method calls, Intellij will let you choose (by clicking) which one you want to step into.

    More info from Intellij is here.

    Stepping out of a method

    Purpose: Executes the remaining lines of code in the current method and returns to the caller.
    -Used when you've stepped into a method, stepped through some of it, and now want to return to the caller method without stepping through the remainder of the current method.

    How: Click the Step Out button in the debugger toolbar, as shown below.


    [image credit: LaunchCode]

    Video segment 13.45 - 13.55 :

    More info from Intellij is here.

    Setting a conditional breakpoint

    Purpose: To pause the execution at a certain breakpoint only when a certain condition is met e.g., to stop at a breakpoint only when the 100th iteration of a loop.

    How: Right-click on a breakpoint and enter a condition (e.g., i == 5)


    [image credit: LaunchCode]

    Video segment 15.20 - 16.45 :

    Evaluate expression

    Purpose: Allows you to compute the value of an expression at a specific point during execution, enabling dynamic inspection of variables and data structures.
    e.g., while debugging, you want to find the result of expressions truncate(myVariable * 2) based on the current value myVariable

    How: Enter it in the Evaluate expression field in the Variables pane (shown below) and press Enter.


    [image credit: Tom Gregory Tech]

    More info from Intellij is here.

    Set an exception breakpoint

    Purpose: To pause execution whenever a specified exception is thrown, regardless of where it occurs in your code, making it easier to identify and diagnose issues.

    How: Choose Run > View Breakpoints from the main menu, and use the icon to add an exception breakpoint, as shown below.


    [image credit: Tom Gregory Tech]

    More info from Intellij is here.


    Authors:

    +Used when you've stepped into a method, stepped through some of it, and now want to return to the caller method without stepping through the remainder of the current method.

    How: Click the Step Out button in the debugger toolbar, as shown below.


    [image credit: LaunchCode]

    Video segment 13.45 - 13.55 :

    More info from Intellij is here.

    Setting a conditional breakpoint

    Purpose: To pause the execution at a certain breakpoint only when a certain condition is met e.g., to stop at a breakpoint only when the 100th iteration of a loop.

    How: Right-click on a breakpoint and enter a condition (e.g., i == 5)


    [image credit: LaunchCode]

    Video segment 15.20 - 16.45 :

    Evaluate expression

    Purpose: Allows you to compute the value of an expression at a specific point during execution, enabling dynamic inspection of variables and data structures.
    e.g., while debugging, you want to find the result of expressions truncate(myVariable * 2) based on the current value myVariable

    How: Enter it in the Evaluate expression field in the Variables pane (shown below) and press Enter.


    [image credit: Tom Gregory Tech]

    More info from Intellij is here.

    Set an exception breakpoint

    Purpose: To pause execution whenever a specified exception is thrown, regardless of where it occurs in your code, making it easier to identify and diagnose issues.

    How: Choose Run > View Breakpoints from the main menu, and use the icon to add an exception breakpoint, as shown below.


    [image credit: Tom Gregory Tech]

    More info from Intellij is here.


    Authors:

    diff --git a/tutorials/intellijDebugger.page-vue-render.js b/tutorials/intellijDebugger.page-vue-render.js index 7d7e3381..d69d6af1 100644 --- a/tutorials/intellijDebugger.page-vue-render.js +++ b/tutorials/intellijDebugger.page-vue-render.js @@ -131,6 +131,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: "),_c('a',{attrs:{"href":"https://github.com/ruishanteo"}},[_v("@ruishanteo")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/intellijImportGradleProject.html b/tutorials/intellijImportGradleProject.html index 47345f17..e78212bb 100644 --- a/tutorials/intellijImportGradleProject.html +++ b/tutorials/intellijImportGradleProject.html @@ -19,7 +19,7 @@ i. Select the project directory, and click OK.
    ii. If there are any further prompts, accept the defaults but do ensure that the selected version of Gradle JVM matches the JDK being used for the project.
  • Confirm the correct Java version is being used for Gradle, as follows:
    (a) Confirm the project JDK is set to the one you are supposed to use for the project, as explained here.
    -(b) Confirm the correct JVM is used for Gradle, as given in the panel below:
  • Intellij: Setting the JVM for Gradle

    Go to File -> Settings and ensure the Gradle JVM is set as Project SDK ..., so that Gradle will use the same JDK used by the project.

    Also take note of the Build and run using: and Run tests using: settings. They are useful if you want to control whether you want Intellij to use Gradle to build/run/test your project.


    1. After the importing of the project is complete (which could take a few minutes), you will see the Gradle Toolbar in the IDEA interface e.g., look for the elephant icon (on Windows, this appears on the right-edge of the IDE window) and click it.
      Gradle icon

    +(b) Confirm the correct JVM is used for Gradle, as given in the panel below:

    Intellij: Setting the JVM for Gradle

    Go to File -> Settings and ensure the Gradle JVM is set as Project SDK ..., so that Gradle will use the same JDK used by the project.

    Also take note of the Build and run using: and Run tests using: settings. They are useful if you want to control whether you want Intellij to use Gradle to build/run/test your project.


    1. After the importing of the project is complete (which could take a few minutes), you will see the Gradle Toolbar in the IDEA interface e.g., look for the elephant icon (on Windows, this appears on the right-edge of the IDE window) and click it.
      Gradle icon

    diff --git a/tutorials/intellijImportGradleProject.page-vue-render.js b/tutorials/intellijImportGradleProject.page-vue-render.js index f8988689..3e23f808 100644 --- a/tutorials/intellijImportGradleProject.page-vue-render.js +++ b/tutorials/intellijImportGradleProject.page-vue-render.js @@ -17,6 +17,6 @@ with(this){return _c('ol',[_c('li',[_v("Open Intellij.")]),_v(" "),_c('li',[_v(" with(this){return _c('ol',{attrs:{"start":"4"}},[_c('li',[_v("After the importing of the project is complete (which could take a few minutes), you will see the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Gradle Toolbar")]),_v(" in the IDEA interface "),_c('span',{staticClass:"dimmed"},[_v("e.g., look for the elephant icon (on Windows, this appears on the right-edge of the IDE window) and click it")]),_v("."),_c('br'),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/images/gradle/GradleIcon.png","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"/guides/tutorials/images/gradle/GradleIcon.png","alt":"Gradle icon"}})])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/intellijJdk.html b/tutorials/intellijJdk.html index 2fdd3eed..0a95fa76 100644 --- a/tutorials/intellijJdk.html +++ b/tutorials/intellijJdk.html @@ -14,7 +14,7 @@

    Guides for SE student projects »

    Intellij IDEA: Configuring the JDK

    Please refer to Intellij's own documentation here.

    +

    Guides for SE student projects »

    Intellij IDEA: Configuring the JDK

    Please refer to Intellij's own documentation here.

    diff --git a/tutorials/intellijJdk.page-vue-render.js b/tutorials/intellijJdk.page-vue-render.js index ce23806e..0ac0766b 100644 --- a/tutorials/intellijJdk.page-vue-render.js +++ b/tutorials/intellijJdk.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"intellij-idea-configuring-the-jdk"}},[_v("Intellij IDEA: Configuring the JDK"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#intellij-idea-configuring-the-jdk","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Please refer to Intellij's own documentation "),_c('a',{attrs:{"href":"https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk"}},[_v("here")]),_v(".")]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/intellijUsefulSettings.html b/tutorials/intellijUsefulSettings.html index 1507371d..52542a47 100644 --- a/tutorials/intellijUsefulSettings.html +++ b/tutorials/intellijUsefulSettings.html @@ -15,7 +15,7 @@

    Guides for SE student projects »

    Intellij IDEA: Useful settings

    Enabling assertions

    This tweak does not apply if you use Gradle to run code even within Intellij. In that case, refer to 'Enabling assertions' sections of the Gradle tutorial.

    1. Choose RunEdit Configurations....
    2. Select the run configuration of interest.
    3. Click on Modify options link and choose Add VM options
    4. Add -ea to the VM options box. -

    Enabling soft wrapping

    While it is common to enforce a maximum line length for code written in some languages (typically, for code made up of statements such as Java), it is also common not to enforce such a limit for source content that contain paragraph-like structures (e.g., Markdown, HTML). In such cases, you'll need to scroll the editor window horizontally to read the content, which can be a frustrating experience. Here's an example (notice how the text continues beyond the visible area of the editor window and you need to use the horizontal scrolling to see the hidden part):

    Luckily, you can use the 'soft wrap' feature of Intellij to get the editor window to put line breaks in the content so that horizontal scrolling is no longer required. Here is how the same code from the above example looks after enabling the soft-wraps feature (notice how the whole text is visible now, due to the soft line breaks added by the editor):

    Read this to find how to enable soft wraps.

    +

    Enabling soft wrapping

    While it is common to enforce a maximum line length for code written in some languages (typically, for code made up of statements such as Java), it is also common not to enforce such a limit for source content that contain paragraph-like structures (e.g., Markdown, HTML). In such cases, you'll need to scroll the editor window horizontally to read the content, which can be a frustrating experience. Here's an example (notice how the text continues beyond the visible area of the editor window and you need to use the horizontal scrolling to see the hidden part):

    Luckily, you can use the 'soft wrap' feature of Intellij to get the editor window to put line breaks in the content so that horizontal scrolling is no longer required. Here is how the same code from the above example looks after enabling the soft-wraps feature (notice how the whole text is visible now, due to the soft line breaks added by the editor):

    Read this to find how to enable soft wraps.

    diff --git a/tutorials/intellijUsefulSettings.page-vue-render.js b/tutorials/intellijUsefulSettings.page-vue-render.js index 24d67f01..2564a2b9 100644 --- a/tutorials/intellijUsefulSettings.page-vue-render.js +++ b/tutorials/intellijUsefulSettings.page-vue-render.js @@ -26,6 +26,6 @@ with(this){return _c('p',[_v("While it is common to enforce a maximum line lengt with(this){return _c('p',[_v("Read "),_c('a',{attrs:{"href":"https://www.jetbrains.com/idea/guide/tips/enable-soft-wrap/"}},[_v("this")]),_v(" to find how to enable soft wraps.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/jar.html b/tutorials/jar.html index d9c17850..3a37fed1 100644 --- a/tutorials/jar.html +++ b/tutorials/jar.html @@ -72,7 +72,7 @@ -

    If you are using JavaFX, see the panel below to find what else you need to add to the build.gradle to pack JavaFX libraries into the generated JAR file.


    Creating a JAR file in Intellij - A video by Artur Spirin:

    If your app uses third-party libraries, you are recommended to create a fat JAR file using Gradle instead.

    Although JUnit is a third-party library, you need not package it into a fat JAR file because JUnit is used only in the test code, not in the application code.

    But if you use JavaFX, you need to package the JavaFX libraries into a fat JAR file.


    Resources

    +

    If you are using JavaFX, see the panel below to find what else you need to add to the build.gradle to pack JavaFX libraries into the generated JAR file.


    Creating a JAR file in Intellij - A video by Artur Spirin:

    If your app uses third-party libraries, you are recommended to create a fat JAR file using Gradle instead.

    Although JUnit is a third-party library, you need not package it into a fat JAR file because JUnit is used only in the test code, not in the application code.

    But if you use JavaFX, you need to package the JavaFX libraries into a fat JAR file.


    Resources

    diff --git a/tutorials/jar.page-vue-render.js b/tutorials/jar.page-vue-render.js index 2e542b28..179ff049 100644 --- a/tutorials/jar.page-vue-render.js +++ b/tutorials/jar.page-vue-render.js @@ -44,6 +44,6 @@ with(this){return _c('h2',{attrs:{"id":"resources"}},[_v("Resources"),_c('a',{st with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"https://docs.oracle.com/javase/tutorial/deployment/jar/basicsindex.html"}},[_v("Oracle's tutorial on JAR files")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow"}},[_v("Gradle documentation for the Shadow plugin")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://imperceptiblethoughts.com/shadow/introduction/"}},[_v("Shadow plugin homepage")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFx.html b/tutorials/javaFx.html index cf961ac1..8f783f5b 100644 --- a/tutorials/javaFx.html +++ b/tutorials/javaFx.html @@ -14,7 +14,7 @@
    + diff --git a/tutorials/javaFx.page-vue-render.js b/tutorials/javaFx.page-vue-render.js index c014908d..50e6dec7 100644 --- a/tutorials/javaFx.page-vue-render.js +++ b/tutorials/javaFx.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":"" with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('span',{staticClass:"text-dark"},[_c('strong',[_c('strong',[_v("Guides for SE student projects »")])])]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#guides-for-se-student-projects","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p'),_c('h1',{attrs:{"id":"javafx-tutorial"}},[_v("JavaFX tutorial"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#javafx-tutorial","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/javaFxPart1.html"}},[_v("Part 1: Introduction")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/javaFxPart2.html"}},[_v("Part 2: Creating a GUI for Duke")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/javaFxPart3.html"}},[_v("Part 3: Interacting with the user")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/javaFxPart4.html"}},[_v("Part 4: Using FXML")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"/guides/tutorials/javaFxPart5.html"}},[_v("Part 5: Tweaking the GUI")])])]),_c('p')])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFxPart1.html b/tutorials/javaFxPart1.html index e3395421..a0223f93 100644 --- a/tutorials/javaFxPart1.html +++ b/tutorials/javaFxPart1.html @@ -164,10 +164,10 @@ -

    This approach enables JavaFX to create the Application instance using the newly defined no-argument constructor, while preserving the functionality of the existing constructor.

    Now, run the application (e.g., run ./gradlew run command in the terminal) and you should see something like this:

    Hello World

    The following warning issued by Java runtime can be ignored. This warning appears when you use a later JavaFX version (e.g., 17) with a JDK version that doesn't support the modules feature yet (e.g., Java 11).

    WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...

    Similarly, the warning about the different versions can be ignored as well

    WARNING: Loading FXML document with JavaFX API of version ___ by JavaFX runtime of version ___

    Congratulations! You have created your first GUI application!

    Exercises

    1. We mentioned that Nodes are the fundamental building blocks of JavaFX and used a Label as our root node in the HelloWorld application. +

      This approach enables JavaFX to create the Application instance using the newly defined no-argument constructor, while preserving the functionality of the existing constructor.

      Now, run the application (e.g., run ./gradlew run command in the terminal) and you should see something like this:

      Hello World

      The following warning issued by Java runtime can be ignored. This warning appears when you use a later JavaFX version (e.g., 17) with a JDK version that doesn't support the modules feature yet (e.g., Java 11).

      WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...

      Similarly, the warning about the different versions (if any) can be ignored as well.

      WARNING: Loading FXML document with JavaFX API of version ___ by JavaFX runtime of version ___

      Congratulations! You have created your first GUI application!

      Exercises

      1. We mentioned that Nodes are the fundamental building blocks of JavaFX and used a Label as our root node in the HelloWorld application.
        1. What are some of the other types of Nodes?
        2. How does JavaFX group them?
      2. Nodes can be interacted with like Plain Old Java Objects (POJO).
        1. What properties of a Label can you change programmatically?
        2. Try changing the Label to have a font of Arial at size 50.
      3. You’ve learnt that a Stage can be thought of as a window. -
        1. Can you have more than one Stage in an application?
        2. Try creating another stage and showing it! What happens?

      ToC | What's next? JavaFX tutorial part 2 - Creating a GUI for Duke


      Authors:

      • Initial Version: Jeffry Lum

      +
      1. Can you have more than one Stage in an application?
      2. Try creating another stage and showing it! What happens?

    ToC | What's next? JavaFX tutorial part 2 - Creating a GUI for Duke


    Authors:

    • Initial Version: Jeffry Lum

    diff --git a/tutorials/javaFxPart1.page-vue-render.js b/tutorials/javaFxPart1.page-vue-render.js index 712f035e..21cb4b76 100644 --- a/tutorials/javaFxPart1.page-vue-render.js +++ b/tutorials/javaFxPart1.page-vue-render.js @@ -1,7 +1,7 @@ var pageVueRenderFn = function anonymous( ) { -with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":""}},[_c('navbar',{attrs:{"type":"dark"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"https://se-education.org","title":"SE-EDU"}},[_c('span',[_c('span',{staticClass:"fas fa-chevron-circle-left",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_c('strong',[_v("SE-EDU")])])])])]},proxy:true},{key:"right",fn:function(){return [_c('li',{staticClass:"nav-link"},[_c('form',{staticClass:"navbar-form"},[_c('searchbar',{attrs:{"data":searchData,"placeholder":"Search this site","on-hit":searchCallback,"menu-align-right":""}})],1)])]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/index.html"}},[_c('span',[_c('strong',[_v("Home")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/about.html"}},[_c('span',[_c('strong',[_v("About")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/se-edu/guides"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])])],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_c('p'),_m(1),_v(" "),_m(2),_v(" "),_c('p',[_v("Imagine yourself as a director of a play. First you provision the props that you will feature in your play. These can be hand props for your actors to interact with or even set dressings just to liven up the background. You then decide where to place the props for every scene. With a proper script in hand, you can finally approach a theatre and request for a stage. Thereafter, it’s just a matter of pulling the curtains on your masterpiece.")]),_v(" "),_c('pic',{attrs:{"src":"/guides/tutorials/images/javafx/JavaFxHierarchy.png"}}),_v(" "),_m(3),_v(" "),_c('p',[_v("Well, that's a very high-level view of how JavaFX works. The actual implementation of a Java FX is a bit more (ahem...) \"involved\". This tutorial takes you through the steps of building a typical Java FX application, using a chatbot application called Duke as a running example. Given below is what the end result can look like if you follow this tutorial until the end:")]),_v(" "),_c('video',{attrs:{"oncontextmenu":"return false;","width":"700px","autoplay":"","muted":"","loop":""},domProps:{"muted":true}},[_c('source',{attrs:{"src":"videos/javafx/DynamicStyleDemo.mp4","type":"video/mp4"}})]),_v(" "),_c('p',[_v("Let's get started!")]),_v(" "),_m(4),_v(" "),_m(5),_v(" "),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_v("If you are following this tutorial to learn how to add a GUI to an existing app, we suggest that you follow this tutorial using the above repo first, without mixing tutorial code with your existing project code. Once you are happy with the GUI you've built following this tutorial, you can copy over the GUI code to your existing project, and adapt it to fit that project.")])]),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_c('div',{attrs:{"id":"javafx-gradle"}},[_m(8),_v(" "),_c('pre',[_m(9),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])]),_v(" "),_c('p',[_v("Also note the following:")]),_v(" "),_c('div',{staticClass:"indented-level1"},[_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('span',[_c('span',{staticClass:"glyphicon glyphicon-log-in",attrs:{"aria-hidden":"true"}})]),_v(" Gradle Tutorial → After updating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("build.gradle")]),_v(" file (extract)")])]},proxy:true}])},[_v(" "),_c('div',[_c('p',[_c('strong',[_v("After updating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("build.gradle")]),_v(" file,")])]),_v(" "),_c('ul',[_c('li',[_v("if you are using an IDE: Use the IDE UI to reload dependencies based on the updated file. For example, if using Intellij IDEA, you can click the "),_c('img',{attrs:{"src":"/guides/tutorials/images/gradle/RefreshGradleIcon.png"}}),_v(" icon in the Gradle tool window to reload the file."),_c('br'),_v("\nFor good measure, you can restart the IDE too.")]),_v(" "),_c('li',[_v("if not using an IDE: Run "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".\\gradlew clean build")]),_v(" to rebuild everything based on the updated file.")])])])])],1),_v(" "),_c('p'),_v(" "),_m(10),_v(" "),_m(11),_v(" "),_c('div',{staticClass:"code-block"},[_m(12),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(13),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_m(14),_v(" "),_m(15),_v(" "),_m(16),_v(" "),_c('div',{staticClass:"code-block"},[_m(17),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(18),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_m(19),_v(" "),_c('div',{staticClass:"code-block"},[_m(20),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(21),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_v("JavaFX creates the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Application")]),_v(" instance by calling the no-argument constructor. If there is no other constructor in the class (such as the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Main")]),_v(" we created above), there is no need to provide such a constructor because Java automatically provides a no-argument constructor when there are no other constructors.")]),_v(" "),_c('p',[_v("But if you already have an existing constructor which takes arguments in that class (in which case Java will not provide a no-argument constructor automatically), you need to create an overloaded constructor with no arguments yourself. An example given below:")]),_v(" "),_c('div',{staticClass:"code-block"},[_c('div',{staticClass:"code-block-heading"},[_c('span',[_v("Main.java")])]),_c('div',{staticClass:"code-block-content"},[_c('pre',[_c('code',{pre:true,attrs:{"heading":"Main.java","class":"hljs java"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("//...")]),_v("\n")]),_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("private")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("static")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("final")]),_v(" String DEFAULT_FILE_PATH = "),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"duke/example.txt\"")]),_v(";\n")]),_c('span',[_v("\n")]),_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-class"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("class")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("extends")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Application")]),_v(" ")]),_v("{\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// Existing constructor")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_c('span',{pre:true,attrs:{"class":"hljs-params"}},[_v("(String filePath)")]),_v(" ")]),_v("{\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// ...")]),_v("\n")]),_c('span',[_v(" }\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// Overloaded constructor")])]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_c('span',{pre:true,attrs:{"class":"hljs-params"}},[_v("()")]),_v(" ")]),_v("{")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("this")]),_v("(DEFAULT_FILE_PATH);")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_v("}")]),_v("\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// ...")]),_v("\n")]),_c('span',[_v("}\n")])]),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_c('p',[_v("This approach enables JavaFX to create the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Application")]),_v(" instance using the newly defined no-argument constructor, while preserving the functionality of the existing constructor.")])]),_v(" "),_m(22),_v(" "),_m(23),_v(" "),_c('box',{attrs:{"type":"info","seamless":""}},[_c('p',[_v("The following warning issued by Java runtime can be ignored. This warning appears when you use a later JavaFX version (e.g., 17) with a JDK version that doesn't support the "),_c('em',[_v("modules")]),_v(" feature yet (e.g., Java 11).")]),_v(" "),_c('blockquote',[_c('p',[_v("WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...")])]),_v(" "),_c('p',[_v("Similarly, the warning about the different versions can be ignored as well")]),_v(" "),_c('blockquote',[_c('p',[_v("WARNING: Loading FXML document with JavaFX API of version ___ by JavaFX runtime of version ___")])])]),_v(" "),_c('p',[_v("Congratulations! You have created your first GUI application!")]),_v(" "),_m(24),_v(" "),_m(25),_v(" "),_m(26),_v(" "),_c('hr'),_v(" "),_m(27),_v(" "),_m(28),_c('p')],1),_v(" "),_c('overlay-source',{staticClass:"fixed-header-padding",attrs:{"id":"page-nav","tag-name":"nav","to":"page-nav"}},[_c('div',{staticClass:"nav-component slim-scroll"},[_c('overlay-source',{staticClass:"nav nav-pills flex-column my-0 small no-flex-wrap",attrs:{"id":"mb-page-nav","tag-name":"nav","to":"mb-page-nav"}},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#javafx-tutorial-part-1-getting-started"}},[_v("JavaFX tutorial part 1 – Getting started‎")]),_v(" "),_c('nav',{staticClass:"nav nav-pills flex-column my-0 nested no-flex-wrap"},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#lifecycle-of-a-javafx-application"}},[_v("Lifecycle of a JavaFX application‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-the-project"}},[_v("Setting up the project‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-java-fx"}},[_v("Setting up Java FX‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#writing-your-first-java-fx-program"}},[_v("Writing your first Java FX program‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#exercises"}},[_v("Exercises‎")])])])],1)]),_v(" "),_c('scroll-top-button')],1),_v(" "),_m(29)])} +with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"sticky":""}},[_c('navbar',{attrs:{"type":"dark"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"https://se-education.org","title":"SE-EDU"}},[_c('span',[_c('span',{staticClass:"fas fa-chevron-circle-left",attrs:{"aria-hidden":"true"}}),_v(" "),_c('strong',[_c('strong',[_v("SE-EDU")])])])])]},proxy:true},{key:"right",fn:function(){return [_c('li',{staticClass:"nav-link"},[_c('form',{staticClass:"navbar-form"},[_c('searchbar',{attrs:{"data":searchData,"placeholder":"Search this site","on-hit":searchCallback,"menu-align-right":""}})],1)])]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/index.html"}},[_c('span',[_c('strong',[_v("Home")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/guides/about.html"}},[_c('span',[_c('strong',[_v("About")])])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/se-edu/guides"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])])],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_c('p'),_m(1),_v(" "),_m(2),_v(" "),_c('p',[_v("Imagine yourself as a director of a play. First you provision the props that you will feature in your play. These can be hand props for your actors to interact with or even set dressings just to liven up the background. You then decide where to place the props for every scene. With a proper script in hand, you can finally approach a theatre and request for a stage. Thereafter, it’s just a matter of pulling the curtains on your masterpiece.")]),_v(" "),_c('pic',{attrs:{"src":"/guides/tutorials/images/javafx/JavaFxHierarchy.png"}}),_v(" "),_m(3),_v(" "),_c('p',[_v("Well, that's a very high-level view of how JavaFX works. The actual implementation of a Java FX is a bit more (ahem...) \"involved\". This tutorial takes you through the steps of building a typical Java FX application, using a chatbot application called Duke as a running example. Given below is what the end result can look like if you follow this tutorial until the end:")]),_v(" "),_c('video',{attrs:{"oncontextmenu":"return false;","width":"700px","autoplay":"","muted":"","loop":""},domProps:{"muted":true}},[_c('source',{attrs:{"src":"videos/javafx/DynamicStyleDemo.mp4","type":"video/mp4"}})]),_v(" "),_c('p',[_v("Let's get started!")]),_v(" "),_m(4),_v(" "),_m(5),_v(" "),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_v("If you are following this tutorial to learn how to add a GUI to an existing app, we suggest that you follow this tutorial using the above repo first, without mixing tutorial code with your existing project code. Once you are happy with the GUI you've built following this tutorial, you can copy over the GUI code to your existing project, and adapt it to fit that project.")])]),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_c('div',{attrs:{"id":"javafx-gradle"}},[_m(8),_v(" "),_c('pre',[_m(9),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])]),_v(" "),_c('p',[_v("Also note the following:")]),_v(" "),_c('div',{staticClass:"indented-level1"},[_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('span',[_c('span',{staticClass:"glyphicon glyphicon-log-in",attrs:{"aria-hidden":"true"}})]),_v(" Gradle Tutorial → After updating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("build.gradle")]),_v(" file (extract)")])]},proxy:true}])},[_v(" "),_c('div',[_c('p',[_c('strong',[_v("After updating the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("build.gradle")]),_v(" file,")])]),_v(" "),_c('ul',[_c('li',[_v("if you are using an IDE: Use the IDE UI to reload dependencies based on the updated file. For example, if using Intellij IDEA, you can click the "),_c('img',{attrs:{"src":"/guides/tutorials/images/gradle/RefreshGradleIcon.png"}}),_v(" icon in the Gradle tool window to reload the file."),_c('br'),_v("\nFor good measure, you can restart the IDE too.")]),_v(" "),_c('li',[_v("if not using an IDE: Run "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".\\gradlew clean build")]),_v(" to rebuild everything based on the updated file.")])])])])],1),_v(" "),_c('p'),_v(" "),_m(10),_v(" "),_m(11),_v(" "),_c('div',{staticClass:"code-block"},[_m(12),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(13),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_m(14),_v(" "),_m(15),_v(" "),_m(16),_v(" "),_c('div',{staticClass:"code-block"},[_m(17),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(18),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_m(19),_v(" "),_c('div',{staticClass:"code-block"},[_m(20),_c('div',{staticClass:"code-block-content"},[_c('pre',[_m(21),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_c('box',{attrs:{"type":"tip","seamless":""}},[_c('p',[_v("JavaFX creates the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Application")]),_v(" instance by calling the no-argument constructor. If there is no other constructor in the class (such as the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Main")]),_v(" we created above), there is no need to provide such a constructor because Java automatically provides a no-argument constructor when there are no other constructors.")]),_v(" "),_c('p',[_v("But if you already have an existing constructor which takes arguments in that class (in which case Java will not provide a no-argument constructor automatically), you need to create an overloaded constructor with no arguments yourself. An example given below:")]),_v(" "),_c('div',{staticClass:"code-block"},[_c('div',{staticClass:"code-block-heading"},[_c('span',[_v("Main.java")])]),_c('div',{staticClass:"code-block-content"},[_c('pre',[_c('code',{pre:true,attrs:{"heading":"Main.java","class":"hljs java"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("//...")]),_v("\n")]),_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("private")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("static")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("final")]),_v(" String DEFAULT_FILE_PATH = "),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"duke/example.txt\"")]),_v(";\n")]),_c('span',[_v("\n")]),_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-class"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("class")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("extends")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Application")]),_v(" ")]),_v("{\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// Existing constructor")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_c('span',{pre:true,attrs:{"class":"hljs-params"}},[_v("(String filePath)")]),_v(" ")]),_v("{\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// ...")]),_v("\n")]),_c('span',[_v(" }\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// Overloaded constructor")])]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("public")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("Main")]),_c('span',{pre:true,attrs:{"class":"hljs-params"}},[_v("()")]),_v(" ")]),_v("{")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("this")]),_v("(DEFAULT_FILE_PATH);")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"highlighted"}},[_v("}")]),_v("\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// ...")]),_v("\n")]),_c('span',[_v("}\n")])]),_c('div',{staticClass:"function-btn-container"},[_c('button',{staticClass:"function-btn d-print-none",attrs:{"onclick":"copyCodeBlock(this)"}},[_v("\n "),_c('div',{staticClass:"function-btn-body"},[_v("\n \n"),_c('svg',{attrs:{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","width":"18","height":"18","viewBox":"0 0 18 18","version":"1.1"}},[_v("\n "),_c('g',{attrs:{"id":"surface1"}},[_v("\n "),_c('path',{attrs:{"d":"M 11.273438 0 L 2.546875 0 C 1.746094 0 1.089844 0.613281 1.089844\n 1.363281 L 1.089844 10.910156 L 2.546875 10.910156 L 2.546875 1.363281 L 11.273438\n 1.363281 Z M 13.453125 2.726562 L 5.453125 2.726562 C 4.65625 2.726562 4 3.339844 4\n 4.089844 L 4 13.636719 C 4 14.386719 4.65625 15 5.453125 15 L 13.453125 15 C 14.253906\n 15 14.910156 14.386719 14.910156 13.636719 L 14.910156 4.089844 C 14.910156 3.339844\n 14.253906 2.726562 13.453125 2.726562 Z M 13.453125 13.636719 L 5.453125 13.636719 L\n 5.453125 4.089844 L 13.453125 4.089844 Z M 13.453125 13.636719 "}}),_v("\n ")]),_v("\n")]),_v("\n\n ")]),_v("\n ")])])])])]),_c('p',[_v("This approach enables JavaFX to create the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Application")]),_v(" instance using the newly defined no-argument constructor, while preserving the functionality of the existing constructor.")])]),_v(" "),_m(22),_v(" "),_m(23),_v(" "),_c('box',{attrs:{"type":"info","seamless":""}},[_c('p',[_v("The following warning issued by Java runtime can be ignored. This warning appears when you use a later JavaFX version (e.g., 17) with a JDK version that doesn't support the "),_c('em',[_v("modules")]),_v(" feature yet (e.g., Java 11).")]),_v(" "),_c('blockquote',[_c('p',[_v("WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...")])]),_v(" "),_c('p',[_v("Similarly, the warning about the different versions (if any) can be ignored as well.")]),_v(" "),_c('blockquote',[_c('p',[_v("WARNING: Loading FXML document with JavaFX API of version ___ by JavaFX runtime of version ___")])])]),_v(" "),_c('p',[_v("Congratulations! You have created your first GUI application!")]),_v(" "),_m(24),_v(" "),_m(25),_v(" "),_m(26),_v(" "),_c('hr'),_v(" "),_m(27),_v(" "),_m(28),_c('p')],1),_v(" "),_c('overlay-source',{staticClass:"fixed-header-padding",attrs:{"id":"page-nav","tag-name":"nav","to":"page-nav"}},[_c('div',{staticClass:"nav-component slim-scroll"},[_c('overlay-source',{staticClass:"nav nav-pills flex-column my-0 small no-flex-wrap",attrs:{"id":"mb-page-nav","tag-name":"nav","to":"mb-page-nav"}},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#javafx-tutorial-part-1-getting-started"}},[_v("JavaFX tutorial part 1 – Getting started‎")]),_v(" "),_c('nav',{staticClass:"nav nav-pills flex-column my-0 nested no-flex-wrap"},[_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#lifecycle-of-a-javafx-application"}},[_v("Lifecycle of a JavaFX application‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-the-project"}},[_v("Setting up the project‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#setting-up-java-fx"}},[_v("Setting up Java FX‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#writing-your-first-java-fx-program"}},[_v("Writing your first Java FX program‎")]),_v(" "),_c('a',{pre:true,attrs:{"class":"nav-link py-1","href":"#exercises"}},[_v("Exercises‎")])])])],1)]),_v(" "),_c('scroll-top-button')],1),_v(" "),_m(29)])} }; var pageVueStaticRenderFns = [function anonymous( ) { @@ -92,6 +92,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: Jeffry Lum")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFxPart2.html b/tutorials/javaFxPart2.html index 18742451..4e8692f7 100644 --- a/tutorials/javaFxPart2.html +++ b/tutorials/javaFxPart2.html @@ -229,7 +229,7 @@

    Run the application again. It should now look like this:

    Exercises

    1. In the tutorial, we used an AnchorPane to achieve the desired layout.
      1. Can you find other ways to obtain a similar layout?
      2. What are the advantages and disadvantages of your layout?
    2. Try interacting with the application -
      1. What happens when you press the Enter key or click the Send button?
      2. Why?

    Previous | ToC | What's next? JavaFX tutorial part 3 - Interacting with the user


    Authors:

    • Initial Version: Jeffry Lum

    +
    1. What happens when you press the Enter key or click the Send button?
    2. Why?

    Previous | ToC | What's next? JavaFX tutorial part 3 - Interacting with the user


    Authors:

    • Initial Version: Jeffry Lum

    diff --git a/tutorials/javaFxPart2.page-vue-render.js b/tutorials/javaFxPart2.page-vue-render.js index 4c21b488..218bb829 100644 --- a/tutorials/javaFxPart2.page-vue-render.js +++ b/tutorials/javaFxPart2.page-vue-render.js @@ -110,6 +110,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: Jeffry Lum")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFxPart3.html b/tutorials/javaFxPart3.html index d1105216..d8747517 100644 --- a/tutorials/javaFxPart3.html +++ b/tutorials/javaFxPart3.html @@ -265,7 +265,7 @@

    Run the application and play around with it.

    Congratulations! You have successfully implemented a fully functional GUI for Duke! But there's more. Continue to the next section to find out.

    Exercises

    1. While the GUI looks similar to the mockup, there are still parts that need to be refined. Try your hand at some of these tasks:
      • Add padding between each DialogBox
      • Add padding between each ImageView and its Label
      • Clip the ImageView into a circle
      • Add background color to each DialogBox
    2. After attempting the changes, reflect critically on the following: -
      • What was the development workflow like?
      • Is the code base well-organized?

    Previous | ToC | What's next? JavaFX tutorial part 4 - Using FXML


    Authors:

    • Initial Version: Jeffry Lum

    +
    • What was the development workflow like?
    • Is the code base well-organized?

    Previous | ToC | What's next? JavaFX tutorial part 4 - Using FXML


    Authors:

    • Initial Version: Jeffry Lum

    diff --git a/tutorials/javaFxPart3.page-vue-render.js b/tutorials/javaFxPart3.page-vue-render.js index b3c8fc23..6b7204d9 100644 --- a/tutorials/javaFxPart3.page-vue-render.js +++ b/tutorials/javaFxPart3.page-vue-render.js @@ -116,6 +116,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: Jeffry Lum")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFxPart4.html b/tutorials/javaFxPart4.html index ea553d2e..b457fcc3 100644 --- a/tutorials/javaFxPart4.html +++ b/tutorials/javaFxPart4.html @@ -353,7 +353,7 @@ -

    More about fx:root on the documentation Introduction to FXML | JavaFX 2.2.

    Exercises

    1. Convert MainWindow to use the fx:root construct.
    2. Extend MainWindow to have a Stage as a root Node.
    3. Customize the appearance of the application further with CSS.

    Previous | ToC | What's next? JavaFX tutorial part 5 - Tweaking the GUI


    Authors:

    • Initial Version: Jeffry Lum

    +

    More about fx:root on the documentation Introduction to FXML | JavaFX 2.2.

    Exercises

    1. Convert MainWindow to use the fx:root construct.
    2. Extend MainWindow to have a Stage as a root Node.
    3. Customize the appearance of the application further with CSS.

    Previous | ToC | What's next? JavaFX tutorial part 5 - Tweaking the GUI


    Authors:

    • Initial Version: Jeffry Lum

    diff --git a/tutorials/javaFxPart4.page-vue-render.js b/tutorials/javaFxPart4.page-vue-render.js index 215ccc93..9b11ab41 100644 --- a/tutorials/javaFxPart4.page-vue-render.js +++ b/tutorials/javaFxPart4.page-vue-render.js @@ -122,6 +122,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: Jeffry Lum")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaFxPart5.html b/tutorials/javaFxPart5.html index f6125aa6..b24decae 100644 --- a/tutorials/javaFxPart5.html +++ b/tutorials/javaFxPart5.html @@ -1045,7 +1045,7 @@ -

    Image Opacity Demo

    Other things to consider

    Here are other things you can do with your app to make it more personalized:

    Previous | ToC


    Authors:

    • Initial Version: Debbie Hii (@flexibo)

    +

    Image Opacity Demo

    Other things to consider

    Here are other things you can do with your app to make it more personalized:

    Previous | ToC


    Authors:

    • Initial Version: Debbie Hii (@flexibo)

    diff --git a/tutorials/javaFxPart5.page-vue-render.js b/tutorials/javaFxPart5.page-vue-render.js index f7f2bf19..02d4ac29 100644 --- a/tutorials/javaFxPart5.page-vue-render.js +++ b/tutorials/javaFxPart5.page-vue-render.js @@ -548,6 +548,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: Debbie Hii (@flexibo)")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/javaInstallationMac.html b/tutorials/javaInstallationMac.html index f3f90992..e68f08bf 100644 --- a/tutorials/javaInstallationMac.html +++ b/tutorials/javaInstallationMac.html @@ -185,7 +185,7 @@ -

    Authors:

    +

    Authors:

    diff --git a/tutorials/javaInstallationMac.page-vue-render.js b/tutorials/javaInstallationMac.page-vue-render.js index 0375a047..ebbcc25b 100644 --- a/tutorials/javaInstallationMac.page-vue-render.js +++ b/tutorials/javaInstallationMac.page-vue-render.js @@ -41,6 +41,6 @@ with(this){return _c('code',{pre:true,attrs:{"class":"hljs bash"}},[_c('span',[_ with(this){return _c('code',{pre:true,attrs:{"class":"hljs bash"}},[_c('span',[_v("java -version\n")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/jekyll.html b/tutorials/jekyll.html index eac62433..625cba7d 100644 --- a/tutorials/jekyll.html +++ b/tutorials/jekyll.html @@ -17,7 +17,7 @@

    Guides for SE student projects »

    Using Jekyll for project documentation

    Jekyll is a popular tool for generating static websites from markdown-like text.

    Given below are some information useful for when you want to update documentation in a project that uses Jekyll.

    Setting up GitHub Pages for Jekyll

    As GitHub has native support for Jekyll, it can convert your documentation into HTML and deploy it on the github.io URL of your project.

    Do the following to set up the GitHub Pages website of your project:

    1. Go to your repo's settings tab.
    2. Click   Pages  on the menu on the left edge of page.
    3. Set the Source as:  Deploy from a branch branch master branch and /docs folder (assuming project documentation is in that folder) and click  Save .

    The project website will be available at https://{your_org}.github.io/{your_repo} the next time the master branch is updated. Example: https://myorg.github.io/myrepo

    Updating documents

    Jekyll uses kramdown (a superset of Markdown) for writing content. You can use Intellij (or any other text editor) to update the relevant .md files.

    Recommendation: Limit your content to Markdown and GFMD syntax only i.e., avoid kramdown-specific syntax that are not compatible with Markdown/GFMD

    Recommendation: Enable soft-wrapping in your code editor for *.md files. For example, as explained in Intellij IDEA: Useful settings guide.

    • Previewing changes locally: There are several ways to preview changes locally.
      • Option 1 -- Intellij preview: Intellij supports previewing Markdown files, as explained here. While the preview shown by Intellij is somewhat rudimentary, it is good enough for most cases.
      • Option 2 -- Run Jekyll locally: You can set up Jekyll locally and run it to see the exact way the update affects the final outcome.
    • Previewing changes on GitHub:
      • Option 1 -- GitHub preview: You can see a basic preview of the page by navigating to the corresponding .md source file in GitHub.
      • Option 2 -- Use Netlify PR preview: You can set up Netlify to show previews of PRs (to learn how, read the Using Netlify guide). This method shows a preview of the exact way the update affects the final outcome.

    Site-wide settings

    • Typically, the _config.yml file specifies project-specific site-wide settings.
      -An example is the title property, which defines the title of your site, usually the name of your project.

    • The files in docs/_include and docs/_layouts control the template of the pages; the files in docs/_sass control the style of the pages.

      Caution: Modifying these files requires some knowledge and experience with Jekyll. You should only modify them (at your own risk) if you need greater control over the site’s layout.

    +An example is the title property, which defines the title of your site, usually the name of your project.

  • The files in docs/_include and docs/_layouts control the template of the pages; the files in docs/_sass control the style of the pages.

    Caution: Modifying these files requires some knowledge and experience with Jekyll. You should only modify them (at your own risk) if you need greater control over the site’s layout.

  • diff --git a/tutorials/jekyll.page-vue-render.js b/tutorials/jekyll.page-vue-render.js index 66ba6c90..03517897 100644 --- a/tutorials/jekyll.page-vue-render.js +++ b/tutorials/jekyll.page-vue-render.js @@ -47,6 +47,6 @@ with(this){return _c('li',[_c('p',[_v("Typically, the "),_c('code',{pre:true,att with(this){return _c('p',[_v("The files in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("docs/_include")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("docs/_layouts")]),_v(" control the template of the pages; the files in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("docs/_sass")]),_v(" control the style of the pages.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/junit.html b/tutorials/junit.html index 77c0e259..0d3bc4c3 100644 --- a/tutorials/junit.html +++ b/tutorials/junit.html @@ -100,7 +100,7 @@ -

    3. Run tests, either using the Intellij UI (preferred -- this makes debugging failed test cases easier) or using Gradle itself, as explained in the section below.

    Running tests

    In Intellij IDEA:

    • To run a specific JUnit test class (e.g., src/test/java/seedu/DukeTest.java), right-click on the test class, and choose Run {classname}.

    If the above doesn't work, you may want to go to File > Settings and change theRun tests using: setting to Intellij IDEA (instead of Gradle), as shown below:

    Expand to see screenshot ...

    change Intellij settings to not use Gradle


    • To run all tests in a folder (e.g., src/test/java folder), right-click on the folder, and choose Run Tests in '...'.
    • Other supported IDEs (e.g., Eclipse, NetBeans, VS Code, etc.) have similar mechanisms.

    Using Gradle::

    • To run all tests in the project, run the Gradle task test (more info on running Gradle tasks)
    • [If using Intellij UI to run the test task] The location of the test task in the Gradle task hierarchy is Tasks -> verification -> test (see screenshot below).

    Other ways:

    Writing useful JUnit tests

    After you are able to run JUnit tests successfully using a dummy test class such as the above, you can add more tests and test classes as necessary.

    To learn how to write useful JUnit test cases, refer this section of our SE book. For a quick overview of more advance JUnit features, refer this section.

    Resources

    +

    3. Run tests, either using the Intellij UI (preferred -- this makes debugging failed test cases easier) or using Gradle itself, as explained in the section below.

    Running tests

    In Intellij IDEA:

    • To run a specific JUnit test class (e.g., src/test/java/seedu/DukeTest.java), right-click on the test class, and choose Run {classname}.

    If the above doesn't work, you may want to go to File > Settings and change theRun tests using: setting to Intellij IDEA (instead of Gradle), as shown below:

    Expand to see screenshot ...

    change Intellij settings to not use Gradle


    • To run all tests in a folder (e.g., src/test/java folder), right-click on the folder, and choose Run Tests in '...'.
    • Other supported IDEs (e.g., Eclipse, NetBeans, VS Code, etc.) have similar mechanisms.

    Using Gradle::

    • To run all tests in the project, run the Gradle task test (more info on running Gradle tasks)
    • [If using Intellij UI to run the test task] The location of the test task in the Gradle task hierarchy is Tasks -> verification -> test (see screenshot below).

    Other ways:

    Writing useful JUnit tests

    After you are able to run JUnit tests successfully using a dummy test class such as the above, you can add more tests and test classes as necessary.

    To learn how to write useful JUnit test cases, refer this section of our SE book. For a quick overview of more advance JUnit features, refer this section.

    Resources

    diff --git a/tutorials/junit.page-vue-render.js b/tutorials/junit.page-vue-render.js index 94c1e453..d96f569f 100644 --- a/tutorials/junit.page-vue-render.js +++ b/tutorials/junit.page-vue-render.js @@ -95,6 +95,6 @@ with(this){return _c('h2',{attrs:{"id":"resources"}},[_v("Resources"),_c('a',{st with(this){return _c('ul',[_c('li',[_c('a',{attrs:{"href":"https://junit.org/junit5/docs/current/user-guide/"}},[_v("JUnit 5 User Guide")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docs.gradle.org/current/userguide/java_testing.html#using_junit5"}},[_v("Gradle documentation for JUnit")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/markbind-forked-sites.html b/tutorials/markbind-forked-sites.html index 53995975..cee491c8 100644 --- a/tutorials/markbind-forked-sites.html +++ b/tutorials/markbind-forked-sites.html @@ -42,7 +42,7 @@

    Updating documents

    MarkBind is a superset of Markdown. Refer the MarkBind UG: Authoring Contents for more details on the syntax. Given below is the recommended workflow for any non-trivial changes to this docs site.

    1. Install MarkBind (as described in the section above), if you haven't done so already.
    2. Open a terminal and navigate to the [project root]/docs folder.
    3. Run the npm run serve command. That will open the generated website in your default browser in a live preview mode.
    4. In the browser, navigate to the page you want to preview.
    5. Edit the source files (usually, *.md files). When you save the file, the live preview will update to reflect the new contents (after a few seconds).

    While live preview can pick up most changes, it may not be able to pick up certain changes (e.g., changes to files in the _markbind folder or changes to nunjucks macros). Furthermore, some syntax errors in your code can cause the live preview to crash. In those cases, just stop the server (e.g., Ctrl+C on Windows) and start it again.

    Recommendation: Enable soft-wrapping in your code editor for *.md files. For example, as explained in Intellij IDEA: Useful settings guide.

    Generating a Table of Content for a page: As MarkBind pages automatically generate a page navigation menu (which appears on the top right edge of the page), there is no need to manually insert a ToC into a page.
    -Furthermore, when saving the page as a PDF, you can make the page navigation menu appear as a ToC in the generated PDF, by inserting <page-nav-print /> in the page where you want the ToC to appear.

    Working with UML diagrams

    MarkBind has built-in support for PlantUML diagrams. See the this page of the MarkBind User Guide to find how to use PlantUML with MarkBind.

    Also see se-edu/guides Using PlantUML for useful info on using PlantUML in a project such as AB3.

    +Furthermore, when saving the page as a PDF, you can make the page navigation menu appear as a ToC in the generated PDF, by inserting <page-nav-print /> in the page where you want the ToC to appear.

    Working with UML diagrams

    MarkBind has built-in support for PlantUML diagrams. See the this page of the MarkBind User Guide to find how to use PlantUML with MarkBind.

    Also see se-edu/guides Using PlantUML for useful info on using PlantUML in a project such as AB3.

    diff --git a/tutorials/markbind-forked-sites.page-vue-render.js b/tutorials/markbind-forked-sites.page-vue-render.js index 5cadfcfb..7bb18661 100644 --- a/tutorials/markbind-forked-sites.page-vue-render.js +++ b/tutorials/markbind-forked-sites.page-vue-render.js @@ -86,6 +86,6 @@ with(this){return _c('p',[_c('strong',[_v("MarkBind has built-in support for Pla with(this){return _c('p',[_v("Also see "),_c('a',{attrs:{"href":"https://se-education.org/guides/tutorials/plantUml.html"}},[_c('em',[_v("se-edu/guides "),_c('strong',[_v("Using PlantUML")])])]),_v(" for useful info on using PlantUML in a project such as AB3.")])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/markbind.html b/tutorials/markbind.html index f0adb729..923cb4ec 100644 --- a/tutorials/markbind.html +++ b/tutorials/markbind.html @@ -14,7 +14,7 @@

    Guides for SE student projects »

    Using MarkBind for project documentation

    If you are working with a forked repo that is using MarkBind already, refer to this guide instead.

    MarkBind is a tool for generating static websites from markdown-like text, particularly suitable for text-heavy websites such as software project documentation.

    Given below are some information useful for when you want to update documentation in a project that uses MarkBind.

    Installation

    Updating documents

    MarkBind is a superset of Markdown. Refer the MarkBind user guide for more details.

    First, start the live preview: Unless it is a trivial change, you would want to see how your change to the documentation source files will reflect in the generated website. You can use the MarkBind live preview mode to preview the generated website as you update the source file. To start the live preview mode,

    1. Open a command prompt.
    2. Navigate to the the documentation root (in most projects, the documentation root is [project root]/docs -- if you are not sure, look for the folder containing the site.json file).
    3. Run the markbind serve command. That will open the generated website in your default browser.
    4. In the browser, navigate to the page you want to modify.

    Next, edit the files you want:

    1. Edit the source files (usually, .md files).
    2. When you save the file, the live preview will update to reflect the new contents (after a few seconds).

    While live preview can pick up most changes, it may not be able to pick up certain changes (e.g., changes to files in the _markbind folder or changes to nunjucks macros). Furthermore, some syntax errors in your code can cause the live preview to crash. In those cases, just stop the server (Ctrl+C on Windows) and start it again.

    Automating PR previews, deployments

    Project admins can,

    • set up Netlify to give a preview of how a PR can affect the generated website. More info here.
    • set up Travis to automatically generate and deploy the project website when new code is pushed. More info here

    +

    Guides for SE student projects »

    Using MarkBind for project documentation

    If you are working with a forked repo that is using MarkBind already, refer to this guide instead.

    MarkBind is a tool for generating static websites from markdown-like text, particularly suitable for text-heavy websites such as software project documentation.

    Given below are some information useful for when you want to update documentation in a project that uses MarkBind.

    Installation

    Updating documents

    MarkBind is a superset of Markdown. Refer the MarkBind user guide for more details.

    First, start the live preview: Unless it is a trivial change, you would want to see how your change to the documentation source files will reflect in the generated website. You can use the MarkBind live preview mode to preview the generated website as you update the source file. To start the live preview mode,

    1. Open a command prompt.
    2. Navigate to the the documentation root (in most projects, the documentation root is [project root]/docs -- if you are not sure, look for the folder containing the site.json file).
    3. Run the markbind serve command. That will open the generated website in your default browser.
    4. In the browser, navigate to the page you want to modify.

    Next, edit the files you want:

    1. Edit the source files (usually, .md files).
    2. When you save the file, the live preview will update to reflect the new contents (after a few seconds).

    While live preview can pick up most changes, it may not be able to pick up certain changes (e.g., changes to files in the _markbind folder or changes to nunjucks macros). Furthermore, some syntax errors in your code can cause the live preview to crash. In those cases, just stop the server (Ctrl+C on Windows) and start it again.

    Automating PR previews, deployments

    Project admins can,

    • set up Netlify to give a preview of how a PR can affect the generated website. More info here.
    • set up Travis to automatically generate and deploy the project website when new code is pushed. More info here

    diff --git a/tutorials/markbind.page-vue-render.js b/tutorials/markbind.page-vue-render.js index 85b6b363..8ffb61db 100644 --- a/tutorials/markbind.page-vue-render.js +++ b/tutorials/markbind.page-vue-render.js @@ -41,6 +41,6 @@ with(this){return _c('h2',{attrs:{"id":"automating-pr-previews-deployments"}},[_ with(this){return _c('ul',[_c('li',[_v("set up Netlify to give a preview of how a PR can affect the generated website. More info "),_c('a',{attrs:{"href":"https://markbind.org/userGuide/deployingTheSite.html#deploying-to-netlify"}},[_v("here")]),_v(".")]),_v(" "),_c('li',[_v("set up Travis to automatically generate and deploy the project website when new code is pushed. More info "),_c('a',{attrs:{"href":"https://markbind.org/userGuide/deployingTheSite.html#deploying-to-github-pages"}},[_v("here")])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/netlify.html b/tutorials/netlify.html index f5e7b22d..da811b36 100644 --- a/tutorials/netlify.html +++ b/tutorials/netlify.html @@ -16,7 +16,7 @@ Search this site

    Guides for SE student projects »

    Using Netlify

    Netlify is an automated hosting platform for deploying websites. Its deploy previews feature is particularly useful for .

    The sections below explains how to use Netlify in a project.

    Caution: Netlify allows only 300 free build minutes per month. They use an unsavory practice of letting you exceed the limit silently and then sending you an invoice for the extra use. You will not be able to use Netlify again unless you pay (or get them to cancel the charge). Therefore, we caution you to use Netlify (if at all) during times you update documentation and only if you want to use Netlify Deploy Previews to help review such PRs.

    Setting up

    1. Go to https://www.netlify.com/ and click Sign Up. Next, click GITHUB SIGN IN, enter your GitHub account details and authorize netlify.

    2. After logging in, click New site from Git.

    3. You will then be brought to the setup page. Click GitHub to link your repository to Netlify.

      • Depending on whether you are the owner of the repository, you can either grant or request access to Netlify so that it can access your repository and build your documentation.
        Grant or request access
      • After granting or requesting access to your repository, click Authorize netlify.
    4. Pick your repository from the list.

    5. Fill out the details as follows and then click Deploy site.

      • Branch to deploy: select master branch
      • If using Jekyll for project documentation:
        • Build command: cd docs && bundle install && bundle exec jekyll build
        • Publish directory: docs/_site
      • If using MarkBind for project documentation: -
        • Build Command: cd docs && npm i markbind-cli -g && markbind build --baseUrl
        • Publish directory: docs/_site

      For both Jekyll and MarkBind, omit the cd docs && and docs/ from the build command and the publish directory respectively if the documentation is in the root (i.e., not inside the docs folder).

    6. Once Netlify has completed building your project, you can now:

      • View your main branch’s deployed documentation on the site name given by Netlify (customizable as shown below).
        Temporary site name
      • Preview the updated documentation whenever a pull request is made by clicking the Details hyperlink next to the Netlify test status.
        Netlify details link

    Changing the site name

    If you don’t like the site name given by Netlify, you can change it as follows:

    1. Click on Settings.

    2. Then click Change site name and fill in your desired site name.
      Change site name

    +
    • Build Command: cd docs && npm i markbind-cli -g && markbind build --baseUrl
    • Publish directory: docs/_site

    For both Jekyll and MarkBind, omit the cd docs && and docs/ from the build command and the publish directory respectively if the documentation is in the root (i.e., not inside the docs folder).

  • Once Netlify has completed building your project, you can now:

    • View your main branch’s deployed documentation on the site name given by Netlify (customizable as shown below).
      Temporary site name
    • Preview the updated documentation whenever a pull request is made by clicking the Details hyperlink next to the Netlify test status.
      Netlify details link
  • Changing the site name

    If you don’t like the site name given by Netlify, you can change it as follows:

    1. Click on Settings.

    2. Then click Change site name and fill in your desired site name.
      Change site name

    diff --git a/tutorials/netlify.page-vue-render.js b/tutorials/netlify.page-vue-render.js index 725fafe8..4f2d7215 100644 --- a/tutorials/netlify.page-vue-render.js +++ b/tutorials/netlify.page-vue-render.js @@ -47,6 +47,6 @@ with(this){return _c('h2',{attrs:{"id":"changing-the-site-name"}},[_v("Changing with(this){return _c('ol',[_c('li',[_c('p',[_v("Click on "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Settings")]),_v(".")])]),_v(" "),_c('li',[_c('p',[_v("Then click "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Change site name")]),_v(" and fill in your desired site name."),_c('br'),_v(" "),_c('a',{attrs:{"href":"/guides/tutorials/images/netlify/change_site_name.png","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"/guides/tutorials/images/netlify/change_site_name.png","alt":"Change site name"}})])])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/plantUml.html b/tutorials/plantUml.html index 83dc96d1..df1eb564 100644 --- a/tutorials/plantUml.html +++ b/tutorials/plantUml.html @@ -204,7 +204,7 @@ -

    Explicitly define all symbols to avoid any potential layout mishaps.

    +

    Explicitly define all symbols to avoid any potential layout mishaps.

    diff --git a/tutorials/plantUml.page-vue-render.js b/tutorials/plantUml.page-vue-render.js index 79672aca..f16eeee3 100644 --- a/tutorials/plantUml.page-vue-render.js +++ b/tutorials/plantUml.page-vue-render.js @@ -113,6 +113,6 @@ with(this){return _c('td',[_c('img',{attrs:{"src":"/guides/tutorials/images/plan with(this){return _c('td',[_c('img',{attrs:{"src":"/guides/tutorials/images/plantuml/PackagesAndConsistency.png"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/savingPdf.html b/tutorials/savingPdf.html index c8e5e416..fb75e43c 100644 --- a/tutorials/savingPdf.html +++ b/tutorials/savingPdf.html @@ -31,7 +31,7 @@ -

    +

    diff --git a/tutorials/savingPdf.page-vue-render.js b/tutorials/savingPdf.page-vue-render.js index 2b03751b..390e831c 100644 --- a/tutorials/savingPdf.page-vue-render.js +++ b/tutorials/savingPdf.page-vue-render.js @@ -17,6 +17,6 @@ with(this){return _c('p',[_c('strong',[_v("Use Chrome ("),_c('mark',[_c('span',{ with(this){return _c('ol',[_c('li',[_c('p',[_v("Go to your generated documentation site on GitHub using Chrome.")])]),_v(" "),_c('li',[_c('p',[_v("Within Chrome, click on the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Print")]),_v(" option in Chrome’s menu.")])]),_v(" "),_c('li',[_c('p',[_v("Set the destination to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Save as PDF")]),_v(", then click "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Save")]),_v(" to save a copy of the file in PDF format."),_c('br'),_v(" "),_c('mark',[_v("For best results, use the settings indicated in the screenshot below.")])]),_v(" "),_c('p',[_c('a',{attrs:{"href":"/guides/tutorials/images/chrome_save_as_pdf.png","target":"_self"}},[_c('img',{staticClass:"img-fluid",attrs:{"src":"/guides/tutorials/images/chrome_save_as_pdf.png","alt":"Saving documentation as PDF files in Chrome"}})])])])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/sourcetree.html b/tutorials/sourcetree.html index 2feb6dff..22d223e9 100644 --- a/tutorials/sourcetree.html +++ b/tutorials/sourcetree.html @@ -22,7 +22,7 @@
    • Hosting Service: GitHub
    • Preferred Protocol: HTTPS
    • Authentication: Personal Access Token (different from option 1 above)
  • Click on the Refresh Personal Access Token button. When prompted, enter your usual GitHub username but give the PAT (the one you created in step 1) instead of the regular password.
  • Now, your Sourcetree should be able to push code to a GitHub repo that you have write permission to.
  • Option 3:

    1. Open the Windows Credential Manager.
    2. For each credential related to GitHub (if the name mentions GitHub) in Web Credentials or Windows Credentials categories,
      (a) edit it and replace the password field with a GitHub PAT.
      (b) If the above didn't work, delete those credential altogether and try Option 1 or 2 again.

    On a Mac

    • Option 1: Try this YouTube guide from Nick Graham:

    Caching GitHub credentials

    If you are prompted to enter GitHub credentials everytime you connect to GitHub using Sourcetree, you can cache GitHub credentials by following the guide given here (recommended: use the Git Credentials Manager option, not the GitHub CLI option).

    +It gives two methods. Recommended to try method 2 first.

    Caching GitHub credentials

    If you are prompted to enter GitHub credentials everytime you connect to GitHub using Sourcetree, you can cache GitHub credentials by following the guide given here (recommended: use the Git Credentials Manager option, not the GitHub CLI option).

    diff --git a/tutorials/sourcetree.page-vue-render.js b/tutorials/sourcetree.page-vue-render.js index d9218a3c..7398b3e3 100644 --- a/tutorials/sourcetree.page-vue-render.js +++ b/tutorials/sourcetree.page-vue-render.js @@ -62,6 +62,6 @@ with(this){return _c('ul',[_c('li',[_c('p',[_c('strong',[_v("Option 1:")]),_v(" with(this){return _c('ul',[_c('li',[_c('strong',[_v("Option 2:")]),_v(" If the above doesn't work, try this guide (from Medium): "),_c('a',{attrs:{"href":"https://medium.com/geekculture/using-personal-access-token-in-sourcetree-to-connect-to-github-3702a29554d3"}},[_v("Using Sourcetree to connect to GitHub without password")]),_v("."),_c('br'),_v("\nIt gives two methods. Recommended to try method 2 first.")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/textUiTesting.html b/tutorials/textUiTesting.html index 7576c90d..86784251 100644 --- a/tutorials/textUiTesting.html +++ b/tutorials/textUiTesting.html @@ -102,7 +102,7 @@

  • Update the javac and java commands in the script to match the name/location of your main class.
    -If you are using packages, the two commands need to take the packages into account too.

  • Add an input.txt containing the input commands.

  • Add an EXPECTED.txt to the same folder, containing the expected output.

  • Run the .bat/.sh file to execute the test.

    • If the actual output matches the EXPECTED.TXT, the test passes.
    • If the actual output differs from the EXPECTED.TXT, the script will report a failure.
  • Updating tests as the program evolves

    The purpose of testing as explained in the previous section is to confirm there are no . However, we often update the behavior of the program intentionally e.g., enhance an existing feature. Let's look at how to update our test set up in those cases.

    Option 1: This is the ideal but more tedious approach.

    1. Determine how the expected behavior should change due to your update to the code.
    2. Update the EXPECTED.TXT file accordingly.
    3. Run the test to confirm the actual behavior is same as the updated expected behavior.

    Option 2: This is a more practical shortcut.

    1. Run the test as per normal after updating the code. The test will fail because the new program behavior is different from the one given in the EXPECTED.TXT.
    2. Use a diff tool to compare the ACTUAL.TXT against the EXPECTED.TXT.
      Intellij IDEA can compare two files. There are stand-alone tools for comparing files too e.g., WinDiff, WinMerge
    3. Confirm the differences indicate the behavior has changed as you intended. If the differences are not as intended, your code is buggy; fix the code and repeat from step 1.
    4. Copy over the content of the ACTUAL.TXT to EXPECTED.TXT i.e., we accept that the current actual behavior should be the new expected behavior. Rerun the test to confirm that it passes this time.

    Troubleshooting

    • Problem: The ACTUAL.TXT and EXPECTED.TXT looks exactly the same but the test fails.
      Explanation: The likely cause that the line endings are different (not visible to the naked eye) because the two files were created in two different operating systems.
      Solution: You can use the dos2unix utility (available in git-bash and *nix operating systems) to convert a file to Unix format.

    Authors:

    • Initial Version: based on se-edu/addressbook-level2, adapted by Jeffry Lum

    +If you are using packages, the two commands need to take the packages into account too.

  • Add an input.txt containing the input commands.

  • Add an EXPECTED.txt to the same folder, containing the expected output.

  • Run the .bat/.sh file to execute the test.

    • If the actual output matches the EXPECTED.TXT, the test passes.
    • If the actual output differs from the EXPECTED.TXT, the script will report a failure.
  • Updating tests as the program evolves

    The purpose of testing as explained in the previous section is to confirm there are no . However, we often update the behavior of the program intentionally e.g., enhance an existing feature. Let's look at how to update our test set up in those cases.

    Option 1: This is the ideal but more tedious approach.

    1. Determine how the expected behavior should change due to your update to the code.
    2. Update the EXPECTED.TXT file accordingly.
    3. Run the test to confirm the actual behavior is same as the updated expected behavior.

    Option 2: This is a more practical shortcut.

    1. Run the test as per normal after updating the code. The test will fail because the new program behavior is different from the one given in the EXPECTED.TXT.
    2. Use a diff tool to compare the ACTUAL.TXT against the EXPECTED.TXT.
      Intellij IDEA can compare two files. There are stand-alone tools for comparing files too e.g., WinDiff, WinMerge
    3. Confirm the differences indicate the behavior has changed as you intended. If the differences are not as intended, your code is buggy; fix the code and repeat from step 1.
    4. Copy over the content of the ACTUAL.TXT to EXPECTED.TXT i.e., we accept that the current actual behavior should be the new expected behavior. Rerun the test to confirm that it passes this time.

    Troubleshooting

    • Problem: The ACTUAL.TXT and EXPECTED.TXT looks exactly the same but the test fails.
      Explanation: The likely cause that the line endings are different (not visible to the naked eye) because the two files were created in two different operating systems.
      Solution: You can use the dos2unix utility (available in git-bash and *nix operating systems) to convert a file to Unix format.

    Authors:

    • Initial Version: based on se-edu/addressbook-level2, adapted by Jeffry Lum

    diff --git a/tutorials/textUiTesting.page-vue-render.js b/tutorials/textUiTesting.page-vue-render.js index 1a893a82..d075f9d6 100644 --- a/tutorials/textUiTesting.page-vue-render.js +++ b/tutorials/textUiTesting.page-vue-render.js @@ -62,6 +62,6 @@ with(this){return _c('p',[_c('strong',[_v("Authors:")])])} with(this){return _c('ul',[_c('li',[_v("Initial Version: based on se-edu/addressbook-level2, adapted by Jeffry Lum")])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file diff --git a/tutorials/vscode.html b/tutorials/vscode.html index 3b0d6ae8..eba269d7 100644 --- a/tutorials/vscode.html +++ b/tutorials/vscode.html @@ -14,7 +14,7 @@

    Guides for SE student projects »

    VS Code - Community Resources

    This page contains 'community resources' contributed by students.

    Coming soon ...

    +

    Guides for SE student projects »

    VS Code - Community Resources

    This page contains 'community resources' contributed by students.

    Coming soon ...

    diff --git a/tutorials/vscode.page-vue-render.js b/tutorials/vscode.page-vue-render.js index 71aadcb5..b327f5b4 100644 --- a/tutorials/vscode.page-vue-render.js +++ b/tutorials/vscode.page-vue-render.js @@ -11,6 +11,6 @@ with(this){return _c('h1',{attrs:{"id":"guides-for-se-student-projects"}},[_c('s with(this){return _c('h1',{attrs:{"id":"vs-code-community-resources"}},[_v("VS Code - Community Resources"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vs-code-community-resources","onclick":"event.stopPropagation()"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Mon, 2 Sept 2024, 23:18:52 GMT+8]")])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('small',[_v("[Powered by "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"30"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")]),_v(" on Wed, 4 Sept 2024, 18:37:04 GMT+8]")])])])} }]; \ No newline at end of file