diff --git a/.github/workflows/delete-deploy.yml b/.github/workflows/delete-deploy.yml index c57bff8a78..4836a7d605 100644 --- a/.github/workflows/delete-deploy.yml +++ b/.github/workflows/delete-deploy.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Delete deployments run: ./config/gh-actions/delete-deploy.sh diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index fcca272e9a..7e0798fdbc 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -16,15 +16,15 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '14.x' - name: Set up Node caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 4b0f6a89f2..c3e6150ad2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -15,32 +15,33 @@ jobs: name: ${{ matrix.os }} JDK 8 strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] runs-on: ${{ matrix.os }} env: NODE_VERSION: "lts/*" steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: - java-version: 1.8 + distribution: 'zulu' + java-version: 8 - name: Verify Java version run: echo -e "Actual JDK in use -- "; java -version - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '14.x' - name: Set up Gradle caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | ~/.gradle/caches @@ -50,7 +51,7 @@ jobs: ${{ matrix.os }}-gradle- - name: Set up Node caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ matrix.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -67,11 +68,15 @@ jobs: run: ./gradlew lintFrontend - name: Build with Gradle - run: time ./gradlew clean checkstyleMain checkstyleTest test systemTest coverage + run: ./gradlew clean checkstyleAll test systemTest coverage - name: Run code coverage if: ${{ success() && matrix.os == 'ubuntu-20.04' }} - run: bash <(curl -s https://codecov.io/bash) + uses: codecov/codecov-action@v3 + with: + directory: ${{ github.workspace }}/build/reports/jacoco/coverage + files: coverage.xml + fail_ci_if_error: true - name: Build preview website (pull request) if: ${{ success() && github.event_name == 'pull_request' && matrix.os == 'ubuntu-20.04' }} @@ -89,7 +94,7 @@ jobs: - name: Upload artifacts (pull request) if: ${{ success() && github.event_name == 'pull_request' && matrix.os == 'ubuntu-20.04' }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: reposense-deployment path: | @@ -101,32 +106,33 @@ jobs: name: ${{ matrix.os }} JDK 8 strategy: matrix: - os: [macos-10.15, macos-11] + os: [macos-11, macos-12] runs-on: ${{ matrix.os }} env: HOMEBREW_NO_AUTO_UPDATE: 1 # Prevent time-consuming brew update steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: - java-version: 1.8 + distribution: 'zulu' + java-version: 8 - name: Verify Java version run: echo -e "Actual JDK in use -- "; java -version - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '14.x' - name: Set up Gradle caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | ~/.gradle/caches @@ -136,7 +142,7 @@ jobs: ${{ matrix.os }}-gradle- - name: Set up Node caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ matrix.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -153,33 +159,100 @@ jobs: run: ./gradlew lintFrontend - name: Build with Gradle - run: time ./gradlew clean checkstyleMain checkstyleTest test systemTest coverage + run: ./gradlew clean checkstyleAll test systemTest coverage + + - name: Run code coverage + if: ${{ success() && matrix.os == 'macos-11' }} + uses: codecov/codecov-action@v3 + with: + directory: ${{ github.workspace }}/build/reports/jacoco/coverage + files: coverage.xml + fail_ci_if_error: true + + windows: + name: ${{ matrix.os }} JDK 8 + strategy: + matrix: + os: [windows-2019, windows-2022] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 8 + + - name: Verify Java version + run: Write-Output "Actual JDK in use -- "; java -version + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '14.x' + + - name: Set up Gradle caching + uses: actions/cache@v3 + with: + path: | + $HOME/.gradle/caches + $HOME/.gradle/wrapper + key: ${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: | + ${{ matrix.os }}-gradle- + + - name: Set up Node caching + uses: actions/cache@v3 + with: + path: $HOME/.npm + key: ${{ matrix.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ matrix.os }}-node- + + - name: Run linter + run: ./gradlew lintFrontend + + - name: Build with Gradle + run: ./gradlew clean checkstyleAll test systemTest coverage + + - name: Run code coverage + if: ${{ success() && matrix.os == 'windows-2022' }} + uses: codecov/codecov-action@v3 + with: + directory: ${{ github.workspace }}/build/reports/jacoco/coverage + files: coverage.xml + fail_ci_if_error: true cypress: name: Cypress frontend tests - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: - java-version: 1.8 + distribution: 'zulu' + java-version: 8 - name: Verify Java version run: echo -e "Actual JDK in use -- "; java -version - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '14.x' - name: Set up Gradle caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | ~/.gradle/caches @@ -189,7 +262,7 @@ jobs: ${{ runner.os }}-gradle- - name: Set up Node caching - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -199,18 +272,6 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Install packages - run: npm install - - - name: Set up Cypress - uses: cypress-io/github-action@v2 - with: - build: npm i -D cypress - working-directory: ./frontend/cypress - browser: chrome - headless: true - runTests: false # Just perform installation - - name: Set up environment run: sudo apt-get install -y libgtk2.0-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 diff --git a/.github/workflows/pending.yml b/.github/workflows/pending.yml index e948f26ae5..635ec989ce 100644 --- a/.github/workflows/pending.yml +++ b/.github/workflows/pending.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Update PR checklist for surge.sh as pending run: | @@ -27,7 +27,7 @@ jobs: - name: Upload artifacts if: ${{ success() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: reposense-deployment-id path: ./pr diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 72aa2c7042..64ad9820a5 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,14 +7,16 @@ on: jobs: stale: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 + - uses: actions/stale@v4 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-stale: 30 - days-before-close: 7 + days-before-stale: -1 + days-before-close: -1 + days-before-pr-stale: 30 + days-before-pr-close: 7 exempt-pr-labels: 's.DoNotMerge' remove-stale-when-updated: true stale-pr-label: 'Stale' diff --git a/.github/workflows/surge.yml b/.github/workflows/surge.yml index e572f3bcd5..21217a25c3 100644 --- a/.github/workflows/surge.yml +++ b/.github/workflows/surge.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '14.x' - name: Download deployment artifacts uses: dawidd6/action-download-artifact@v2 diff --git a/README.md b/README.md index d2351de2cd..826ba90910 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # RepoSense [![Build Status](https://github.com/reposense/RepoSense/actions/workflows/integration.yml/badge.svg)](https://github.com/reposense/RepoSense/actions/workflows/integration.yml) -[![Build status](https://ci.appveyor.com/api/projects/status/gsbkj5qby3pjd6nw/branch/master?svg=true)](https://ci.appveyor.com/project/eugenepeh/reposense/branch/master) [![codecov.io](https://codecov.io/gh/reposense/RepoSense/branch/master/graphs/badge.svg?branch=master)](http://codecov.io/github/reposense/RepoSense?branch=master) [![Netlify Status](https://api.netlify.com/api/v1/badges/260983b3-589e-4619-a2e8-0bfb7a2b4422/deploy-status)](https://app.netlify.com/sites/reposense/deploys) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 83aded9206..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -# AppVeyor configuration file -# For more details see https://www.appveyor.com/docs/build-configuration/ - -# Call on gradle to build and run tests -# --no-daemon: Prevent the daemon from launching to prevent file-in-use errors -# when we cache the ~/.gradle directory -build_script: - - gradlew.bat --no-daemon clean checkstyleMain checkstyleTest - -test_script: - - appveyor-retry gradlew.bat --no-daemon test systemTest - -environment: - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 # Use 64-bit Java - -# Files/folders to preserve between builds to speed them up -cache: - - C:\Users\appveyor\.gradle diff --git a/build.gradle b/build.gradle index 0e57d920e2..a6a9bf84ca 100644 --- a/build.gradle +++ b/build.gradle @@ -6,17 +6,17 @@ plugins { id 'idea' id 'jacoco' id 'java' - id 'com.github.johnrengelman.shadow' version '5.2.0' - id 'com.liferay.node' version '4.4.0' - id 'com.github.psxpaul.execfork' version '0.1.8' - id 'com.palantir.git-version' version '0.12.3' + id 'com.github.johnrengelman.shadow' version '7.1.2' + id 'com.liferay.node' version '7.2.18' + id 'com.github.psxpaul.execfork' version '0.2.0' + id 'com.palantir.git-version' version '0.13.0' } OperatingSystem os = DefaultNativePlatform.currentOperatingSystem; mainClassName = 'reposense.RepoSense' -node.nodeVersion = '10.16.0' +node.nodeVersion = '14.20.1' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -31,15 +31,17 @@ configurations { } dependencies { - implementation group: 'com.google.code.gson' ,name: 'gson', version:'2.8.5' - implementation group: 'net.freeutils', name: 'jlhttp', version: '2.4' - implementation group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.8.1' - implementation group: 'org.apache.ant', name: 'ant', version: '1.10.3' - implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.6' + String jUnitVersion = '5.8.2' + implementation group: 'com.google.code.gson' ,name: 'gson', version:'2.9.0' + implementation group: 'net.freeutils', name: 'jlhttp', version: '2.6' + implementation group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.9.0' + implementation group: 'org.apache.ant', name: 'ant', version: '1.10.12' + implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.9.0' implementation group: 'org.apache.commons', name: 'commons-text', version: '1.9' - implementation group: 'org.fusesource.jansi', name: 'jansi', version: '1.18' + implementation group: 'org.fusesource.jansi', name: 'jansi', version: '2.4.0' - testImplementation group: 'junit', name: 'junit', version: '4.12' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: jUnitVersion + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: jUnitVersion } sourceSets { @@ -52,18 +54,46 @@ sourceSets { } wrapper { - gradleVersion = '5.2.1' + gradleVersion = '7.4.2' } +def installFrontend = tasks.register('installFrontend', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { + workingDir 'frontend/' + args = ['install'] +} + +def buildFrontend = tasks.register('buildFrontend', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { + dependsOn installFrontend + workingDir 'frontend/' + args = ['run', 'devbuild'] +} + +def zipReport = tasks.register('zipReport', Zip) { + dependsOn buildFrontend + from 'frontend/build/' + archiveBaseName = 'templateZip' + destinationDirectory = file('src/main/resources') +} + +def compileJava = tasks.compileJava +def classes = tasks.classes + +tasks.named("processSystemtestResources").configure { + duplicatesStrategy = DuplicatesStrategy.INCLUDE +} + +tasks.run.dependsOn(zipReport); + run { //the second arguments indicates the default value associated with the property. + tasks.compileJava.mustRunAfter(zipReport) args System.getProperty('args', '').split() systemProperty "version", getRepoSenseVersion() } checkstyle { - toolVersion = '8.1' - configDir = file("$rootProject.projectDir/config/checkstyle") + toolVersion = '9.3' + getConfigDirectory().set(file("$rootProject.projectDir/config/checkstyle")) } idea { @@ -72,19 +102,6 @@ idea { } } -jacoco { - toolVersion = "0.8.3" -} - -jacocoTestReport { - reports { - html.enabled = true - xml.enabled true - csv.enabled false - html.destination file("${buildDir}/jacocoHtml") - } -} - test { environment("REPOSENSE_ENVIRONMENT", "TEST") @@ -97,46 +114,43 @@ test { deleteReposAddressDirectory() } + useJUnitPlatform() + doLast { deleteReposAddressDirectory() } } +tasks.shadowJar.dependsOn(zipReport); + shadowJar { - archiveName = 'RepoSense.jar' - destinationDir = file("${buildDir}/jar/") + tasks.compileJava.mustRunAfter(zipReport) + tasks.processResources.mustRunAfter(zipReport) + archiveFileName = 'RepoSense.jar' + destinationDirectory = file("${buildDir}/jar/") manifest { attributes 'Implementation-Version': getRepoSenseVersion() } } -task installFrontend(type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { - workingDir 'frontend/' - args = ['install'] -} - -task buildFrontend(dependsOn: ['installFrontend'], type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { - workingDir 'frontend/' - args = ['run', 'devbuild'] -} - -task lintFrontend(dependsOn: ['installFrontend'], type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { +tasks.register('lintFrontend', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { + dependsOn installFrontend workingDir 'frontend/' args = ['run', 'lint'] } -task zipReport(dependsOn: 'buildFrontend', type: Zip) { - from 'frontend/build/' - baseName = 'templateZip' - destinationDir = file('src/main/resources') -} +def checkstyleMain = tasks.checkstyleMain +def checkstyleTest = tasks.checkstyleTest +def checkstyleSystemtest = tasks.checkstyleSystemtest -tasks.shadowJar.dependsOn('zipReport'); -tasks.compileJava.dependsOn('zipReport'); -tasks.run.dependsOn('compileJava'); +tasks.register('checkstyleAll', Checkstyle) { + dependsOn checkstyleMain, checkstyleTest, checkstyleSystemtest + tasks.checkstyleTest.mustRunAfter('checkstyleMain') + tasks.checkstyleSystemtest.mustRunAfter('checkstyleTest') +} -task systemtest(dependsOn: 'zipReport', type: Test) { +tasks.register('systemtest', Test) { testClassesDirs = sourceSets.systemtest.output.classesDirs classpath = sourceSets.systemtest.runtimeClasspath environment("REPOSENSE_ENVIRONMENT", "TEST") @@ -150,34 +164,43 @@ task systemtest(dependsOn: 'zipReport', type: Test) { deleteReposAddressDirectory() } + useJUnitPlatform() + doLast { deleteReposAddressDirectory() } } -task startServerInBackground(dependsOn: 'classes', type: com.github.psxpaul.task.JavaExecFork) { +def serveTestReportInBackground = tasks.register('serveTestReportInBackground', com.github.psxpaul.task.JavaExecFork) { + dependsOn zipReport, compileJava, processResources, classes + tasks.compileJava.mustRunAfter(zipReport) + tasks.processResources.mustRunAfter(zipReport) main = mainClassName classpath = sourceSets.main.runtimeClasspath args = ['--config', './frontend/cypress/config', '--since', 'd1', '--view'] String versionJvmArgs = '-Dversion=' + getRepoSenseVersion() jvmArgs = [ versionJvmArgs ] + killDescendants = false // Kills descendants of started process using methods only found in Java 9 and beyond. + // Above flag is set to true by default but is incompatible with Java 8. It should be removed from this file if we fully migrate to Java 11. waitForPort = 9000 } -task installCypress(type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { +def installCypress = tasks.register('installCypress', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { workingDir 'frontend/cypress/' args = ['install'] } -task cypress(dependsOn: ['zipReport', 'installCypress', 'startServerInBackground'], type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { - tasks.startServerInBackground.mustRunAfter('installCypress') +tasks.register('cypress', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { + dependsOn installCypress, serveTestReportInBackground + tasks.serveTestReportInBackground.mustRunAfter(installCypress) workingDir = file('frontend/cypress/') args = ["run-script", "debug"] } -task frontendTest(dependsOn: ['zipReport', 'installCypress', 'startServerInBackground'], type: com.liferay.gradle.plugins.node.tasks.ExecuteNpmTask) { - tasks.startServerInBackground.mustRunAfter('installCypress') +tasks.register('frontendTest', com.liferay.gradle.plugins.node.tasks.ExecutePackageManagerTask) { + dependsOn installCypress, serveTestReportInBackground + tasks.serveTestReportInBackground.mustRunAfter(installCypress) workingDir = file('frontend/cypress/') args = ["run-script", "tests"] @@ -192,7 +215,24 @@ tasks.withType(Copy) { includeEmptyDirs = true } -task coverage(type: JacocoReport) { +jacoco { + toolVersion = "0.8.7" +} + +jacocoTestReport { + reports { + html.required = true + xml.required = true + csv.required = false + html.destination file("${buildDir}/jacocoHtml") + } + + executionData systemtest, frontendTest +} + +tasks.register('coverage', JacocoReport) + +coverage.configure { sourceDirectories.from files(sourceSets.main.allSource.srcDirs) classDirectories.from files(sourceSets.main.output) executionData.from files(jacocoTestReport.executionData) @@ -204,8 +244,8 @@ task coverage(type: JacocoReport) { } reports { - html.enabled = true - xml.enabled = true + html.required = true + xml.required = true } } @@ -217,7 +257,7 @@ String getRepoSenseVersion() { return repoSenseVersion } -task syncFrontendPublic(type: Sync) { +def syncFrontendPublic = tasks.register('syncFrontendPublic', Sync) { from 'reposense-report' into 'frontend/public/' include '**/*.json' @@ -228,28 +268,28 @@ task syncFrontendPublic(type: Sync) { } } -task macHotReloadFrontend(type: Exec) { - dependsOn(installFrontend) +def macHotReloadFrontend = tasks.register('macHotReloadFrontend', Exec) { + dependsOn installFrontend onlyIf {os.isMacOsX()} workingDir 'frontend/' commandLine 'npm', 'run', 'serveOpen' } -task windowsHotReloadFrontend(type: Exec) { - dependsOn(installFrontend) +def windowsHotReloadFrontend = tasks.register('windowsHotReloadFrontend', Exec) { + dependsOn installFrontend onlyIf {os.isWindows()} workingDir 'frontend/' commandLine 'cmd','/c', 'START', '"hotreload RepoSense frontend"', 'npm', 'run', 'serveOpen' } -task linuxHotReloadFrontend(type: Exec) { - dependsOn(installFrontend) +def linuxHotReloadFrontend = tasks.register('linuxHotReloadFrontend', Exec) { + dependsOn installFrontend onlyIf {os.isLinux()} workingDir 'frontend/' commandLine 'npm', 'run', 'serveOpen' } -task hotReloadFrontend() { +tasks.register('hotReloadFrontend') { dependsOn syncFrontendPublic finalizedBy windowsHotReloadFrontend finalizedBy macHotReloadFrontend @@ -263,7 +303,4 @@ void deleteReposAddressDirectory() { reposDirectory.deleteDir() } -jacocoTestReport.executionData(systemtest) -jacocoTestReport.executionData(frontendTest) - defaultTasks 'clean', 'build', 'systemtest', 'frontendTest', 'coverage' diff --git a/config/author-config.csv b/config/author-config.csv index b2a7c99c1f..6af7446252 100644 --- a/config/author-config.csv +++ b/config/author-config.csv @@ -1,4 +1,4 @@ -Repository's Location,Branch,Author's GitHub ID,Author's Emails,Author's Display Name,Author's Git Author Name,Ignore Glob List +Repository's Location,Branch,Author's Git Host ID,Author's Emails,Author's Display Name,Author's Git Author Name,Ignore Glob List https://github.com/reposense/testrepo-Beta.git,master,nbriannl,,"Ashwin Mukadaan Singhania, Rathod",, https://github.com/reposense/testrepo-Beta.git,master,zacharytang,zacharytang.tc@gmail.com,Yagami Rukei Polland,,src/main** https://github.com/reposense/testrepo-Beta.git,master,April0616,,2805Tagoe,LAPTOP-7KFM2KSP\User;Fan Yuting, @@ -7,3 +7,6 @@ https://github.com/reposense/testrepo-Beta.git,add-config-json,nbriannl,,A.M.S.R https://github.com/reposense/testrepo-Beta.git,add-config-json,zacharytang,zacharytang.tc@gmail.com,Yaga..Polland,,src/main** https://github.com/reposense/testrepo-Beta.git,add-config-json,April0616,, ,LAPTOP-7KFM2KSP\User;Fan Yuting, https://github.com/reposense/testrepo-Beta.git,add-config-json,CindyTsai1,,Ravind s/o Ramesh,YuHsuan,src/test** +https://bitbucket.org/skyblaise/testrepo-bitbucket.git,master,skyblaise,,Zhang Shi Chen,SHICHEN ZHANG;SkyBlaise, +https://gitlab.com/reposense/testrepo-gitlab.git,main,zsc990124,,Zhang Shi Chen,SHICHEN ZHANG;SkyBlaise, +https://tomluozhijie@git.code.sf.net/p/repo-sense-test-repo/code,master,luozhijie-tom,,Luo Zhijie,Luo Zhijie;Luo Zhijie, diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index f5118345c1..7136b8d86b 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -4,8 +4,9 @@ "https://checkstyle.org/dtds/configuration_1_3.dtd"> @@ -29,6 +30,10 @@ + + + + @@ -145,11 +150,6 @@ - - - - - @@ -272,6 +272,10 @@ + + + + @@ -327,6 +331,7 @@ + @@ -335,52 +340,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - + - + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml index dabcd1ff4e..2a0ff8b4ff 100644 --- a/config/checkstyle/suppressions.xml +++ b/config/checkstyle/suppressions.xml @@ -6,4 +6,6 @@ + + diff --git a/config/gh-actions/delete-deploy.sh b/config/gh-actions/delete-deploy.sh index 9e1293590d..87bb596d8a 100755 --- a/config/gh-actions/delete-deploy.sh +++ b/config/gh-actions/delete-deploy.sh @@ -60,13 +60,33 @@ mark_deployment_inactive() { # Function to get deployment data about repo via a cURL command # $1: Deployment environment name +# $2: Page number get_deployment_data() { - curl "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/deployments?per_page=100&environment=${1}" \ + curl "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/deployments?per_page=100&page=${2}&environment=${1}" \ -X GET \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: token ${GITHUB_TOKEN}" } +# Function to get deployment ids iterating through deployment pages +# $1: Deployment environment name +get_all_deployment_ids() { + curr_page=1 + deploy_ids=() + res_ids=("TEMP") + while [ ${#res_ids[@]} -ne 0 ] + do + # Get deployment data for curr_page + res=$(get_deployment_data "${1}" ${curr_page}) + # Get deployment ids from res + res_ids=($(get_ids_from_response "$res")) + # Append ids to deploy_ids + deploy_ids=("${deploy_ids[@]}" "${res_ids[@]}") + curr_page=$((curr_page+1)) + done + echo "${deploy_ids[*]}" +} + # Function to post surge deployment links as a comment on PR via a cURL command post_preview_links_comment() { curl "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/issues/${ACTIONS_PULL_REQUEST_NUMBER}/comments" \ @@ -91,13 +111,8 @@ delete_all_deployments() { done } -# Get deployment data from Github -DASHBOARD_RES=$(get_deployment_data "$ACTIONS_DASHBOARD_ENV") -DOCS_RES=$(get_deployment_data "$ACTIONS_DOCS_ENV") - -# Extract deployment IDs -DASHBOARD_IDS=($(get_ids_from_response "$DASHBOARD_RES")) -DOCS_IDS=($(get_ids_from_response "$DOCS_RES")) +DASHBOARD_IDS=($(get_all_deployment_ids "$ACTIONS_DASHBOARD_ENV")) +DOCS_IDS=($(get_all_deployment_ids "$ACTIONS_DOCS_ENV")) post_preview_links_comment delete_all_deployments "${DASHBOARD_IDS[@]}" diff --git a/config/repo-config.csv b/config/repo-config.csv index 535b99b19c..7e33fde922 100644 --- a/config/repo-config.csv +++ b/config/repo-config.csv @@ -8,3 +8,6 @@ https://github.com/reposense/testrepo-Delta.git,add-binary-file,,,,,,, https://github.com/reposense/RepoSense.git,master,,,,,,, https://github.com/reposense/testrepo-Empty.git,master,,,,,,, ftp://github.com/reposense/RepoSense.git,master,,,,,,, +https://bitbucket.org/skyblaise/testrepo-bitbucket.git,master,,,,,,, +https://gitlab.com/reposense/testrepo-gitlab.git,main,,,,,,, +https://tomluozhijie@git.code.sf.net/p/repo-sense-test-repo/code,master,,,,,,, diff --git a/docs/_markbind/layouts/dg-sitenav.md b/docs/_markbind/layouts/dg-sitenav.md index 1f966b0ab4..4889598fd5 100644 --- a/docs/_markbind/layouts/dg-sitenav.md +++ b/docs/_markbind/layouts/dg-sitenav.md @@ -9,6 +9,7 @@ {name: "Project management", link: "dg/projectManagement.html"}, {name: "DevOps guide", link: "dg/devOpsGuide.html"}, {name: "Appendices"}, + {level: 2, name: "CLI syntax reference", link: "dg/cli.html"}, {level: 2, name: "Style guides", link: "dg/styleGuides.html"} ] %} diff --git a/docs/about.md b/docs/about.md index 1bdfdf1297..94d35cad85 100644 --- a/docs/about.md +++ b/docs/about.md @@ -5,7 +5,7 @@

{{ title }}

-RepoSense is a project based in the [National University of Singapore, School of Computing](http://www.comp.nus.edu.sg/), funded by a _Teaching Enhancement Grant_ from the [NUS Center for Development of Teaching and Learning](http://www.cdtl.nus.edu.sg/). +RepoSense is a project based in the [National University of Singapore, School of Computing](http://www.comp.nus.edu.sg/), funded by a _Teaching Enhancement Grant_ from the [NUS Center for Development of Teaching and Learning](https://nus.edu.sg/cdtl). @@ -20,64 +20,48 @@ RepoSense is a project based in the [National University of Singapore, School of ### [Wang Chao](https://github.com/fzdy1914) ![](https://avatars3.githubusercontent.com/u/35621726?s=150&v=4)
**Role**: Project Lead [2021 Jan - ]
-Maintainer [2020 May- 2021 Jan]
+Maintainer [2020 May - 2021 Jan]
Committer [2019 May - 2020 May]
Contributor [2018 Dec - 2019 May]
-### [Peh Xian Bin, Eugene](https://github.com/eugenepeh) -![](https://avatars.githubusercontent.com/u/19277206?s=150&v=4)
-**Role**: Maintainer [2020 May - ]
-Project Lead [2018 May - 2020 May]
- - -### [James Pang Mun Wai](https://github.com/jamessspanggg) -![](https://avatars1.githubusercontent.com/u/32864116?s=150&v=4)
-**Role**: Maintainer [2021 Jan - ]
-Committer [2020 May - 2021 Jan]
-Contributor [2019 May - 2020 May]
- - - -### [Liu Yiwen](https://github.com/0blivious) -**Role**: Contributor [2019 August - ]
- - - -### [Tejas Bhuwania](https://github.com/Tejas2805) -![](https://avatars2.githubusercontent.com/u/35946746?s=150&v=4)
-**Role**: Contributor [2019 August - ]
+### [Hsu Zhong Jun](https://github.com/dcshzj) +![](https://avatars.githubusercontent.com/u/27919917?s=150&v=4)
+**Role**: Committer [2021 June - ]
+Contributor [2020 August - 2021 May]
-### [Anubhav](https://github.com/anubh-v) -**Role**: Contributor [2019 September - ]
+### [Chan Ger Hean](https://github.com/gerhean) +**Role**: Committer [2022 January - ]
+Contributor [2021 January - 2021 December]
-### [Ang Ze Yu](https://github.com/ang-zeyu) -**Role**: Contributor [2020 January - ]
+### [Huang Chengyu](https://github.com/HCY123902) +**Role**: Committer [2022 January - ]
+Contributor [2021 January - ]
-### [Chan Ger Hean](https://github.com/gerhean) -**Role**: Contributor [2021 January - ]
+### [Chan Jun Da](https://github.com/chan-j-d) +**Role**: Contributor [2021 July - ]
-### [Hsu Zhong Jun](https://github.com/dcshzj) -**Role**: Contributor [2021 January - ]
+### [Tay Yi Hsuen](https://github.com/yhtMinceraft1010X) +**Role**: Contributor [2021 July - ]
-### [Huang Chengyu](https://github.com/HCY123902) -**Role**: Contributor [2021 January - ]
+### [Gokul Rajiv](https://github.com/gok99) +**Role**: Contributor [2022 January - ]
-### [Roland Yu Wenyang](https://github.com/rolandyuwy) -**Role**: Contributor [2021 January - ]
+### [Zhou Jiahao](https://github.com/Zhou-Jiahao-1998) +**Role**: Contributor [2022 January - ]
@@ -112,6 +96,13 @@ Contributor [2018 May - 2018 Aug]
+### [Peh Xian Bin, Eugene](https://github.com/eugenepeh) +![](https://avatars.githubusercontent.com/u/19277206?s=150&v=4)
+**Role**: Maintainer [2020 May - 2021 Jan]
+Project Lead [2018 May - 2020 May]
+ + + ### [Aditya Agarwal](https://github.com/adityaa1998) Contributor [2018 May - 2018 Aug] @@ -122,7 +113,7 @@ Contributor [2018 Aug - 2019 May] -### [Chelsey Ong Hee](https://github.com/chelseyong) +### [Chelsey Ong Hee](https://github.com/chel-seyy) Contributor [2018 Dec - 2019 May] @@ -142,6 +133,13 @@ Contributor [2018 Dec - 2019 May] +### [James Pang Mun Wai](https://github.com/jamessspanggg) +![](https://avatars1.githubusercontent.com/u/32864116?s=150&v=4)
+**Role**: Committer [2020 May - 2021 Jan]
+Contributor [2019 May - 2020 May]
+ + + ### [Lee Jin Yao](https://github.com/jylee-git) ![](https://avatars3.githubusercontent.com/u/35756209?s=150&v=4)
**Role**: Contributor [2019 May - 2020 May]
@@ -161,3 +159,30 @@ Contributor [2018 Dec - 2019 May] ### [Yash Chowdhary](https://github.com/yash-chowdhary) ![](https://avatars2.githubusercontent.com/u/21968718?s=150&v=4)
**Role**: Contributor [2020 January - 2020 May]
+ + + +### [Liu Yiwen](https://github.com/0blivious) +**Role**: Contributor [2019 August - 2021 May]
+ + + +### [Tejas Bhuwania](https://github.com/Tejas2805) +![](https://avatars2.githubusercontent.com/u/35946746?s=150&v=4)
+**Role**: Contributor [2019 August - 2021 August]
+ + + +### [Anubhav](https://github.com/anubh-v) +**Role**: Contributor [2019 September - 2020 August]
+ + + +### [Ang Ze Yu](https://github.com/ang-zeyu) +**Role**: Contributor [2020 January - 2021 May]
+ + + +### [Roland Yu Wenyang](https://github.com/rolandyuwy) +**Role**: Contributor [2021 January - 2021 March]
+ diff --git a/docs/dg/architecture.md b/docs/dg/architecture.md index 1ae90e8360..38a3022f62 100644 --- a/docs/dg/architecture.md +++ b/docs/dg/architecture.md @@ -96,7 +96,7 @@ Note that when constructing new commands containing path arguments, use the `Str * [`Author`](https://github.com/reposense/RepoSense/blob/master/src/main/java/reposense/model/Author.java) stores the `GitHub ID` of an author. Any contributions or commits made by the author, using his/her `GitHub ID` or aliases, will be attributed to the same `Author` object. `AuthorshipReporter` and `CommitsReporter` use it to attribute the commit and file contributions to the respective authors. * [`CliArguments`](https://github.com/reposense/RepoSense/blob/master/src/main/java/reposense/model/CliArguments.java) stores the parsed command-line arguments supplied by the user. It contains the configuration settings such as the CSV config file to read from, the directory to output the report to, and the date range of commits to analyze. These configuration settings are passed into `RepoConfiguration`. * [`FileTypeManager`](https://github.com/reposense/RepoSense/blob/master/src/main/java/reposense/model/FileTypeManager.java) stores the file format to be analyzed and the custom groups specified by the user for any repository. - * [`RepoConfiguration`](https://github.com/reposense/RepoSense/blob/master/src/main/java/reposense/model/RepoConfiguration.java) stores the configuration information from the CSV config file for a single repository: the repository's organization, name, branch, list of authors to analyse, date range to analyze commits, and files from `CliArguments`. + * [`RepoConfiguration`](https://github.com/reposense/RepoSense/blob/master/src/main/java/reposense/model/RepoConfiguration.java) stores the configuration information from the CSV config file for a single repository: the repository's organization, name, branch, list of authors to analyze, date range to analyze commits, and files from `CliArguments`. This configuration information is used by: - `GitClone` to determine the location to clone the repository from and which branch to check out to. - `AuthorshipReporter` and `CommitsReporter` to determine the range of commits and files to analyze. diff --git a/docs/dg/cli.md b/docs/dg/cli.md new file mode 100644 index 0000000000..221effe69f --- /dev/null +++ b/docs/dg/cli.md @@ -0,0 +1,44 @@ +{% set title = "Appendix: CLI syntax reference" %} + + title: "{{ title | safe }}" + pageNav: 3 + + +

{{ title }}

+ +The section below provides explanations for flags used in system testing. For other flags, please visit the CLI +syntax reference under Appendix section of User Guide. + + + +### `--test-mode` + +**`--test-mode`**: Enables test mode behavior. + + + +* Used in `ConfigSystemTest`. +* Some test cases requires `AuthorConfiguration.hasAuthorConfigFile` to be set to `false` to pass. The exact +reason is unknown as the test cases are pretty old to track back. Tracing this shows that there is something to do +with `AnnotatorAnalyzer.findAuthorInLine()` where `AuthorConfiguration.hasAuthorConfigFile()` is called. +* Can be used for behaviors specific to test code. + * E.g. `--fresh-cloning`. Fresh cloning is always `false` when running RepoSense normally, and is only used in + system tests. + + + + + +### `--fresh-cloning` + +**`--fresh-cloning`**: Clones the repo again if it has been cloned before. + + + +* Used in `ConfigSystemTest`. +* Some test cases performs shallow cloning while some does not. Fresh cloning ensures that the test cases that does +not perform shallow cloning will clone the repo again if the previous test case uses shallow cloning, ensuring +correctness of the analysis. +* Requires `--test-mode` flag to be enabled. + + diff --git a/docs/dg/devOpsGuide.md b/docs/dg/devOpsGuide.md index dbc335f474..c82bba542c 100644 --- a/docs/dg/devOpsGuide.md +++ b/docs/dg/devOpsGuide.md @@ -18,7 +18,7 @@ This page documents the various components that form part of the DevOps infrastr ## GitHub Actions -[GitHub Actions](https://docs.github.com/en/actions) is a platform that is used by RepoSense for running the test suite and is primarily used for continuous integration and testing. The test suite is is stored in `.github/workflows/` and comprises of: +[GitHub Actions](https://docs.github.com/en/actions) is a platform that is used by RepoSense for running the test suite and is primarily used for continuous integration and testing. The test suite is stored in `.github/workflows/` and comprises of: - Unit tests (in `src/tests/`) - System tests (in `src/systemtest/`) @@ -26,11 +26,12 @@ This page documents the various components that form part of the DevOps infrastr ### Continuous integration -All three types of tests in the test suite are run in a single GitHub Actions workflow called "Continuous Integration". The steps are defined in [`integration.yml`](https://github.com/reposense/RepoSense/blob/master/.github/workflows/integration.yml) and are split into three types of jobs: +All three types of tests in the test suite are run in a single GitHub Actions workflow called "Continuous Integration". The steps are defined in [`integration.yml`](https://github.com/reposense/RepoSense/blob/master/.github/workflows/integration.yml) and are split into four types of jobs: 1. Ubuntu JDK 8 (`ubuntu`): Runs both unit tests and system tests on JDK 1.8 running on supported Ubuntu versions. This job also produces a RepoSense report and the MarkBind documentation website for previewing. 2. macOS JDK 8 (`macos`): Runs both unit tests and system tests on JDK 1.8 running on supported macOS versions. -3. Cypress frontend tests (`cypress`): Runs only the frontend tests on JDK 1.8 running on Ubuntu 18.04 LTS. +3. Windows JDK 8 (`windows`): Runs both unit tests and system tests on JDK 1.8 running on supported Windows versions. +4. Cypress frontend tests (`cypress`): Runs only the frontend tests on JDK 1.8 running on Ubuntu 20.04 LTS. The list of supported OS versions are [available on the GitHub Docs website](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources). These jobs should be updated regularly whenever RepoSense supports newer versions of the Java Development Kit (JDK) as well as when new OS versions are made available (via the job OS matrix). Frontend tests are run separately to take advantage of parallel job execution. @@ -38,6 +39,8 @@ Some of the jobs execute some commands that are too complicated to be included i This workflow is run for both incoming pull requests to any branch as well as direct commits to any branch in the repository. +Cypress frontend tests are run against reports generated from config files in `frontend/cypress/config`. It uses the `cypress` branch of the RepoSense repository which is kept independent of `master` and should be updated only when there are new frontend tests that need to be accommodated. + ### Report and documentation previews For each pull request to any branch in the repository, a RepoSense report and the MarkBind documentation website is generated based on the code submitted in the pull request. This is to facilitate pull request reviewers in being able to quickly preview how the RepoSense report and/or the documentation website will change after the pull request is merged. @@ -71,12 +74,6 @@ This task automates the cleaning up of the pull requests by automatically markin -## Appveyor - -[Appveyor](https://ci.appveyor.com/project/eugenepeh/reposense) is another platform used for running continuous integration tasks on both commits and pull requests, primarily used for running the test suite on the Windows platform. The settings are located in [`appveyor.yml`](https://github.com/reposense/RepoSense/blob/master/appveyor.yml). - - - ## Surge.sh Surge.sh is a platform for hosting the RepoSense report and documentation preview builds. The deployment is automatically performed by the "Surge.sh build preview" job using the [`deploy.sh`](https://github.com/reposense/RepoSense/blob/master/config/gh-actions/deploy.sh) script in the `config/gh-actions/` folder. diff --git a/docs/dg/learningBasics.md b/docs/dg/learningBasics.md index 160319f60c..7f10897849 100644 --- a/docs/dg/learningBasics.md +++ b/docs/dg/learningBasics.md @@ -34,7 +34,7 @@ The backend implementation of RepoSense is located in `src/main`. The RepoSense backend is mostly written in `Java 8`. 1. You need to have a basic knowledge of Java before getting started, including its syntax, [API](https://docs.oracle.com/javase/8/docs/api/), and certain frameworks such as [JUnit](https://se-education.org/learningresources/contents/java/JUnit.html). -1. Once you are familiar with the basic syntax, you may wish to learn more advanced topics such as [concurrency](https://se-education.org/learningresources/contents/java/JavaConcurrency.html), [synchronization](https://se-education.org/learningresources/contents/java/JavaSynchronization.html), and [streams](https://se-education.org/learningresources/contents/java/streams-an-introduction.html). These topics can help you to understand certain part of the backend implementation (concurrent cloning and analysis of multiple repositories, etc). They are optional but you may find them useful when working on certain issues. +1. Once you are familiar with the basic syntax, you may wish to learn more advanced topics such as [concurrency](https://se-education.org/learningresources/contents/java/JavaConcurrency.html), [synchronization](https://se-education.org/learningresources/contents/java/JavaSynchronization.html), and [streams](https://se-education.org/learningresources/contents/java/streams-an-introduction.html). These topics can help you to understand certain part of the backend implementation (concurrent cloning and analysis of multiple repositories, etc.). They are optional but you may find them useful when working on certain issues. {{ step(2) }} **Learn the RepoSense backend architecture** @@ -265,10 +265,10 @@ Vue.js uses JavaScript as its programming language. Before learning **Vue.js**, You can refer to the [Javascript documentation](https://devdocs.io/javascript/) to learn the basic syntax. There are plenty of other resources available and please feel free to find the resource most suitable for you. -RepoSense uses **Vue.js** (Vue2) in its front-end implementation. In particular, major user interface components, such as [summary view](report.html#summary-view-v-summary-js), [authorship view](report.html#authorship-view-v-authorship-js), and [zoom view](report.html#zoom-view-v-zoom-js), are implemented as Vue components. The corresponding source files are in `frontend/src`. +RepoSense uses **Vue.js** (Vue3) in its front-end implementation. In particular, major user interface components, such as [summary view](report.html#summary-view-v-summary-js), [authorship view](report.html#authorship-view-v-authorship-js), and [zoom view](report.html#zoom-view-v-zoom-js), are implemented as Vue components. The corresponding source files are in `frontend/src`. -* If you are new to Vue.js, you may want to start learning by looking at the [the beginner tutorial](https://www.vuemastery.com/courses/intro-to-vue-js/). -* You can dive deeper later by checking the [Vue.js documentation](https://vuejs.org/v2/guide/index.html) to learn about essential concepts such as component life cycle hooks, and component properties. +* If you are new to Vue.js, you may want to start learning by looking at [the beginner tutorial](https://www.vuemastery.com/courses/intro-to-vue-js/). +* You can dive deeper later by checking the [Vue.js documentation](https://vuejs.org/guide/introduction.html) to learn about essential concepts such as component life cycle hooks, and component properties. * It is recommended if you can work on some small projects first to gain more solid understanding of Vue.js. @@ -333,29 +333,29 @@ Here are some small tasks for you to gain some basic knowledge of the code relat - Try to locate where the author title is in [`v-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/v-summary-charts.vue). + Try to locate where the author title is in [`c-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/c-summary-charts.vue). - You can check what `activeUser` and `activeRepo` do in [`v-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/v-summary-charts.vue). + You can check what `activeUser` and `activeRepo` do in [`c-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/c-summary-charts.vue). - Refer to how changes are made to the title background and icon background in [`v-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/v-summary-charts.vue). + Refer to how changes are made to the title background and icon background in [`c-summary-charts.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/c-summary-charts.vue). - Some of the CSS styling for `v-summary-charts.vue` is in [`style.scss`](https://github.com/reposense/RepoSense/blob/master/frontend/src/styles/style.scss). You can add corresponding class selector if necessary. + Some of the CSS styling for `c-summary-charts.vue` is in [`style.scss`](https://github.com/reposense/RepoSense/blob/master/frontend/src/styles/style.scss). You can add corresponding class selector if necessary. There is more than 1 way to achieve this. One solution is shown as the following: - Add this to `v_summary.scss`. + Add this to `c_summary.scss`. ``` .active-text { @@ -363,7 +363,7 @@ Here are some small tasks for you to gain some basic knowledge of the code relat } ``` - In `v-summary-charts.vue`, locate `summary-chart__title--name`, and add the following to its `v-bind:class` attribute map. + In `c-summary-charts.vue`, locate `summary-chart__title--name`, and add the following to its `v-bind:class` attribute map. ``` 'active-text': user.name === activeUser && user.repoName === activeRepo @@ -393,12 +393,12 @@ Here are some small tasks for you to gain some basic knowledge of the code relat - Try to locate where the file title and the file path are in [`v-authorship.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-authorship.vue). + Try to locate where the file title and the file path are in [`c-authorship.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-authorship.vue). - You can check how tooltip is added for the triangular icon in the file title in [`v-authorship.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-authorship.vue). + You can check how tooltip is added for the triangular icon in the file title in [`c-authorship.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-authorship.vue). @@ -410,7 +410,7 @@ Here are some small tasks for you to gain some basic knowledge of the code relat There is more than 1 way to achieve this. One solution is shown as the following: - 1. In `v-authorship.vue`, locate the section that iterates through each file in `selectedFiles`. + 1. In `c-authorship.vue`, locate the section that iterates through each file in `selectedFiles`. 2. There is a specific portion of the section that renders the toggle icon, the file index, and the file path of the file title. 3. Try to locate the `span` tag that renders `file.path`, and wraps it inside a new `tooptip`. 4. In the `tooltip`, use the following instructions to handle the switch of tooltip message. @@ -442,12 +442,12 @@ Here are some small tasks for you to gain some basic knowledge of the code relat - Try to locate where the commit title is in [`v-zoom.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-zoom.vue). + Try to locate where the commit title is in [`c-zoom.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-zoom.vue). - You can check how tooltip is added for other icons in [`v-zoom.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-zoom.vue). + You can check how tooltip is added for other icons in [`c-zoom.vue`](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-zoom.vue). @@ -459,7 +459,7 @@ Here are some small tasks for you to gain some basic knowledge of the code relat There is more than 1 way to achieve this. One solution is shown as the following: - 1. In `v-zoom.vue`, locate the section that iterates througth each `day` in `selectedCommits`. + 1. In `c-zoom.vue`, locate the section that iterates through each `day` in `selectedCommits`. 2. The component that helps render the commit message title should be an `a` tag which uses the `getSliceLink` method to set the link to the commit details and uses `slice.messageTitle` to show the commit message title. 3. Wrap the `a` tag in a new `tooltip`. 4. In the `tooltip`, add the following content to show the tooltip message. diff --git a/docs/dg/projectManagement.md b/docs/dg/projectManagement.md index 54923434cd..d2c815753f 100644 --- a/docs/dg/projectManagement.md +++ b/docs/dg/projectManagement.md @@ -21,7 +21,7 @@ This page contains information about project management tasks. The target audien -## Making a release on Github +## Making a release on GitHub Before making a release, please check the following prerequisites: @@ -32,7 +32,7 @@ Before making a release, please check the following prerequisites: 1. Switch to the local `release` branch, and merge the `master` branch into it with `git merge master --no-ff` (no fast forward to keep the commit history for releases). 1. Push the local `release` branch directly to the [upstream `release` branch](https://github.com/reposense/RepoSense/tree/release) (make sure you have the push access). -To make a release for RepoSense on Github, please follow the `Creating a release` section in the [Github Docs](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository).
+To make a release for RepoSense on GitHub, please follow the `Creating a release` section in the [GitHub Docs](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository).
Take note of the following when making the release according to the above guide: * When entering a release version number, use semantic versioning with some small tweaks: diff --git a/docs/dg/report.md b/docs/dg/report.md index 13c889b0b5..1fa6baad75 100644 --- a/docs/dg/report.md +++ b/docs/dg/report.md @@ -8,7 +8,7 @@ The report's source files are located in [`frontend/src`](https://github.com/reposense/RepoSense/blob/master/frontend/src) and are built by [vue-cli](https://github.com/vuejs/vue-cli) before being packaged into the JAR file to be extracted as part of the report. -[Vue](https://vuejs.org/v2/api/) (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. It is heavily utilized in the report to update the information in the various views dynamically. (Style guide available [here](https://vuejs.org/v2/style-guide/), Developer tool available [here](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)). Vue lifecycle hooks are the defined methods that get executed in a particular stage of the Vue object lifespan. The following is the Vue lifecycle diagram taken from [here](https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram) indicating the hook sequence: +[Vue](https://vuejs.org/api/) (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. It is heavily utilized in the report to update the information in the various views dynamically. (Style guide available [here](https://vuejs.org/style-guide/), Developer tool available [here](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)). Vue lifecycle hooks are the defined methods that get executed in a particular stage of the Vue object lifespan. The following is the Vue lifecycle diagram taken from [here](https://vuejs.org/guide/essentials/lifecycle.html#lifecycle-diagram) indicating the hook sequence: ![vue lifecycle diagram](../images/vue-lifecycle-diagram.png) The following is a snapshot of the report: @@ -36,11 +36,11 @@ The tabbed interface is responsible for loading various modules such as authorsh - **main.js** - sets up plugins and 3rd party components used in the report - [**app.vue**](#app-app-vue) - module that supports the report interface - [**api.js**](#data-loader-api-js) - loading and parsing of the report content -- [**v_summary.vue**](#summary-view-v-summary-vue) - module that supports the summary view -- [**v_authorship.vue**](#authorship-view-v-authorship-vue) - module that supports the authorship tab view -- [**v_zoom.vue**](#zoom-view-v-zoom-vue) - module that supports the zoom tab view -- [**v_ramp.vue**](#ramp-view-v-ramp-vue) - module that supports the ramp chart view -- [**v_segment.vue**](#segment-view-v-segment-vue) - module that supports the code segment view +- [**c_summary.vue**](#summary-view-c-summary-vue) - module that supports the summary view +- [**c_authorship.vue**](#authorship-view-c-authorship-vue) - module that supports the authorship tab view +- [**c_zoom.vue**](#zoom-view-c-zoom-vue) - module that supports the zoom tab view +- [**c_ramp.vue**](#ramp-view-c-ramp-vue) - module that supports the ramp chart view +- [**c_segment.vue**](#segment-view-c-segment-vue) - module that supports the code segment view @@ -58,12 +58,12 @@ This contains the logic for the main VueJS object, `app.vue`, which is the entry Vuex in `store.js` is used to pass the necessary data into the relevant modules. -`v_summary`, `v_authorship`, `v_zoom`, `v_segment`, and `v_ramp` are components embedded into the report and will render the corresponding content based on the data passed into it from Vuex. +`c_summary`, `c_authorship`, `c_zoom`, `c_segment`, and `c_ramp` are components embedded into the report and will render the corresponding content based on the data passed into it from Vuex. ### Loading of report information The main Vue object depends on the `summary.json` data to determine the right `commits.json` files to load into memory. This is handled by `api.js`, which loads the relevant file information from the network files if available; otherwise, a report archive, `archive.zip`, has to be used. -Once the relevant `commit.json` files are loaded, all the repo information will be passed into `v_summary` to be loaded in the summary view as the relevant ramp charts. +Once the relevant `commit.json` files are loaded, all the repo information will be passed into `c_summary` to be loaded in the summary view as the relevant ramp charts. ### Activating additional view modules Most activity or actions should happen within the module itself, but in the case where there is a need to spawn or alter the view of another module, an event is emitted from the first module to the Vuex store, which then handles the data received and passes it along to the relevant modules. @@ -88,9 +88,9 @@ For the basic skeleton of `window.REPOS`, refer to the generated `summary.json` -## Summary view ([v-summary.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-summary.vue)) +## Summary view ([c-summary.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-summary.vue)) -The `v_summary` module is in charge of loading the ramp charts from the corresponding `commits.json`. +The `c_summary` module is in charge of loading the ramp charts from the corresponding `commits.json`. @@ -102,7 +102,7 @@ The commits information is retrieved from the corresponding project folders for -## Authorship view ([v-authorship.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-authorship.vue)) +## Authorship view ([c-authorship.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-authorship.vue)) The authorship module retrieves the relevant information from the corresponding `authorship.json` file if it is not yet loaded. If it has been loaded, the data will be written into `window.REPOS` and be read from there instead. @@ -113,21 +113,21 @@ The files will be filtered, picking only files the selected author has written i -## Zoom view ([v-zoom.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/v-zoom.vue)) +## Zoom view ([c-zoom.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/views/c-zoom.vue)) -The `v_zoom` module is in charge of filtering and displaying the commits from the ramp chart's selected sub-range. +The `c_zoom` module is in charge of filtering and displaying the commits from the ramp chart's selected sub-range. -## Ramp view ([v-ramp.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/v-ramp.vue)) +## Ramp view ([c-ramp.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/c-ramp.vue)) -The `v_ramp` module is responsible for receiving the relevant information from `v_summary` and generating ramp charts that contain ramp slices. +The `c_ramp` module is responsible for receiving the relevant information from `c_summary` and generating ramp charts that contain ramp slices. ### Padding for dates For ramps between the date ranges, the slices will be selected and it will be pre and post padded with empty slices to align the ramp slice between the `sinceDate` and `untilDate`. The ramps will then be rendered with the slices in the right position. -## Segment view ([v-segment.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/v-segment.vue)) +## Segment view ([c-segment.vue](https://github.com/reposense/RepoSense/blob/master/frontend/src/components/c-segment.vue)) -The `v-segment` module is used as a component in `v_authorship`. It separates the code in terms of "touched" and "untouched" segments and only loads each "untouched" segment when it is toggled. +The `c-segment` module is used as a component in `c_authorship`. It separates the code in terms of "touched" and "untouched" segments and only loads each "untouched" segment when it is toggled. diff --git a/docs/dg/settingUp.md b/docs/dg/settingUp.md index b8f4c5a391..73b4df1658 100644 --- a/docs/dg/settingUp.md +++ b/docs/dg/settingUp.md @@ -9,8 +9,8 @@

{{ title }}

**Prerequisites:** -* **JDK `1.8.0_60`** or later ([download :fas-download:](https://www.oracle.com/technetwork/java/javase/downloads/index.html)). -* **npm** `6.0` or later ([download :fas-download:](https://www.npmjs.com/get-npm)). +* **JDK `1.8.0_60`** up to **`17`** ([download :fas-download:](https://www.oracle.com/technetwork/java/javase/downloads/index.html)). +* **Node.js** `14.19.0` to the latest minor version for `16` ([download :fas-download:](https://www.npmjs.com/get-npm)). * **git `2.14`** or later ([download :fas-download:](https://git-scm.com/downloads)). diff --git a/docs/dg/styleGuides.md b/docs/dg/styleGuides.md index ba10040aba..3ac898abcc 100644 --- a/docs/dg/styleGuides.md +++ b/docs/dg/styleGuides.md @@ -38,3 +38,88 @@ return (commitInfos.isEmpty()) To preserve readability, it is recommended that if-else blocks should only be converted to ternary operators if the resultant code can be kept at most 3 lines long (in accordance to the coding standard). + +## Additional Javadoc requirements: +In addition to what has been mentioned in the [**Java** coding standard (SE-EDU)](https://se-education.org/guides/conventions/java/index.html) and [**Google Java Style Guide**](https://google.github.io/styleguide/javaguide.html), we also stipulate the following standards for Javadoc: +* If Javadoc is written for a method, all input parameters should be described in the Javadoc, either in the description with `@code tags` or through `@param` block tags. + * If `@param` block tags are used, they must be used for all parameters. + * This is not necessary (although still recommended) for methods with `@Override` annotations if Javadoc is used. However, if the method that is being overriden is part of your code and has Javadoc, all parameters must be described. + +Negative Examples: +``` +Not okay (Only mentions zoneId parameter): +/** + * Returns a {@link LocalDateTime} object adjusted for timezone given by {@code zoneId}. + */ +public LocalDateTime adjustTimeZone(LocalDateTime sinceDate, ZoneId zoneId) { + //Code here +} + +Not okay (@param tag used only for zoneId) +/** + * Returns a {@link LocalDateTime} object by adjusting {@code sinceDate} + * to the timezone given by {@code zoneId}. + * + * @param zoneId The timezone ID to adjust the sinceDate to. + */ +public LocalDateTime adjustTimeZone(LocalDateTime sinceDate, ZoneId zoneId) { + //Code here +} +``` +Positive Example #1: +``` +Okay (No @param tags): +/** + * Returns a {@link LocalDateTime} object by adjusting {@code sinceDate} + * to the timezone given by {@code zoneId}. + */ +public LocalDateTime adjustTimeZone(LocalDateTime sinceDate, ZoneId zoneId) { + //Code here +} +``` +Positive Example #2: +``` +Okay (@param tags used for all inputs): +/** + * Returns a {@link LocalDateTime} object by adjusting {@code sinceDate} + * to the timezone given by {@code zoneId}. + * + * @param sinceDate The date prior to the timezone conversion. + * @param zoneId The timezone ID to adjust the sinceDate to. + */ +public LocalDateTime adjustTimeZone(LocalDateTime sinceDate, ZoneId zoneId) { + //Code here +} +``` + +* Within the main code, if an exception is thrown in a method (both header and body) for which Javadoc is written, a `@throws` tag must be used to describe how the exception is likely to arise. + * This requirement does not apply to test code. + * One `@throws` tag per unique exception. + * The order of exceptions in the `@throws` tag block should match that of the method's `throws` statement. +``` +Not okay (order of exceptions in tag block and method signature do not match): +/** + * Returns a {@link LocalDateTime} object from {@code dateString}. + * + * @throws ParseException if {@code dateString} cannot be parsed. + * @throws NullPointerException if {@code dateString} is null. + */ +public LocalDateTime parseDate(String dateString) throws NullPointerException, ParseException { + String trimmedString = dateString.toUpperCase(); // NullPointerException may happen here. + // Code here +} + +Should be: +/** + * Returns a {@link LocalDateTime} object from {@code dateString}. + * + * @throws NullPointerException if {@code dateString} is null. + * @throws ParseException if {@code dateString} cannot be parsed. + */ +public LocalDateTime parseDate(String dateString) throws NullPointerException, ParseException { + String trimmedString = dateString.toUpperCase(); // NullPointerException may happen here. + // Code here +} +``` + + diff --git a/docs/dg/workflow.md b/docs/dg/workflow.md index b4c5c2b662..72486bbedd 100644 --- a/docs/dg/workflow.md +++ b/docs/dg/workflow.md @@ -43,8 +43,11 @@ The issues for first timers usually have guidance provided in the comment or hav * Make sure you know our coding standards. {{ embed('Appendix: Coding Standards', 'styleGuides.md', level=2) }} * **Follow [the tutorial](https://se-education.org/guides/tutorials/intellijCodeStyle.html) to configure Intellij to follow our coding style**. -* **This project uses Checkstyle** to check the compliance of Java code. You can use [this document](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use it. In particular, run `gradlew checkstyleMain checkstyleTest checkstyleSystemtest` to check the style of all the relevant Java code. -* **To check Pug files for style errors**, run `npm run lint` from the project root directory. You can use the `npm run lintfix` to automatically fix some of the JavaScript and CSS lint errors. +* **This project uses Checkstyle** to check the compliance of Java code. You can use [this document](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use it. + * In particular, run `gradlew checkstyleAll` to check the style of all the relevant Java code. This will check the Java code in the following order: main code -> test code -> systemtest code. + * If you only want to check the main code, run `gradlew checkstyleMain`. Likewise, for test code, run `gradlew checkstyleTest` and for systemtest code, run `gradlew checkstyleSystemtest`. + * You can also run any of the combination of the above, such as `gradlew checkstyleMain checkstyleTest` or `gradlew checkstyleTest checkstyleSystemtest`. +* **To check Vue files for style errors**, run `gradlew lintFrontend` from the project root directory. You can also run `npm run lintfix` in the `frontend` folder to automatically fix some of the JavaScript and CSS lint errors. diff --git a/docs/diagrams/ReportArchitecture.puml b/docs/diagrams/ReportArchitecture.puml index 3dba760ee4..e125adc255 100644 --- a/docs/diagrams/ReportArchitecture.puml +++ b/docs/diagrams/ReportArchitecture.puml @@ -4,22 +4,22 @@ skinparam monochrome true skinparam Shadowing false rectangle "main.js\n(window.app)" as main -rectangle "v_zoom.vue" as v_zoom -rectangle "v_ramp.vue" as v_ramp -rectangle "v_summary.vue" as v_summary -rectangle "v_authorship.vue" as v_authorship -rectangle "v_segment.vue" as v_segment +rectangle "c_zoom.vue" as c_zoom +rectangle "c_ramp.vue" as c_ramp +rectangle "c_summary.vue" as c_summary +rectangle "c_authorship.vue" as c_authorship +rectangle "c_segment.vue" as c_segment database "api.js\n" as api -main -down-> v_summary -v_summary -down-> v_zoom -v_summary -> v_ramp -v_zoom -> v_ramp +main -down-> c_summary +c_summary -down-> c_zoom +c_summary -> c_ramp +c_zoom -> c_ramp -main -down-> v_authorship -v_authorship -down-> v_segment +main -down-> c_authorship +c_authorship -down-> c_segment api -down--> main : summary.json -api -down-> v_summary : projectName/commits.json -api -down-> v_authorship : projectName/authorship.json +api -down-> c_summary : projectName/commits.json +api -down-> c_authorship : projectName/authorship.json @enduml diff --git a/docs/diagrams/ReportArchitectureAuthorship.puml b/docs/diagrams/ReportArchitectureAuthorship.puml index b01533ad23..4d8a093064 100644 --- a/docs/diagrams/ReportArchitectureAuthorship.puml +++ b/docs/diagrams/ReportArchitectureAuthorship.puml @@ -3,11 +3,11 @@ hide footbox skinparam monochrome true skinparam Shadowing false -Participant ":Summary\n(v_summary.vue)" as summary +Participant ":Summary\n(c_summary.vue)" as summary Participant ":Main\n(window.app)" as main -Participant ":Authorship\n(v_authorship.vue)" as authorship +Participant ":Authorship\n(c_authorship.vue)" as authorship Participant ":API\n(api.js)" as api -Participant ":Segment\n(v_segment.vue)" as segment +Participant ":Segment\n(c_segment.vue)" as segment -> summary : view code icon clicked activate summary diff --git a/docs/diagrams/ReportArchitectureSummary.puml b/docs/diagrams/ReportArchitectureSummary.puml index 8ef34bbb7e..cb6f48079b 100644 --- a/docs/diagrams/ReportArchitectureSummary.puml +++ b/docs/diagrams/ReportArchitectureSummary.puml @@ -4,9 +4,9 @@ skinparam monochrome true skinparam Shadowing false Participant ":Main\n(window.app)" as main -Participant ":Summary\n(v_summary.vue)" as summary +Participant ":Summary\n(c_summary.vue)" as summary Participant ":API\n(api.js)" as api -Participant ":Ramp\n(v_ramp.vue)" as ramp +Participant ":Ramp\n(c_ramp.vue)" as ramp -> main : page load activate main diff --git a/docs/images/choose-vue.png b/docs/images/choose-vue.png index 80b8614330..1f6a7df4a0 100644 Binary files a/docs/images/choose-vue.png and b/docs/images/choose-vue.png differ diff --git a/docs/images/report-architecture.png b/docs/images/report-architecture.png index 50de9f5070..c1ffd491bc 100644 Binary files a/docs/images/report-architecture.png and b/docs/images/report-architecture.png differ diff --git a/docs/images/use-vue.png b/docs/images/use-vue.png index 6c26aa4cf5..04a487c0e0 100644 Binary files a/docs/images/use-vue.png and b/docs/images/use-vue.png differ diff --git a/docs/images/vue-lifecycle-diagram.png b/docs/images/vue-lifecycle-diagram.png index 6fea9f1174..f287cb1064 100644 Binary files a/docs/images/vue-lifecycle-diagram.png and b/docs/images/vue-lifecycle-diagram.png differ diff --git a/docs/index.md b/docs/index.md index 0e045e7305..1106198a9e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Some example insights RepoSense can provide: * Which programmers/teams are falling behind? * How does everyone compare in their front-end coding work over the past two weeks? -* Who are the the top 10 code contributors? +* Who are the top 10 code contributors? diff --git a/docs/ug/author-config.csv b/docs/ug/author-config.csv index a6da44dd66..68ec5c9bf7 100644 --- a/docs/ug/author-config.csv +++ b/docs/ug/author-config.csv @@ -1,4 +1,4 @@ -Repository's Location,Branch,Author's GitHub ID,Author's Emails,Author's Display Name,Author's Git Author Name,Ignore Glob List +Repository's Location,Branch,Author's Git Host ID,Author's Emails,Author's Display Name,Author's Git Author Name,Ignore Glob List https://github.com/reposense/testrepo-Beta.git,master,nbriannl,nbriannl@example.com;nbr@example.com,Nbr,, https://github.com/reposense/testrepo-Beta.git,master,zacharytang,zacharytang@example.com;zac@example.com,Zac,Zachary Tang,src/main** https://github.com/reposense/testrepo-Beta.git,master,April0616,april@example.com,Fan,LAPTOP-7KFM2KSP\User;Fan Yuting, diff --git a/docs/ug/cli.md b/docs/ug/cli.md index e4e9224c18..96a0bf7a84 100644 --- a/docs/ug/cli.md +++ b/docs/ug/cli.md @@ -54,7 +54,7 @@ The section below provides explanations for each of the flags. -* Cannot be used with `--repos`. +* Cannot be used with `--repos`. The `--repos` flag will take precedence over this flag. * If both `--repos` and `--config` are not specified, RepoSense looks for config files in the `./config` directory. @@ -83,6 +83,12 @@ Binary file formats, such as `jpg`, `png`,`exe`,`zip`, `rar`, `docx`, and `pptx` * Alias: `-F` (uppercase F) * Example:`--find-previous-authors` or `-F` + + +* This flag only works on **git `2.23`** or later. +* If an earlier version of **git** is used, RepoSense can still run but this flag will be ignored. + + ### `--help`, `-h` @@ -92,7 +98,7 @@ Binary file formats, such as `jpg`, `png`,`exe`,`zip`, `rar`, `docx`, and `pptx` -Cannot be used with any other flags. +Cannot be used with any other flags. This flag takes precedence over all other flags. @@ -110,6 +116,27 @@ This flag overrides the `Ignore standalone config` field in the CSV config file. +### `--ignore-filesize-limit`, `-I` + +**`--ignore-filesize-limit`**: Specifies that the file size limit (both default and user-defined) should be ignored during the analysis. +* Default: the file size limit is not ignored +* Alias: `-I` +* Example:`--ignore-filesize-limit` or `-I` + + + +All files are subject to a default file size limit or a custom size limit set by the user. Most files should not be +affected by the default size limit. This flag can be useful for including files in your report that are affected by +the size limit. Note that this flag may result in large report sizes and/or slower report generation. + + + + +This flag overrides the `Ignore file size limit` field in the CSV config file. + + + + ### `--last-modified-date`, `-l` **`--last-modified-date`**: Specifies that the last modified date of each line of code should be added to `authorship.json`. @@ -119,7 +146,7 @@ This flag overrides the `Ignore standalone config` field in the CSV config file. -* Cannot be used with `--shallow-cloning`. +* Cannot be used with `--shallow-cloning`. This may result in an incorrect last modified date. * The last modified dates will be in the same timezone specified with the `--timezone` flag. @@ -145,22 +172,23 @@ This flag overrides the `Ignore standalone config` field in the CSV config file. * If both start date and end date are not specified, the date of generating the report will be taken as the end date. -* Cannot be used with both `--since` and `--until`. +* May analyze the incorrect date range if used with `--since d1`. The program will throw a warning. +* Cannot be used with both `--since` and `--until`. The program will throw an exception. -### `--repos`, `-r` +### `--repo`, `--repos`, `-r` -**`--repos REPO_LOCATION`**: Specifies which repositories to analyze. +**`--repo REPO_LOCATION`**: Specifies which repositories to analyze. * Parameter: `REPO_LOCATION` A list of URLs or the disk location of the git repositories to analyze, separated by spaces. * Alias: `-r` * Examples: * `--repos https://github.com/reposense/RepoSense.git` - * `--repos https://github.com/reposense/RepoSense.git c:/myRepose/foo/bar`: analyzes the two specified repos (one remote, one local) and generates one report containing details of both. + * `--repo https://github.com/reposense/RepoSense.git c:/myRepose/foo/bar`: analyzes the two specified repos (one remote, one local) and generates one report containing details of both. -Cannot be used with `--config`. +Cannot be used with `--config`. This flag takes precedence over `--config`. @@ -173,7 +201,7 @@ Cannot be used with `--config`. -Cannot be used with `--last-modified-date`. +Cannot be used with `--last-modified-date`. This may result in an incorrect last modified date. @@ -189,7 +217,8 @@ Cannot be used with `--last-modified-date`. * If the start date is not specified, only commits made one month before the end date (if specified) or the date of generating the report, will be captured and analyzed. -* If `d1` is specified as the start date (`--since d1` or `-s d1`), then the earliest commit date of all repositories will be taken as the since date. +* If `d1` is specified as the start date (`--since d1` or `-s d1`), then the program will search for the earliest commit date of all repositories and use that as the start date. +* If `d1` is specified together with `--period`, then the program will warn that the date range being analyzed may be incorrect. @@ -225,7 +254,7 @@ Note: If the end date is not specified, the date of generating the report will b -Cannot be used with any other flags. +Cannot be used with any other flags. This flag takes precedence over all other flags other than `--help`. diff --git a/docs/ug/configFiles.md b/docs/ug/configFiles.md index 50458eb4b1..c3032b7ad0 100644 --- a/docs/ug/configFiles.md +++ b/docs/ug/configFiles.md @@ -31,7 +31,7 @@ Given below are the details of the various config files used by RepoSense. | Column Name | Explanation | |-------------|-------------| -| Repository's Location {{ mandatory }} | The `GitHub URL` or `Disk Path` to the git repository e.g., `https://github.com/foo/bar.git` or `C:\Users\user\Desktop\GitHub\foo\bar` | +| Repository's Location {{ mandatory }} | The `Remote Repo URL` or `Disk Path` to the git repository e.g., `https://github.com/foo/bar.git` or `C:\Users\user\Desktop\GitHub\foo\bar` | | Branch | The branch to analyze in the target repository e.g., `master`. Default: the default branch of the repo | | File formats*+ | The file extensions to analyze. Binary file formats, such as `png` and `jpg`, will be automatically labelled as the file type `binary` in the generated report. Default: all file formats | | Find Previous Authors | Enter **`yes`** to utilize Git blame's ignore revisions functionality, RepoSense will attempt to blame the line changes caused by commits in the ignore commit list to the previous authors who altered those lines (if available). | @@ -40,12 +40,19 @@ Given below are the details of the various config files used by RepoSense. | Ignore Commits List*+ | The list of commits to ignore during analysis. For accurate results, the commits should be provided with their full hash. Additionally, a range of commits can be specified using the `..` notation e.g. `abc123..def456` (both inclusive). | | Ignore Authors List*+ | The list of authors to ignore during analysis. Authors should be specified by their [Git Author Name](#a-note-about-git-author-name). | | Shallow Cloning | Enter **`yes`** to clone the repository using Git's shallow cloning functionality. This option can significantly reduce the time taken to clone large repositories. However, the option should ideally be disabled for smaller repositories where the `.git` file is smaller than 500 MB, as it would create overhead. | +| File Size Limit+ | Enter a file size limit for the repository in bytes as a single number without units (for a size limit of 1MB for example, enter 1000000). This file size limit will override the default file size limit (500KB). Files exceeding the file size limit will be marked as ignored and only the file name and line count will be reflected in the report. | +| Ignore File Size Limit | Enter **`yes`** to ignore both the default file size limit and the file size limit possibly set by the user in `repo-config.csv`. | +| Skip Ignored File Analysis | Enter **`yes`** to ignore analysis of files exceeding the file size limit entirely. If file analysis is skipped, all information about the file will be omitted from the generated report. This option can significantly improve report generation time. | The Shallow Cloning option is incompatible with the "--last-modified-date" CLI flag. -* **Multi-value column**: multiple values can be entered in this column using a semicolon `;` as the separator. + +If Ignore File Size Limit is yes, the File Size Limit and Skip Ignored File Analysis columns are ignored. + + +* **Multi-value column**: multiple values can be entered in this column using a semicolon `;` as the separator.
+ **Overrideable column**: prepend with `override:` to use entered value(s) instead of value(s) from standalone config. @@ -63,13 +70,15 @@ Optionally, you can use an `author-config.csv` (which should be in the same dire |-------------|-------------| | Repository's Location | Same as `repo-config.csv`. Default: all the repos in `repo-config.csv` | | Branch | The branch to analyze for this author, e.g., `master`. Default: the author will be bound to all the repos in `repo-config.csv` that has the same repo's location, regardless of branch. | -| Author's GitHub ID {{ mandatory }} | GitHub username of the target author, e.g., `JohnDoe` | -| Author's Emails* | Associated Github emails of the author. This can be found in your [GitHub settings](https://github.com/settings/emails). | -| Author's Display Name | The name to display for the author. Default: author's GitHub username. | +| Author's Git Host ID# {{ mandatory }} | Username of the target author's profile on GitHub, GitLab or Bitbucket, e.g.`JohnDoe`. | +| Author's Emails* | Associated emails of the author. For GitHub users, this can be found in your [GitHub settings](https://github.com/settings/emails). | +| Author's Display Name | The name to display for the author. Default: author's username. | | Author's Git Author Name* | The meaning of _Git Author Name_ is explained in [_A note about git author name_](#a-note-about-git-author-name). | | Ignore Glob List* | Files to ignore for this author, in addition to files ignored by the patterns specified in `repo-config.csv`. The path glob syntax is the same as that of Ignore Glob List in `repo-config.csv`. | * **Multi-value column**: multiple values can be entered in this column using a semicolon `;` as the separator. +
+# For backward compatibility, `Author's GitHub ID` is still accepted as the header in place of `Author's Git Host ID`. If `author-config.csv` is not given and the repo has not provided author details in a standalone config file, all the authors of the repositories within the date range specified (if any) will be analyzed. @@ -107,7 +116,7 @@ You can optionally use `report-config.json` to customize report generation by pr Repo owners can provide the following additional information to RepoSense using a config file that we call the **_standalone config file_**: * which files/authors/commits to analyze/omit -* which git and GitHub usernames belong to which authors +* which git and git host usernames belong to which authors * the display of an author To use this feature, add a `_reposense/config.json` to the root of your repo using the format in the example below ([another example](https://github.com/reposense/RepoSense/blob/master/_reposense/config.json)) and **commit it** (reason: RepoSense can see committed code only): @@ -140,11 +149,12 @@ Note: all fields are optional unless specified otherwise. * `formats`: File formats to analyze. Binary file formats, such as `png` and `jpg`, will be automatically labelled as the file type `binary` in the generated report. Default: all file formats * `ignoreCommitList`: The list of commits to ignore during analysis. For accurate results, the commits should be provided with their full hash. Additionally, a range of commits can be specified using the `..` notation e.g. `abc123..def456` (both inclusive). * `ignoreAuthorList`: The list of authors to ignore during analysis. Authors specified in `authors` field or `author-config.csv` will be also be omitted if they are in this list. Authors should be specified by their [Git Author Name](#a-note-about-git-author-name). +* `fileSizeLimit`: A file size limit for the repository in bytes as a single number without units, that will override the default file size limit. If not specified, the default file size limit will continue to be used. **Fields to provide _author-level_ info**:
Note: `authors` field should contain _all_ authors that should be captured in the analysis. -* `githubId`: GitHub username of the author. {{ mandatory }} field. -* `emails`: Associated GitHub emails of the author. This can be found in your [GitHub settings](https://github.com/settings/emails). +* `githubId`: Username of the author. {{ mandatory }} field. +* `emails`: Associated git emails of the author. For GitHub, this can be found in your [GitHub settings](https://github.com/settings/emails). * `displayName`: Name to display on the report for this author. * `authorNames`: Git Author Name(s) used in the author's commits. By default, RepoSense assumes an author would use her GitHub username as the Git username too. The meaning of _Git Author Name_ is explained in [_A note about git author name_](#a-note-about-git-author-name). * `ignoreGlobList`: _Additional_ (i.e. on top of the repo-level `ignoreGlobList`) folders/files to ignore for a specific author. The path glob syntax is specified by the [_glob format_](https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob). In the example above, the actual `ignoreGlobList` for `alice` would be `["about-us/**", "**index.html", "**.css"]`. @@ -166,13 +176,13 @@ Date: Fri Feb 9 19:14:41 2018 +0800 Make some changes to show my new author's name commit e3f699fd4ef128eebce98d5b4e5b3bb06a512f49 -Author: ActualGitHubId +Author: ActualGitHostId Date: Fri Feb 9 19:13:13 2018 +0800 Initial commit ... ``` -`ActualGitHubId` and `ConfiguredAuthorName` are both `Git Author Name` of the same author.
+`ActualGitHostId` and `ConfiguredAuthorName` are both `Git Author Name` of the same author.
To find the author name that you are currently using for your current git repository, run the following command within your git repository: ``` {.no-line-numbers} git config user.name @@ -185,7 +195,7 @@ To set the author name to use a default value you want for future git repositori ``` {.no-line-numbers} git config --global user.name "YOUR_AUTHOR_NAME” ``` -RepoSense expects the Git Author Name to be the same as author's GitHub username. If an author's `Git Author Name` is different from her `GitHub ID`, the `Git Author Name` needs to be specified in the standalone config file. If the author has more than one `Git Author Name`, multiple values can be entered too. +RepoSense expects the Git Author Name to be the same as author's username on the Git hosting platform (GitHub, GitLab, BitBucket). If an author's `Git Author Name` is different from their username on the Git hosting platform, the `Git Author Name` needs to be specified in the standalone config file. If the author has more than one `Git Author Name`, multiple values can be entered too. diff --git a/docs/ug/customizingReports.md b/docs/ug/customizingReports.md index e77b46fe12..d5d5dc0087 100644 --- a/docs/ug/customizingReports.md +++ b/docs/ug/customizingReports.md @@ -46,8 +46,14 @@ To ensure that their PRs are correct, you can use [Netlify _deploy previews_](ht ### Get target repos to provide more info **If feasible, you can also customize the target repos to play well with RepoSense** in the following two ways: -1\. Add a _stand-alone config file_ to the repo to provide more config details to RepoSense. The format of the file is given below. +1\. Add a _standalone config file_ to the repo to provide more config details to RepoSense. The format of the file is given below. {{ embed("Appendix: **Standalone config file format**", "configFiles.md#section-standalone") }} 2\. To have more precise control over which code segment is attributed to which author, authors can annotate their code using `@@author` tags, as explained below. {{ embed("Appendix: **Using `@@author` tags**", "usingAuthorTags.md") }} + + + +In both instances, it is **necessary to commit any changes** for them to be detected by RepoSense. + + diff --git a/docs/ug/generatingReports.md b/docs/ug/generatingReports.md index a6ff1208eb..f4bb88f557 100644 --- a/docs/ug/generatingReports.md +++ b/docs/ug/generatingReports.md @@ -18,6 +18,12 @@ Let's look at different ways to generate RepoSense reports. * **If you don't have Java on your computer or do not wish to run the executable on your computer**, some alternatives are provided in the [_Generating reports remotely_](#generating-reports-remotely) section below. + + +RepoSense is built to analyze any type of git repo, remote or local. It works best when analyzing remote repositories hosted on GitHub, GitLab or BitBucket. +For other types of repositories, external links are disabled. + + ## Generating reports locally diff --git a/docs/ug/repo-config.csv b/docs/ug/repo-config.csv index 1be18b8e6b..eeeae46611 100644 --- a/docs/ug/repo-config.csv +++ b/docs/ug/repo-config.csv @@ -1,5 +1,5 @@ -Repository's Location,Branch,File formats,Ignore Glob List,Ignore standalone config,Ignore Commits List,Ignore Authors List,Shallow Cloning,Find Previous Authors -https://github.com/reposense/testrepo-Alpha.git,master,,,,2fb6b9b2dd9fa40bf0f9815da2cb0ae8731436c7;c5a6dc774e22099cd9ddeb0faff1e75f9cf4f151;cd7f610e0becbdf331d5231887d8010a689f87c7;768015345e70f06add2a8b7d1f901dc07bf70582,,, -https://github.com/reposense/testrepo-Beta.git,master,java;adocs,docs**,yes,,,, -https://github.com/reposense/testrepo-Delta.git,master,html;css,,,,Ahmad Syafiq;Jordan Chong,, -https://github.com/reposense/RepoSense.git,master,,,,,,, +Repository's Location,Branch,File formats,Ignore Glob List,Ignore standalone config,Ignore Commits List,Ignore Authors List,Shallow Cloning,Find Previous Authors,File Size Limit,Ignore File Size Limit,Skip Ignored File Analysis +https://github.com/reposense/testrepo-Alpha.git,master,,,,2fb6b9b2dd9fa40bf0f9815da2cb0ae8731436c7;c5a6dc774e22099cd9ddeb0faff1e75f9cf4f151;cd7f610e0becbdf331d5231887d8010a689f87c7;768015345e70f06add2a8b7d1f901dc07bf70582,,,,10000,, +https://github.com/reposense/testrepo-Beta.git,master,java;adocs,docs**,yes,,,,,,yes, +https://github.com/reposense/testrepo-Delta.git,master,html;css,,,,Ahmad Syafiq;Jordan Chong,,,,,yes +https://github.com/reposense/RepoSense.git,master,,,,,,,,,, diff --git a/docs/ug/troubleshooting.md b/docs/ug/troubleshooting.md index db632d0bf6..ca72c84a91 100644 --- a/docs/ug/troubleshooting.md +++ b/docs/ug/troubleshooting.md @@ -20,7 +20,7 @@ Alternatively, you may choose to configure *RepoSense* to track using your GitHu ### Contribution bar and code panel is empty (despite a non-empty ramp chart) -The contribution bar and code panel records the lines you have authored to the **latest** commit of the repository and branch you are analyzing. As such, it is possible that while you have lots of committed contributions, your final authorship contribution is low. This happens if you have only deleted lines or someone else has overwritten your code and taken authorship for it (currently, RepoSense does not have the functionality to track overwritten lines)..
+The contribution bar and code panel records the lines you have authored to the **latest** commit of the repository and branch you are analyzing. As such, it is possible that while you have lots of committed contributions, your final authorship contribution is low. This happens if you have only deleted lines or someone else has overwritten your code and taken authorship for it (currently, RepoSense does not have the functionality to track overwritten lines).
It is also possible that another user has overridden the authorship of your lines using the [@@author tags](#provide-data-using-author-tags). diff --git a/docs/ug/usingAuthorTags.md b/docs/ug/usingAuthorTags.md index bd1c1e6d69..20bc113fc5 100644 --- a/docs/ug/usingAuthorTags.md +++ b/docs/ug/usingAuthorTags.md @@ -48,7 +48,7 @@ First, RepoSense checks whether the line matches the supported comment formats. RepoSense treats it as a normal line. Else, it continues to check whether the GitHub username is in valid format. If the username is valid, the code till the next start tag, the end tag, or the end of file will be attributed to that author. -Otherwise the code will not be attributed to any author. +Otherwise, the code will not be attributed to any author.
Note: Remember to **commit** the files after the changes. (reason: RepoSense can see committed code only) diff --git a/docs/ug/usingReports.md b/docs/ug/usingReports.md index 483d628e4c..ec0ef9637c 100644 --- a/docs/ug/usingReports.md +++ b/docs/ug/usingReports.md @@ -28,7 +28,6 @@ As a report consists of web pages, it can be viewed using a Web Browser. Here ar 1. Open the `index.html` (in the unzipped report directory) using a browser. 1. If the report was not loaded automatically, click on the `choose file` button in the shown web page, and select the `archive.zip` (in the same directory) manually.
If even the `choose file` button is not showing up, try a different browser. - ## Report structure @@ -39,6 +38,11 @@ Here is an example of how a typical report looks like: The report is divided into two sections: [_**Chart panel**_](#chart-panel) and the [_**Code panel**_](#code-panel). In some situations, the [_**Commits panel**_](#commits-panel) will appear in place of the _code panel_. All three are explained in the sections below. + + +Links to external webpages (repository link, author's profile, blame view, etc.) is only properly supported when RepoSense analyzes a remote repository belonging to GitHub, GitLab or BitBucket. + + ## Chart panel @@ -62,7 +66,9 @@ The `Chart panel` (an example is shown above) contains a series of _ramp chart_ * The ramp's area is proportional to the amount of contribution the author made at that time period. * The position of the right edge of the ramp (perpendicular to the blue bar) represents the period (the day or the week) in which the contribution was made. * Hover the pointer over a ramp to see the total number of lines represented by that ramp. -* Click on the ramp to see on GitHub the list of commits represented by that ramp. +* Click on the ramp to view details about the list of commits represented in the ramp. + * At the commit-level of granularity, it links to the commit in the remote repository. + * At higher levels of granularity, it displays the list of commits in the Code Panel. * To make the comparison between two authors easier, the color of the ramps that represent different authors' contributions at the same time period are the same. * Ramps representing big contributions can overlap with earlier time periods. This represents the possibility that if the work committed during a specific period is big, it could have started at an earlier time period. @@ -97,7 +103,7 @@ The `Tool Bar` at the top of the Chart panel provides a set of configuration opt * `Contribution`: groups will be sorted by the combined contributions within a group, in the order of number of lines added. * `Variance`: groups will be sorted by how far the daily contributions are spread out from their average value among all authors involved. A detailed definition of variance is located [here](https://en.wikipedia.org/wiki/Variance). * `Sort within groups by`: sorting criteria within each group. - * `Title`: each group will be internally sorted by it's title in alphabetical order. + * `Title`: each group will be internally sorted by its title in alphabetical order. * `Contribution`: each group will be internally sorted by individual contributions in the order of number of lines added. * `Variance`: each group will be internally sorted by how far the daily contributions are spread out from their average value by each author into a particular repo. A detailed definition of variance is located [here](https://en.wikipedia.org/wiki/Variance). * `Granularity`: the period of time for which commits are aggregated in the Ramp Chart. @@ -135,8 +141,8 @@ The `Code panel` allows users to see the code attributed to a specific author. C * Select the checkboxes to include files of preferred file extensions. The number right beside the file extension shows the total number of lines written by the author in such file extension files. In contrast, the number inside the parenthesis indicates the number of non-blank lines written by the author. * Clicking the file title toggles the file content. -* Clicking the first icon beside the file title opens the history view of the file on GitHub. -* Clicking the second icon beside the file title opens the blame view of the file on GitHub. +* Clicking the first icon beside the file title opens the history view of the file on the remote repository. +* Clicking the second icon beside the file title opens the blame view of the file on the remote repository. * Code attributed to the author is highlighted in green. * Non-trivial code segments that the selected author does not write are hidden by default, but you can toggle them by clicking on the %%:fas-plus-circle:%% icon. diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 2e886dadff..1d4168e2a5 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -1,31 +1,56 @@ { - "env": { - "browser": true - }, - "extends": [ - "airbnb-base", - // "plugin:vue/base" - "plugin:vue/recommended" + "env": { + "browser": true + }, + "extends": [ + "airbnb-base", + "plugin:vue/recommended", + "@vue/typescript" + ], + "rules": { + "vue/component-definition-name-casing": [ + "error", + "kebab-case" ], - "rules": { - "vue/component-definition-name-casing": ["error", "kebab-case"], - "vue/order-in-components": 0, // Should remove eventually - "vue/require-prop-types": 0, // Should remove eventually - "no-param-reassign": 0, - "arrow-parens": ["error", "always"], - "indent": ["error", 2, { - "MemberExpression": 2, - "CallExpression": { "arguments": 2 }, - "ArrayExpression": 2, - "ignoredNodes": [ - "ConditionalExpression" - ] - }], - "prefer-destructuring": 0, - // "sort-imports": ["error", { "ignoreDeclarationSort": true }], - "func-names": ["error", "as-needed"], - "no-alert": 0, - "linebreak-style": 0, - "max-len": ["error", { "code": 130 }] - } + "vue/order-in-components": 0, + "vue/require-prop-types": 0, + "no-param-reassign": 0, + "arrow-parens": [ + "error", + "always" + ], + "indent": [ + "error", + 2, + { + "MemberExpression": 2, + "CallExpression": { + "arguments": 2 + }, + "ArrayExpression": 2, + "ignoredNodes": [ + "ConditionalExpression" + ] + } + ], + "prefer-destructuring": 0, + "func-names": [ + "error", + "as-needed" + ], + "no-alert": 0, + "linebreak-style": 0, + "max-len": [ + "error", + { + "code": 120 + } + ], + "prefer-object-spread": 0, + "function-call-argument-newline": 0, + "vue/no-computed-properties-in-data": 0 + }, + "parserOptions": { + "parser": "@typescript-eslint/parser" + } } diff --git a/frontend/.pug-lintrc.json b/frontend/.pug-lintrc.json index 74d90e7c83..c1742f2b20 100644 --- a/frontend/.pug-lintrc.json +++ b/frontend/.pug-lintrc.json @@ -17,7 +17,3 @@ "validateDivTags": true, "validateIndentation": 2 } - /** - * TODO - * Add rule for line wraps when available - */ diff --git a/frontend/.stylelintrc.json b/frontend/.stylelintrc.json index 3ee24d6af8..ebef44f98c 100644 --- a/frontend/.stylelintrc.json +++ b/frontend/.stylelintrc.json @@ -2,6 +2,10 @@ "plugins": [ "stylelint-order" ], + "extends": [ + "stylelint-config-recommended-scss", + "stylelint-config-recommended-vue" + ], "rules": { "color-no-invalid-hex": true, "string-no-newline": true, @@ -24,6 +28,14 @@ "selector-list-comma-newline-after": "always", "no-eol-whitespace": true, "order/properties-alphabetical-order": true, - "indentation": 2 + "indentation": 2, + "scss/at-import-partial-extension": null, + "function-no-unknown": null, + "scss/at-import-no-partial-leading-underscore": null, + "no-descending-specificity": null, + "scss/no-global-function-names": null, + "selector-type-no-unknown": null, + "at-rule-no-unknown": null, + "no-duplicate-selectors": null } } diff --git a/frontend/cypress/config/repo-config.csv b/frontend/cypress/config/repo-config.csv index 04a97dc0f7..5edbcc27b6 100644 --- a/frontend/cypress/config/repo-config.csv +++ b/frontend/cypress/config/repo-config.csv @@ -1,3 +1,3 @@ Repository's Location,Branch,File formats,Ignore Glob List,Ignore standalone config,Ignore Commits List,Ignore Authors List,Shallow Cloning,Find Previous Authors -https://github.com/reposense/RepoSense.git,master,,,,,,, +https://github.com/reposense/RepoSense.git,cypress,,,,,,, https://github.com/reposense/testrepo-Empty.git,master,,,,,,, diff --git a/frontend/cypress/package-lock.json b/frontend/cypress/package-lock.json index 3a06fa81a3..3f9439deb6 100644 --- a/frontend/cypress/package-lock.json +++ b/frontend/cypress/package-lock.json @@ -2,6 +2,13 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, "@cypress/request": { "version": "2.88.10", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz", @@ -50,9 +57,9 @@ } }, "@types/node": { - "version": "14.18.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.12.tgz", - "integrity": "sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==", + "version": "14.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.13.tgz", + "integrity": "sha512-Z6/KzgyWOga3pJNS42A+zayjhPbf2zM3hegRQaOPnLOzEi86VV++6FLDWgR1LGrVCRufP/ph2daa3tEa5br1zA==", "dev": true }, "@types/sinonjs__fake-timers": { @@ -68,9 +75,9 @@ "dev": true }, "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", "dev": true, "optional": true, "requires": { @@ -294,12 +301,12 @@ } }, "cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", "dev": true, "requires": { - "colors": "1.4.0", + "@colors/colors": "1.5.0", "string-width": "^4.2.0" } }, @@ -334,13 +341,6 @@ "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "optional": true - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -386,9 +386,9 @@ } }, "cypress": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.5.1.tgz", - "integrity": "sha512-H7lUWB3Svr44gz1rNnj941xmdsCljXoJa2cDneAltjI9leKLMQLm30x6jLlpQ730tiVtIbW5HdUmBzPzwzfUQg==", + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.5.4.tgz", + "integrity": "sha512-6AyJAD8phe7IMvOL4oBsI9puRNOWxZjl8z1lgixJMcgJ85JJmyKeP6uqNA0dI1z14lmJ7Qklf2MOgP/xdAqJ/Q==", "dev": true, "requires": { "@cypress/request": "^2.88.10", @@ -423,7 +423,7 @@ "listr2": "^3.8.3", "lodash": "^4.17.21", "log-symbols": "^4.0.0", - "minimist": "^1.2.5", + "minimist": "^1.2.6", "ospath": "^1.2.2", "pretty-bytes": "^5.6.0", "proxy-from-env": "1.0.0", @@ -445,26 +445,18 @@ } }, "dayjs": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.8.tgz", - "integrity": "sha512-wbNwDfBHHur9UOzNUjeKUOJ0fCb0a52Wx0xInmQ7Y8FstyajiV1NmK1e00cxsr9YrE9r7yAChE0VvpuY5Rnlow==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.1.tgz", + "integrity": "sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA==", "dev": true }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "delayed-stream": { @@ -673,9 +665,9 @@ } }, "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, "has-flag": { @@ -932,18 +924,18 @@ "dev": true }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -962,15 +954,15 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "npm-run-path": { @@ -1141,9 +1133,9 @@ "dev": true }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -1265,9 +1257,9 @@ } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, "tunnel-agent": { diff --git a/frontend/cypress/tests/codeView/codeView_filterGlob.js b/frontend/cypress/tests/codeView/codeView_filterGlob.js new file mode 100644 index 0000000000..a8109b084f --- /dev/null +++ b/frontend/cypress/tests/codeView/codeView_filterGlob.js @@ -0,0 +1,198 @@ +describe('filter glob', () => { + it('check filter glob radio button is clickable', () => { + // open the code panel + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + // click on filter glob radio button + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + // filter by file type should be unchecked + cy.get('.radio-button--checkbox') + .should('not.be.checked'); + }); + + it('check no filter glob input should show all file types by default', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + // the contents of all the files should be visible + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + }); + + it('check filter glob input should be in focus after click', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + // click on input box + cy.get('#search') + .click() + .should('have.focus'); + }); + + it('check filter glob input should have default empty value', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + cy.get('#search') + .should('have.value', ''); + }); + + it('check deleting previously searched input to filter empty input by enter should show all file types', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + // enter some input + cy.get('#search') + .type('an input'); + + // submit some input + cy.get('#search') + .type('{enter}'); + + // delete previous input + cy.get('#search') + .clear(); + + // enter on empty input + cy.get('#search') + .type('{enter}'); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + }); + + it('check deleting previously searched input to filter empty input by clicking should show all file types', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + cy.get('#search') + .type('an input'); + + cy.get('#submit-button') + .click(); + + cy.get('#search') + .clear(); + + // click 'Filter' on empty input + cy.get('#submit-button') + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + }); + + it('check request to filter invalid glob by enter should not show any files', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + + cy.get('#search') + .type('invalid glob'); + + cy.get('#search') + .type('{enter}'); + + // no file should be shown + cy.get('#tab-authorship .files') + .should('not.be.visible'); + }); + + it('check request to filter invalid glob by clicking should not show any files', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + cy.get('#tab-authorship .files', { timeout: 90000 }) + .should('be.visible'); + + cy.get('#search') + .type('invalid glob'); + + cy.get('#submit-button') + .click(); + + cy.get('#tab-authorship .files') + .should('not.be.visible'); + }); + + it('check filter glob should only show files with that extension', () => { + cy.get('.icon-button.fa-code') + .should('be.visible') + .first() + .click(); + + cy.get('.radio-button--search') + .should('be.visible') + .click(); + + // try java + cy.get('#search') + .type('*java'); + + cy.get('#submit-button') + .click(); + + cy.get('#tab-authorship .files').then(($files) => { + // check if there is any file with .java extension + if ($files.hasClass('path')) { + // check each file for .java extension + cy.get('.title > .path > span') + .then(($spans) => { + $spans.toArray().forEach((span) => { + cy.wrap(span).contains('.java'); + }); + }); + } + }); + }); +}); diff --git a/frontend/cypress/tests/codeView/codeView_hideFileDetails.js b/frontend/cypress/tests/codeView/codeView_hideFileDetails.js index 8122cd8f26..d634e7d976 100644 --- a/frontend/cypress/tests/codeView/codeView_hideFileDetails.js +++ b/frontend/cypress/tests/codeView/codeView_hideFileDetails.js @@ -45,7 +45,7 @@ describe('hide all file details', () => { .should('contain.text', 'show all file details'); // open contents of the first file - cy.get('#tab-authorship .title .path') + cy.get('#tab-authorship .title .caret') .should('be.visible') .first() .click(); diff --git a/frontend/cypress/tests/codeView/codeView_switchAuthorship.js b/frontend/cypress/tests/codeView/codeView_switchAuthorship.js index f1e4de1b5f..501edcc1cf 100644 --- a/frontend/cypress/tests/codeView/codeView_switchAuthorship.js +++ b/frontend/cypress/tests/codeView/codeView_switchAuthorship.js @@ -78,7 +78,6 @@ describe('switch authorship', () => { }); cy.get('#tab-authorship > .files > .file > .title > .path') - .children('span') .first() .then(($span) => { firstFilename = $span.text(); @@ -106,7 +105,6 @@ describe('switch authorship', () => { }); cy.get('#tab-authorship > .files > .file > .title > .path') - .children('span') .first() .should(($span) => { const lastFilename = $span.text(); diff --git a/frontend/cypress/tests/zoomView/zoomView_selectFileTypes.js b/frontend/cypress/tests/zoomView/zoomView_selectFileTypes.js index fb35b79315..db2d01c9dc 100644 --- a/frontend/cypress/tests/zoomView/zoomView_selectFileTypes.js +++ b/frontend/cypress/tests/zoomView/zoomView_selectFileTypes.js @@ -28,7 +28,7 @@ describe('check file types ', () => { .should('not.exist'); }); - it('uncheck file type should uncheck all option and not show legend', () => { + it('uncheck file type should uncheck all option', () => { // Assumptions: the first author of the first repo // committed .java, .js and .gradle files. cy.get('.icon-button.fa-list-ul') @@ -44,10 +44,67 @@ describe('check file types ', () => { .uncheck() .should('not.be.checked'); - cy.get('.zoom__day > .commit-message > .fileTypeLabel') - .should('not.contain.text', 'java'); + cy.get('#tab-zoom .fileTypes input[value="all"]') + .should('not.be.checked'); + }); + + it('a commit should not be seen when all of its file types are unchecked', () => { + // Assumptions: the third commit (19e3294) of the first author of the first repo + // contains changes in only .java files. + cy.get('.icon-button.fa-list-ul') + .should('be.visible') + .first() + .click(); + + cy.get('.zoom__day > .commit-message') + .eq(2) + .within(() => { + cy.get('.hash') + .should('have.text', '19e3294'); + cy.get('.fileTypeLabel') + .should('have.text', 'java'); + }); + + cy.get('#tab-zoom .fileTypes input[value="java"]') + .uncheck() + .should('not.be.checked'); + + cy.get('.zoom__day > .commit-message') + .should('not.contain.text', '19e3294'); + }); + + it.only('unchecked file type label can still remain in a commit of multiple file types', () => { + // Assumptions: the sixth commit (5ab0322) of the first author of the first repo + // contains changes in both .java and .md files. + cy.get('.icon-button.fa-list-ul') + .should('be.visible') + .first() + .click(); + + cy.get('.zoom__day > .commit-message') + .eq(5) + .within(() => { + cy.get('.hash') + .should('have.text', '5ab0322'); + cy.get('.fileTypeLabel') + .should('contain.text', 'java') + .should('contain.text', 'md'); + }); + + cy.get('#tab-zoom .fileTypes input[value="java"]') + .uncheck() + .should('not.be.checked'); - cy.get('.zoom__day > .commit-message > .fileTypeLabel') - .should('contain.text', 'gradle'); + cy.get('.zoom__day > .commit-message') + // note that the same commit is now of second order since other commits + // were filtered out + .eq(2) + .within(() => { + cy.get('.hash') + .should('have.text', '5ab0322'); + cy.get('.fileTypeLabel') + .should('contain.text', 'java') + .should('contain.text', 'md'); + }); }); }); diff --git a/frontend/package.json b/frontend/package.json index ad2a21d80b..3ff1e16152 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,66 +2,74 @@ "name": "reposense", "version": "1.0.0", "description": "[![Build Status](https://travis-ci.org/reposense/RepoSense.svg?branch=master)](https://travis-ci.org/reposense/RepoSense) [![Build status](https://ci.appveyor.com/api/projects/status/gsbkj5qby3pjd6nw/branch/master?svg=true)](https://ci.appveyor.com/project/eugenepeh/reposense/branch/master)", - "main": "index.js", - "directories": { - "doc": "docs" - }, + "author": "", "scripts": { "serve": "vue-cli-service serve", - "serveOpen": "vue-cli-service serve --open", - "lint": "eslint src/**/*.{js,vue} cypress/tests/**/*.js cypress/support.js && stylelint ./src/**/*.{vue,scss} && npm run puglint", - "lintfix": "eslint --fix src/**/*.{js,vue} cypress/tests/**/*.js cypress/support.js && stylelint --fix ./src/**/*.{vue,scss}", - "puglint": "pug-lint-vue src", "build": "vue-cli-service build", - "devbuild": "vue-cli-service build --mode development" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/reposense/RepoSense.git" - }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/reposense/RepoSense/issues" + "lint": "eslint src/**/*.{ts,js,vue} cypress/tests/**/*.js cypress/support.js && stylelint ./src/**/*.{vue,scss} && npm run puglint", + "devbuild": "vue-cli-service build --mode development", + "lintfix": "eslint --fix src/**/*.{ts,js,vue} cypress/tests/**/*.js cypress/support.js && stylelint --fix ./src/**/*.{vue,scss}", + "puglint": "pug-lint-vue src", + "serveOpen": "vue-cli-service serve --open" }, - "homepage": "https://github.com/reposense/RepoSense#readme", + "main": "index.js", "dependencies": { "@fontsource/titillium-web": "^4.5.3", - "@fortawesome/fontawesome-svg-core": "^1.3.0", + "@fortawesome/fontawesome-svg-core": "^6.0.0", "@fortawesome/free-brands-svg-icons": "^6.0.0", "@fortawesome/free-solid-svg-icons": "^6.0.0", "@fortawesome/vue-fontawesome": "^3.0.0-5", "core-js": "^3.6.5", "highlight.js": "^10.5.0", "jszip": "^3.5.0", - "minimatch": "^3.0.4", + "minimatch": "^5.0.1", "muicss": "^0.10.3", "normalize.css": "^8.0.1", "pug-lint-vue": "^0.4.0", "seedrandom": "^3.0.5", "vue": "^3.2.31", "vue-loading-overlay": "^5.0.3", + "vue-observe-visibility": "^1.0.0", "vuex": "^4.0.2" }, "devDependencies": { - "@vue/cli-plugin-babel": "~4.5.0", - "@vue/cli-plugin-eslint": "~4.5.0", - "@vue/cli-service": "~4.5.15", + "@babel/eslint-parser": "^7.17.0", + "@typescript-eslint/eslint-plugin": "^5.18.0", + "@typescript-eslint/parser": "^5.18.0", + "@vue/cli-plugin-babel": "^5.0.4", + "@vue/cli-plugin-eslint": "^5.0.4", + "@vue/cli-plugin-typescript": "^5.0.4", + "@vue/cli-service": "^5.0.4", "@vue/compiler-sfc": "^3.2.30", - "babel-eslint": "^10.1.0", - "eslint": "^6.8.0", - "eslint-config-airbnb-base": "^13.0.0", - "eslint-plugin-import": "^2.13.0", - "eslint-plugin-vue": "^7.4.1", - "node-sass": "^5.0.0", + "@vue/eslint-config-typescript": "^10.0.0", + "eslint": "^8.14.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-vue": "^8.4.1", + "node-sass": "^7.0.3", + "postcss-html": "^1.4.1", "pug": "^3.0.2", "pug-plain-loader": "^1.1.0", "sass": "^1.32.4", - "sass-loader": "^10.1.1", - "stylelint": "^10.1.0", - "stylelint-config-recommended-scss": "^4.2.0", - "stylelint-order": "^3.0.1", - "stylelint-scss": "^3.18.0", - "stylelint-webpack-plugin": "^2.1.1" + "sass-loader": "^12.6.0", + "stylelint": "^14.7.1", + "stylelint-config-recommended-scss": "^6.0.0", + "stylelint-config-recommended-vue": "^1.4.0", + "stylelint-order": "^5.0.0", + "stylelint-scss": "^4.2.0", + "stylelint-webpack-plugin": "^3.2.0", + "typescript": "^4.5.5" + }, + "bugs": { + "url": "https://github.com/reposense/RepoSense/issues" + }, + "directories": { + "doc": "docs" + }, + "homepage": "https://github.com/reposense/RepoSense#readme", + "license": "ISC", + "repository": { + "type": "git", + "url": "git+https://github.com/reposense/RepoSense.git" } } diff --git a/frontend/src/app.vue b/frontend/src/app.vue index e2fce5eb64..2217d97790 100644 --- a/frontend/src/app.vue +++ b/frontend/src/app.vue @@ -1,10 +1,8 @@ - - diff --git a/frontend/src/components/v-summary-charts.vue b/frontend/src/components/c-summary-charts.vue similarity index 85% rename from frontend/src/components/v-summary-charts.vue rename to frontend/src/components/c-summary-charts.vue index 956a510e18..6e90bbee3f 100644 --- a/frontend/src/components/v-summary-charts.vue +++ b/frontend/src/components/c-summary-charts.vue @@ -38,18 +38,20 @@ span.tooltip-text Click to expand group a( v-if="filterGroupSelection === 'groupByRepos'", + v-bind:class="!isBrokenLink(getRepoLink(repo[0])) ? '' : 'broken-link'", v-bind:href="getRepoLink(repo[0])", target="_blank" ) .tooltip - font-awesome-icon.icon-button(:icon="['fab', 'github']") - span.tooltip-text Click to view group's repo + font-awesome-icon.icon-button(:icon="getRepoIcon(repo[0])") + span.tooltip-text {{getGroupRepoLinkMessage(repo[0])}} a( v-else-if="filterGroupSelection === 'groupByAuthors'", - v-bind:href="getAuthorProfileLink(repo[0].name)", target="_blank" + v-bind:class="!isBrokenLink(getAuthorProfileLink(repo[0], repo[0].name)) ? '' : 'broken-link'", + v-bind:href="getAuthorProfileLink(repo[0], repo[0].name)", target="_blank" ) .tooltip font-awesome-icon.icon-button(icon="user") - span.tooltip-text Click to view author's profile + span.tooltip-text {{getAuthorProfileLinkMessage(repo[0])}} template(v-if="isGroupMerged(getGroupName(repo))") a( v-if="filterGroupSelection !== 'groupByAuthors'", @@ -72,9 +74,10 @@ v-bind:class="{ 'active-icon': isSelectedTab(repo[0].name, repo[0].repoName, 'zoom', true) }" ) span.tooltip-text Click to view breakdown of commits - .summary-chart__title--percentile( + .tooltip.summary-chart__title--percentile( v-if="sortGroupSelection.includes('totalCommits')" - ) {{ getPercentile(i) }} % + ) {{ getPercentile(i) }} %  + span.tooltip-text.right-aligned {{ getPercentileExplanation(i) }} .summary-charts__fileType--breakdown(v-if="filterBreakdown") template(v-if="filterGroupSelection !== 'groupByNone'") .summary-charts__fileType--breakdown__legend( @@ -101,18 +104,20 @@ .summary-chart__title--contribution.mini-font [{{ user.checkedFileTypeContribution }} lines] a( v-if="filterGroupSelection !== 'groupByRepos'", + v-bind:class="!isBrokenLink(getRepoLink(repo[j])) ? '' : 'broken-link'", v-bind:href="getRepoLink(repo[j])", target="_blank" ) .tooltip - font-awesome-icon.icon-button(:icon="['fab', 'github']") - span.tooltip-text Click to view repo + font-awesome-icon.icon-button(:icon="getRepoIcon(repo[0])") + span.tooltip-text {{getRepoLinkMessage(repo[j])}} a( v-if="filterGroupSelection !== 'groupByAuthors'", - v-bind:href="getAuthorProfileLink(repo[j].name)", target="_blank" + v-bind:class="!isBrokenLink(getAuthorProfileLink(repo[j], repo[j].name)) ? '' : 'broken-link'", + v-bind:href="getAuthorProfileLink(repo[j], repo[j].name)", target="_blank" ) .tooltip font-awesome-icon.icon-button(icon="user") - span.tooltip-text Click to view author's profile + span.tooltip-text {{getAuthorProfileLinkMessage(repo[j])}} a( onclick="deactivateAllOverlays()", v-on:click="openTabAuthorship(user, repo, j, isGroupMerged(getGroupName(repo)))" @@ -133,14 +138,15 @@ v-bind:class="{ 'active-icon': isSelectedTab(user.name, user.repoName, 'zoom', false) }" ) span.tooltip-text Click to view breakdown of commits - .summary-chart__title--percentile( + .tooltip.summary-chart__title--percentile( v-if="filterGroupSelection === 'groupByNone' && sortGroupSelection.includes('totalCommits')" - ) {{ getPercentile(j) }} % + ) {{ getPercentile(j) }} %  + span.tooltip-text.right-aligned {{ getPercentileExplanation(j) }} .summary-chart__ramp( v-on:click="openTabZoomSubrange(user, $event, isGroupMerged(getGroupName(repo)))" ) - v-ramp( + c-ramp( v-bind:groupby="filterGroupSelection", v-bind:user="user", v-bind:tframe="filterTimeFrame", @@ -178,12 +184,14 @@