diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..baa6e1d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,147 @@
+# trunk-ignore-all(checkov/CKV2_GHA_1)
+# This is a basic workflow to help you get started with Actions
+
+ name: build
+ # Controls when the workflow will run
+ on:
+ # Triggers after test.yml
+ # workflow_run:
+ # workflows: [functionality]
+ # types:
+ # - completed
+ push:
+ tags:
+ - "**"
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+ # A workflow run is made up of one or more jobs that can run sequentially or in parallel
+ jobs:
+ #Job1
+ build:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+ # outputs:
+ # cache-key: ${{ steps.build-script.outputs.cache_key }}
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v2
+ - uses: actions/setup-go@v2
+ with:
+ go-version: '1.20.0'
+
+ # Runs a set of commands using the runners shell
+ - name: build-script
+ id: build-script
+ run: |
+ cd ${{ github.workspace }}
+ mkdir bin
+ mkdir bin/flowcat-darwin-arm64
+ mkdir bin/flowcat-linux-386
+ mkdir bin/flowcat-linux-amd64
+ go test release_test.go
+ if [ `echo $?` -ne 0 ]; then exit 1; fi
+ ls bin/flowcat-darwin-arm64/
+ # echo "${{ hashFiles('bin/flowcat-darwin-arm64/**') }}"
+ # echo "cache_key=${{ hashFiles('bin/flowcat-darwin-arm64/**') }}" >> $GITHUB_OUTPUT
+
+ - name: upload-darwin-arm64-cache
+ id: darwin-arm64-cache
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ bin
+ bin/*
+ bin/flowcat-darwin-arm64/flowcat
+ key: ${{ github.sha }}
+
+ - name: upload-linux-386-cache
+ id: linux-386-cache
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ bin
+ bin/*
+ bin/flowcat-linux-386/flowcat
+ key: ${{ github.sha }}
+
+ - name: upload-linux-amd64-cache
+ id: linux-amd64-cache
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ bin
+ bin/*
+ bin/flowcat-linux-amd64/flowcat
+ key: ${{ github.sha }}
+
+
+ release:
+ name: "Release"
+ needs: [build]
+
+ runs-on: "ubuntu-latest"
+
+ steps:
+ - name: get-cache-key
+ env:
+ cache_key: test
+ run: echo "$cache_key"
+
+ - name: get-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ bin
+ bin/*
+ bin/flowcat-darwin-arm64/flowcat
+ key: ${{ github.sha }}
+ #key: test
+
+ - name: "Determine tag"
+ run: echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
+
+ - name: "Create release"
+ uses: "actions/github-script@v6"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const fs = require('fs');
+ try {
+ const response = await github.rest.repos.createRelease({
+ draft: true,
+ generate_release_notes: true,
+ name: process.env.RELEASE_TAG,
+ owner: context.repo.owner,
+ prerelease: false,
+ repo: context.repo.repo,
+ tag_name: process.env.RELEASE_TAG,
+ });
+ await github.rest.repos.uploadReleaseAsset({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ release_id: response.data.id,
+ name: "flowcat-darwin-arm64",
+ data: await fs.readFileSync("bin/flowcat-darwin-arm64/flowcat")
+ });
+ await github.rest.repos.uploadReleaseAsset({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ release_id: response.data.id,
+ name: "flowcat-linux-386",
+ data: await fs.readFileSync("bin/flowcat-linux-386/flowcat")
+ });
+ await github.rest.repos.uploadReleaseAsset({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ release_id: response.data.id,
+ name: "flowcat-linux-amd64",
+ data: await fs.readFileSync("bin/flowcat-linux-amd64/flowcat")
+ });
+ core.exportVariable('RELEASE_ID', response.data.id);
+ core.exportVariable('RELEASE_UPLOAD_URL', response.data.upload_url);
+ } catch (error) {
+ core.setFailed(error.message);
+ }
+
+
diff --git a/.github/workflows/darwin-arm64 build and functionality.yml b/.github/workflows/darwin-arm64 build and functionality.yml
deleted file mode 100644
index bb1649c..0000000
--- a/.github/workflows/darwin-arm64 build and functionality.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
- name: linux-amd64 build and functionality
- # Controls when the workflow will run
- on:
- # Triggers after linux-386 build completes
- workflow_run:
- workflows: [darwin-arm64 build and functionality]
- types:
- - completed
- # pull_request:
- # branches: [ "*" ]
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
- # A workflow run is made up of one or more jobs that can run sequentially or in parallel
- jobs:
- #Job1
- build:
- # The type of runner that the job will run on
- runs-on: ubuntu-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
- - uses: actions/setup-go@v2
- with:
- go-version: '^1.20.0'
- #with:
- # The Go version to download (if necessary) and use. Supports semver spec and ranges.
- #go-version: # optional
- # Whether to download only stable versions
- #stable: # optional, default is true
- # Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user.
- #token: # optional, default is ${{ github.token }}
-
- # Runs a single command using the runners shell
- #- name: Run a one-line script
- # run: echo Hello, world!
-
- # Runs a set of commands using the runners shell
- - name: build-script
- run: |
- cd ${{ github.workspace }}
- cd tests
- sh -e ./test_runner.sh darwin-arm64
- if [ `echo $?` -ne 0 ]; then exit 1; fi
-
- - uses: stefanzweifel/git-auto-commit-action@v4
- with:
- # Optional, but recommended
- commit_message: Automatic Binary Builds
-
-
- # Optional. Used by `git-commit`.
- # See https://git-scm.com/docs/git-commit#_options
- commit_options: --no-verify --signoff
-
- # Optional glob pattern of files which should be added to the commit
- # Defaults to all (.)
- # See the `pathspec`-documentation for git
- # - https://git-scm.com/docs/git-add#Documentation/git-add.txt-ltpathspecgt82308203
- # - https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec
- file_pattern: bin/*
-
- # Optional. Used by `git-status`
- # See https://git-scm.com/docs/git-status#_options
- status_options: --untracked-files=all
-
- # Optional. Used by `git-push`
- # See https://git-scm.com/docs/git-push#_options
- push_options: --force
-
- # Optional. Disable dirty check and always try to create a commit and push
- skip_dirty_check: false
-
- # Optional. Skip internal call to `git fetch`
- skip_fetch: true
-
- # Optional. Skip internal call to `git checkout`
- skip_checkout: true
-
- # Optional. Prevents the shell from expanding filenames.
- # Details: https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
- disable_globbing: true
diff --git a/.github/workflows/linux-386 build and functionality.yml b/.github/workflows/linux-386 build and functionality.yml
deleted file mode 100644
index d653d74..0000000
--- a/.github/workflows/linux-386 build and functionality.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
- name: linux-386 build and functionality
- # Controls when the workflow will run
- on:
- # Triggers after entry workflow "flowcat"
- push:
- branches: [ "master" ]
- # pull_request:
- # branches: [ "*" ]
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
- # A workflow run is made up of one or more jobs that can run sequentially or in parallel
- jobs:
- #Job1
- build:
- # The type of runner that the job will run on
- runs-on: ubuntu-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
- - uses: actions/setup-go@v2
- with:
- go-version: '^1.20.0'
- #with:
- # The Go version to download (if necessary) and use. Supports semver spec and ranges.
- #go-version: # optional
- # Whether to download only stable versions
- #stable: # optional, default is true
- # Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user.
- #token: # optional, default is ${{ github.token }}
-
- # Runs a single command using the runners shell
- #- name: Run a one-line script
- # run: echo Hello, world!
-
- # Runs a set of commands using the runners shell
- - name: build-script
- run: |
- cd ${{ github.workspace }}
- cd tests
- sh -e ./test_runner.sh linux-386
- if [ `echo $?` -ne 0 ]; then exit 1; fi
-
- - uses: stefanzweifel/git-auto-commit-action@v4
- with:
- # Optional, but recommended
- commit_message: Automatic Binary Builds
-
-
- # Optional. Used by `git-commit`.
- # See https://git-scm.com/docs/git-commit#_options
- commit_options: --no-verify --signoff
-
- # Optional glob pattern of files which should be added to the commit
- # Defaults to all (.)
- # See the `pathspec`-documentation for git
- # - https://git-scm.com/docs/git-add#Documentation/git-add.txt-ltpathspecgt82308203
- # - https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec
- file_pattern: bin/*
-
- # Optional. Used by `git-status`
- # See https://git-scm.com/docs/git-status#_options
- status_options: --untracked-files=all
-
- # Optional. Used by `git-push`
- # See https://git-scm.com/docs/git-push#_options
- push_options: --force
-
- # Optional. Disable dirty check and always try to create a commit and push
- skip_dirty_check: false
-
- # Optional. Skip internal call to `git fetch`
- skip_fetch: true
-
- # Optional. Skip internal call to `git checkout`
- skip_checkout: true
-
- # Optional. Prevents the shell from expanding filenames.
- # Details: https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
- disable_globbing: true
\ No newline at end of file
diff --git a/.github/workflows/linux-amd64 build and functionality.yml b/.github/workflows/linux-amd64 build and functionality.yml
deleted file mode 100644
index 87224bb..0000000
--- a/.github/workflows/linux-amd64 build and functionality.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
- name: linux-amd64 build and functionality
- # Controls when the workflow will run
- on:
- # Triggers after linux-386 build completes
- workflow_run:
- workflows: [linux-386 build and functionality]
- types:
- - completed
- # pull_request:
- # branches: [ "*" ]
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
- # A workflow run is made up of one or more jobs that can run sequentially or in parallel
- jobs:
- #Job1
- build:
- # The type of runner that the job will run on
- runs-on: ubuntu-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
- - uses: actions/setup-go@v2
- with:
- go-version: '^1.20.0'
- #with:
- # The Go version to download (if necessary) and use. Supports semver spec and ranges.
- #go-version: # optional
- # Whether to download only stable versions
- #stable: # optional, default is true
- # Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user.
- #token: # optional, default is ${{ github.token }}
-
- # Runs a single command using the runners shell
- #- name: Run a one-line script
- # run: echo Hello, world!
-
- # Runs a set of commands using the runners shell
- - name: build-script
- run: |
- cd ${{ github.workspace }}
- cd tests
- sh -e ./test_runner.sh linux-amd64
- if [ `echo $?` -ne 0 ]; then exit 1; fi
-
- - uses: stefanzweifel/git-auto-commit-action@v4
- with:
- # Optional, but recommended
- commit_message: Automatic Binary Builds
-
-
- # Optional. Used by `git-commit`.
- # See https://git-scm.com/docs/git-commit#_options
- commit_options: --no-verify --signoff
-
- # Optional glob pattern of files which should be added to the commit
- # Defaults to all (.)
- # See the `pathspec`-documentation for git
- # - https://git-scm.com/docs/git-add#Documentation/git-add.txt-ltpathspecgt82308203
- # - https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec
- file_pattern: bin/*
-
- # Optional. Used by `git-status`
- # See https://git-scm.com/docs/git-status#_options
- status_options: --untracked-files=all
-
- # Optional. Used by `git-push`
- # See https://git-scm.com/docs/git-push#_options
- push_options: --force
-
- # Optional. Disable dirty check and always try to create a commit and push
- skip_dirty_check: false
-
- # Optional. Skip internal call to `git fetch`
- skip_fetch: true
-
- # Optional. Skip internal call to `git checkout`
- skip_checkout: true
-
- # Optional. Prevents the shell from expanding filenames.
- # Details: https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
- disable_globbing: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..d5721eb
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,43 @@
+# trunk-ignore-all(checkov/CKV2_GHA_1)
+# builds binaries and runs go test to make sure functionality works as expected
+
+name: functionality
+# Controls when the workflow will run
+on:
+ # Triggers after linux-386 build completes
+ # workflow_run:
+ # workflows: [darwin-arm64 build and functionality]
+ # types:
+ # - completed
+ push:
+ branches: [ "*" ]
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ #Job1
+ build:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v4
+ - uses: actions/setup-go@v4
+ with:
+ go-version: '1.20.0'
+ #with:
+ # The Go version to download (if necessary) and use. Supports semver spec and ranges.
+ #go-version: # optional
+ # Whether to download only stable versions
+ #stable: # optional, default is true
+ # Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user.
+ #token: # optional, default is ${{ github.token }}
+
+ # Runs a set of commands using the runners shell
+ - name: build-script
+ run: |
+ cd ${{ github.workspace }}
+ /opt/hostedtoolcache/go/1.20.0/x64/bin/go test -v *.go
+ if [ `echo $?` -ne 0 ]; then exit 1; fi
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f9f588c..323a734 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
go.work
flowcat
todo
+bin/*
+tests/*
diff --git a/README.md b/README.md
index 4f0026a..c25131c 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# flowcat 3.0.0
+# flowcat v4.0.0
-## Flowcat helps developers bring their todo tasks forward to the user so you don't need to waste time looking for them. It provides a clear overview of your tasks and allows you to stay focused on your work. You can also output to a file for planning purposes or to separate tasks into different categories.
+## Flowcat helps developers bring their todo tasks forward to the user so you don't need to waste time looking for them. It provides a clear overview of your tasks and allows you to stay focused on your work. You can also output to a file for planning purposes or to separate tasks into different categories
@@ -57,14 +57,11 @@ Options for Flowcat:
### SETUP
#### Installation
-Download the appropriate version for your system below then put the flowcat binary for your OS in one of your userpaths such as /usr/local/bin/, /bin/, /sbin/ or another path
+Download the appropriate version for your system from the releases on Github, unzip the file then put the flowcat binary for your OS in one of your userpaths such as /usr/local/bin/, /bin/, /sbin/ or another path
-[![linux-amd64 build and functionality](https://github.com/Acetolyne/flowcat/actions/workflows/linux-amd64%20build%20and%20functionality.yml/badge.svg?branch=master)](https://github.com/Acetolyne/flowcat/actions/workflows/linux-amd64%20build%20and%20functionality.yml) https://github.com/Acetolyne/flowcat/raw/master/bin/flowcat-linux-amd64/flowcat
-
-[![linux-386 build and functionality](https://github.com/Acetolyne/flowcat/actions/workflows/linux-386%20build%20and%20functionality.yml/badge.svg?branch=master)](https://github.com/Acetolyne/flowcat/actions/workflows/linux-386%20build%20and%20functionality.yml) https://github.com/Acetolyne/flowcat/raw/master/bin/flowcat-linux-386/flowcat
-
-[![darwin-arm64 build and functionality](https://github.com/Acetolyne/flowcat/actions/workflows/darwin-arm64%20build%20and%20functionality.yml/badge.svg?branch=master)](https://github.com/Acetolyne/flowcat/actions/workflows/darwin-arm64%20build%20and%20functionality.yml) https://github.com/Acetolyne/flowcat/raw/master/bin/flowcat-darwin-arm64/flowcat
+[![functionality](https://github.com/Acetolyne/flowcat/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/Acetolyne/flowcat/actions/workflows/test.yml)
+[![build](https://github.com/Acetolyne/flowcat/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Acetolyne/flowcat/actions/workflows/build.yml)
Flowcat is currently only tested on Linux systems, now that flowcat is written in GoLang I am looking at porting it to Windows systems as well. While not tested yet it should currently work with MacOS as well but feedback is required.
@@ -74,11 +71,16 @@ Flowcat is currently only tested on Linux systems, now that flowcat is written i
To install from source clone the repository with the command ```git clone https://github.com/Acetolyne/flowcat```
build the binary for your system with ```go build *.go -o flowcat```
Now move the binary to a system path such as /usr/bin/
-alternatively if you don't want to setup a go environment to build from source you may use one of the pre-compiled binaries in the bin directory.
+if you are cross compiling for another system you will need to export the appropriate variables as per the golang documentation.
+
+#### download binary
+alternatively if you don't want to setup a go environment to build from source you may use one of the pre-compiled binaries that are available as releases on the github page https://github.com/Acetolyne/flowcat.
#### Settings initialization
running ```flowcat init``` will allow you to make a settings file for your user so that you can set the default -m argument as well as a list of regex for files to ignore. Once running flowcat init flowcat will confirm the file was written to ~/.flowcat/config, it is suggested to edit the settings file to include the files or regex you would like to ignore when flowcat runs.
+If you use the -o option to output to a file that file will automatically be ignored so you are not reading your output, this makes it safe to output to the same directory that you are reading.
+
#### Regex
The regex used for matching against ignore files and to match lines via the -m argument is described in the documentation at https://github.com/google/re2/wiki/Syntax and uses the MatchString method.
@@ -88,7 +90,6 @@ The syntax of the regular expressions accepted is the same general syntax used b
-
#### VSCode autorun option
A useful workflow is to have flowcat regenerate your todo list when you save a file. Using the RunOnSave extension by pucelle this can be accomplished, you have to setup a separate setting for each project folder but it can really help you track your tasks during your projects lifetime. Below is an example of how I have mine setup. these setting need to go in the settings.json file in VSCode found by navigating to File > Preferences > Settings then clicking on Run On Save under extensions, which is visible after installing the extension, then click edit in settings.json and modify the file to have something similar to the below example replacing the paths to your project folders. Add as many project folders as you need, this also allows for different regex matching for different programming languages or even creation of multiple separated task lists.
@@ -114,29 +115,28 @@ A useful workflow is to have flowcat regenerate your todo list when you save a f
```
### Supported filetypes
flowcat currently supports the following filetypes additionally files with no extensions use the basic // comment style and /* */ comment style for multiline comments.
-To have additional filetypes added to flowcat please open an issue on GitHub for the lexer that is used by flowcat at github.com/Acetolyne/commentlex
+To have additional filetypes added to flowcat please open an issue on GitHub at github.com/Acetolyne/flowcat
-##### Supported Filetypes
+#### Supported Filetypes
-.go
-.py
-.js
-.rs
-.html
-.gohtml
-.php
+```text
.c
+.class
.cpp
+.go
+.gohtml
.h
-.class
+.html
.jar
.java
+.js
.jsp
-.sh
-.php
-.html
-.gohtml
-.md
.lua
-.rb
+.md
+.php
.py
+.rb
+.rs
+.sh
+.tmpl
+```
\ No newline at end of file
diff --git a/bin/flowcat-darwin-arm64/flowcat b/bin/flowcat-darwin-arm64/flowcat
deleted file mode 100755
index 2c761b1..0000000
Binary files a/bin/flowcat-darwin-arm64/flowcat and /dev/null differ
diff --git a/bin/flowcat-linux-386/flowcat b/bin/flowcat-linux-386/flowcat
deleted file mode 100755
index 9350cf2..0000000
Binary files a/bin/flowcat-linux-386/flowcat and /dev/null differ
diff --git a/bin/flowcat-linux-amd64/flowcat b/bin/flowcat-linux-amd64/flowcat
deleted file mode 100755
index 2a9e675..0000000
Binary files a/bin/flowcat-linux-amd64/flowcat and /dev/null differ
diff --git a/build/scripts/auto_extensions.go b/build/scripts/auto_extensions.go
deleted file mode 100644
index db9c2c4..0000000
--- a/build/scripts/auto_extensions.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package main
-
-// import (
-// "bufio"
-// "fmt"
-// "os"
-// "strings"
-// )
-
-// func main() {
-// var s lexer.Scanner
-// var buffer string
-// s.Mode = lexer.ScanComments
-// allext := s.GetExtensions()
-
-// file, err := os.Open("../../README.md")
-// if err != nil {
-// fmt.Println(err)
-// }
-
-// scanner := bufio.NewScanner(file)
-// for scanner.Scan() {
-// buffer += scanner.Text() + "\n"
-// if strings.Contains(buffer, "##### Supported Filetypes") {
-// break
-// }
-// }
-
-// if err := scanner.Err(); err != nil {
-// fmt.Println(err)
-// }
-// for l := range allext {
-// curext := allext[l]
-// buffer += curext + "\n"
-// }
-// file.Close()
-// file, err = os.OpenFile("../../README.md", os.O_APPEND|os.O_WRONLY, os.ModeAppend)
-// if err != nil {
-// fmt.Println(err)
-// }
-// err = file.Truncate(0)
-// if err != nil {
-// fmt.Println(err)
-// }
-// _, err = file.Seek(0, 0)
-// if err != nil {
-// fmt.Println(err)
-// }
-// _, err = fmt.Fprintf(file, "%s", buffer)
-// if err != nil {
-// fmt.Println(err)
-// }
-// }
diff --git a/changelog b/changelog
index 4129582..59af3a0 100644
--- a/changelog
+++ b/changelog
@@ -1,5 +1,9 @@
-VERSION 3.0.0
+VERSION 4.0.0
-Moved to using a custom lexer to parse files.
-Adds ability to parse files with multiple comment styles such as html files that may have html comments as well as javascript comments in a single filetype.
-Moves settings file to user home folder instead of per directory as this didn't work well when scanning specific folders within a project.
+Moved to a new lexer that significantly improves speed of finding matching comments
+Added better testing files
+Started using releases on Github
+Added logging
+moved config file to user directory only
+Fixed issue where comments inside of print statements were returned
+updated default to match on TODO instead of @todo
\ No newline at end of file
diff --git a/lexer.go b/lexer.go
index b734313..be69601 100644
--- a/lexer.go
+++ b/lexer.go
@@ -1,12 +1,6 @@
package main
-//@todo use the map like if map[FILE TYPE] == tok.Type then add token to a slice of token structs
-//@todo return a slice of structs {Line, Token}
-//@todo add current todo regex into middle of comment regex when adding to lexer
-//@todo pass in the users regex to call to GetComments from main file
//@todo create more types of comments
-//@todo make a go test file
-//@todo make the test.txt file be one file to test all types of comments
import (
"encoding/json"
"fmt"
@@ -37,71 +31,76 @@ type CommentValues struct {
}
var tokens = []string{
- "IGNORE", "ML-SINGLE-STYLE", "SL-COMMENT-COMMON-A", "ML-COMMENT-COMMON-A", "SL-SHELL-STYLE", "SL-HTML-STYLE", "ML-HTML-STYLE", "SL-LUA-STYLE", "ML-LUA-STYLE", "ML-RUBY-STYLE", "TEMPLATE-STYLE",
+ "IGNORE", "ML-COMMENT-COMMON-B", "ML-SINGLE-STYLE", "SL-COMMENT-COMMON-A", "ML-COMMENT-COMMON-A", "SL-SHELL-STYLE", "SL-HTML-STYLE", "ML-HTML-STYLE", "SL-LUA-STYLE", "ML-LUA-STYLE", "ML-RUBY-STYLE", "TEMPLATE-STYLE",
}
var tokmap map[string]int
var lexer *lexmachine.Lexer
var Extensions = []CommentValues{
+ {
+ Ext: []string{"py"},
+ // Multiline each starting with #
+ Type: 1,
+ },
{
Ext: []string{"rs"},
// Multiline each starting with //
- Type: 1,
+ Type: 2,
},
{
Ext: []string{"", "go", "py", "js", "rs", "html", "gohtml", "php", "c", "cpp", "h", "class", "jar", "java", "jsp", "php"},
// startSingle: "//",
- Type: 2,
+ Type: 3,
},
{
Ext: []string{"", "go", "py", "js", "rs", "html", "gohtml", "php", "c", "cpp", "h", "class", "jar", "java", "jsp", "php"},
// startMulti: "/*",
// endMulti: "*/",
- Type: 3,
+ Type: 4,
},
{
Ext: []string{"sh", "php", "rb", "py"},
// startSingle: "#",
- Type: 4,
+ Type: 5,
},
{
Ext: []string{"html", "gohtml", "md"},
// Singleline HTML STYLE: "",
- Type: 5,
+ Type: 6,
},
{
Ext: []string{"html", "gohtml", "md"},
// startMulti: "",
- Type: 6,
+ Type: 7,
},
{
Ext: []string{"lua"},
// startSingle: "--",
- Type: 7,
+ Type: 8,
},
{
Ext: []string{"lua"},
// startMulti: "--[[",
// endMulti: "--]]",
- Type: 8,
+ Type: 9,
},
{
Ext: []string{"rb"},
// startMulti: "=begin",
// endMulti: "=end",
- Type: 9,
+ Type: 10,
},
{
Ext: []string{"tmpl"},
// startMulti: "{{/*",
// endMulti: "*/}}",
- Type: 10,
+ Type: 11,
},
{
Ext: []string{"rs"},
// Multiline each starting with //
- Type: 11,
+ Type: 12,
},
}
@@ -134,24 +133,20 @@ func newLexer(match string) *lexmachine.Lexer {
}
var lexer = lexmachine.NewLexer()
//NEGATIVE LOOKAHEADS NOT SUPPORTED use START([^E]|E[^N]|EN[^D])*MATCH([^E]|E[^N]|EN[^D])*END to generate a long POSIX compatible regex
- //@todo create tests for:
- //partial ending token in middle of comment does not cut comment off
- //comment in double quotes
- //comment in single quotes
- //lexer.Add([]byte(`#[^\n]*`), getToken(tokmap["COMMENT"]))
+
lexer.Add(lexReg([]byte(`[\"]//[ ]*`), match, []byte(`[^\n]*[\"][^\n]*`)), getToken(tokmap["IGNORE"])) //IGNORE THE MATCH WHEN IT IS BETWEEN DOUBLE QUOTES
lexer.Add(lexReg([]byte(`[\']//[ ]*`), match, []byte(`[^\n]*[\'][^\n]*`)), getToken(tokmap["IGNORE"])) //IGNORE THE MATCH WHEN IT IS BETWEEN SINGLE QUOTES
+ lexer.Add(lexReg([]byte(`(#(@todo)*.*#`), match, []byte(`([^\n]|\n[#])*)`)), getToken(tokmap["ML-COMMENT-COMMON-B"]))
//lexer.Add(lexReg([]byte(`//.*(\n[\/][\/].*)*`), match, []byte(`.*(\n[\/][\/].*)*`)), getToken(tokmap["ML-SINGLE-STYLE"]))
lexer.Add(lexReg([]byte(`//[ ]*`), match, []byte(`[^\n]*`)), getToken(tokmap["SL-COMMENT-COMMON-A"])) //SL-COMMENT-COMMON-A
lexer.Add(lexReg([]byte(`\/\*([^\*]|\*[^\/])*`), match, []byte(`([^\*]|\*[^\/])*\*\/`)), getToken(tokmap["ML-COMMENT-COMMON-A"])) //ML-COMMENT-COMMON-A
lexer.Add(lexReg([]byte(`#[ ]*`), match, []byte(`[^\n]*`)), getToken(tokmap["SL-SHELL-STYLE"])) //SL-SHELL-STYLE
- lexer.Add(lexReg([]byte(``)), getToken(tokmap["SL-HTML-STYLE"])) //SL-HTML-STYLE
- lexer.Add(lexReg([]byte(``)), getToken(tokmap["ML-HTML-STYLE"])) //ML-HTML-STYLE
- lexer.Add(lexReg([]byte(`\-\-[ ]*`), match, []byte(`[^\n]*`)), getToken(tokmap["SL-LUA-STYLE"])) //SL-LUA-STYLE
+ lexer.Add(lexReg([]byte(`()`)), getToken(tokmap["SL-HTML-STYLE"])) //SL-HTML-STYLE
+ lexer.Add(lexReg([]byte(`(`)), getToken(tokmap["ML-HTML-STYLE"])) //ML-HTML-STYLE
+ lexer.Add(lexReg([]byte(`\-\-\[\[([^\n])*`), match, []byte(`[^\n]+\-\-\]\]`)), getToken(tokmap["SL-LUA-STYLE"])) //SL-LUA-STYLE
lexer.Add(lexReg([]byte(`--\[\[([^-]|-[^-]|--[^\]|\-\-\][^\]])*`), match, []byte(`([^-]|-[^-]|--[^\]]|\-\-\][^\]])*--\]\]`)), getToken(tokmap["ML-LUA-STYLE"])) //ML-LUA-STYLE
- lexer.Add(lexReg([]byte(`\=begin([^=]|=[^e]|=e[^n]|=en[^d])*`), match, []byte(`([^=]|=[^e]|=e[^n]|=en[^d])*`)), getToken(tokmap["ML-RUBY-STYLE"]))
- //@todo regex below has a bug so does not return the last token when doing the match on all chars except */}} when we add the last } it makes the asterisk not match in ending of token.
- lexer.Add(lexReg([]byte(`\{\{\/\*([^\*]|\*[^\/]|\*\/[^\}]|\*\/\}[^\}])*`), match, []byte(`([^\*]|\*[^\/]|\*\/[^\}]|\*\/}[^}])*`)), getToken(tokmap["TEMPLATE-STYLE"]))
+ lexer.Add(lexReg([]byte(`\=begin([^=]|=[^e]|=e[^n]|=en[^d])*`), match, []byte(`([^=]|=[^e]|=e[^n]|=en[^d])*=end`)), getToken(tokmap["ML-RUBY-STYLE"]))
+ lexer.Add(lexReg([]byte(`\{\{\/\*([^\*]|\*[^\/]|\*\/[^\}]|\*\/\}[^\}])*`), match, []byte(`([^\*]|\*[^\/]|\*\/[^\}]|\*\/}[^}])*\*\/\}\}`)), getToken(tokmap["TEMPLATE-STYLE"]))
// lexer.Add(lexReg([]byte(``)), getToken(tokmap["WHAT-STYLE"]))
// lexer.Add(lexReg([]byte(``)), getToken(tokmap["WHAT-STYLE"]))
// lexer.Add(lexReg([]byte(``)), getToken(tokmap["WHAT-STYLE"]))
@@ -178,13 +173,17 @@ func newLexer(match string) *lexmachine.Lexer {
return lexer
}
-func scan(text []byte, path string, showlines bool, outputFile string) error {
+func Scan(text []byte, path string, showlines bool, outputFile string) error {
logger.Info.Println("Scanning file:", path)
var f *os.File
var err error
-
//open output file in preparation
if outputFile != "" {
+ dir, _ := filepath.Split(outputFile)
+ if dir == "" {
+ folder, _ := filepath.Split(path)
+ outputFile = folder + outputFile
+ }
logger.Info.Println("Output will be sent to", outputFile)
f, err = os.OpenFile(outputFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
@@ -201,6 +200,7 @@ func scan(text []byte, path string, showlines bool, outputFile string) error {
}
scanner, err := lexer.Scanner(text)
if err != nil {
+ logger.Err.Println("Error while scanning text", string(text), err.Error())
return err
}
for tk, err, eof := scanner.Next(); !eof; tk, err, eof = scanner.Next() {
@@ -219,9 +219,11 @@ func scan(text []byte, path string, showlines bool, outputFile string) error {
if CommentValue.Type == curtok.Type {
if printfile {
fmt.Println(path)
- _, err = f.WriteString(path + "\n")
- if err != nil {
- logger.Err.Println("Could not write output file", err.Error())
+ if outputFile != "" {
+ _, err = f.WriteString(path + "\n")
+ if err != nil {
+ logger.Err.Println("Could not write output file", err.Error())
+ }
}
printfile = false
}
@@ -258,7 +260,7 @@ func scan(text []byte, path string, showlines bool, outputFile string) error {
func GetComments(text []byte, match string, path string, showlines bool, outputFile string) {
logger.Info.Println("matching on", match)
lexer = newLexer(match)
- err := scan(text, path, showlines, outputFile)
+ err := Scan(text, path, showlines, outputFile)
if err != nil {
logger.Err.Println("Error scanning text", err.Error())
}
diff --git a/main.go b/main.go
index ce12e4f..5a0da88 100644
--- a/main.go
+++ b/main.go
@@ -14,8 +14,6 @@ import (
"gopkg.in/yaml.v2"
)
-// @todo add logger
-// @todo add debug option in config file
// Config structure of configuration from a yaml settings file.
type Config struct {
Linenum string `yaml:"linenum"`
@@ -31,12 +29,11 @@ var Cfg Config
var Debug int
// @todo excluded regex not working when -f is specified because -f value is part of the path
-func checkExclude(path string, outfile string, folderFlag string) (string, bool) {
+func CheckExclude(path string, outfile string, folderFlag string) (string, bool) {
regpath := strings.TrimPrefix(path, folderFlag)
m := Cfg.IgnoredItems
reg := []bool{}
//If we are outputting to a file ignore the output file by default if it is in the project path
- //@todo fix this logic see if path ends with the outfile
if outfile != "" {
if strings.Contains(outfile, folderFlag) {
m = append(m, outfile)
@@ -139,6 +136,7 @@ func main() {
var matchexp string
var outputFile string
+ //@todo add --dfa flag and pass to lexer file to change lexer compiling to dfa if wanted
folderFlag := flag.String("f", "./", "The project top level directory, where flowcat should start recursing from.")
outputFlag := flag.String("o", "", "Optional output file to dump results to, note output will still be shown on terminal.")
matchFlag := flag.String("m", "", "The string to match to do items on.")
@@ -183,7 +181,6 @@ func main() {
//@todo check if the folder .flowcat exists in the user dir
//@todo if it does not exist create it
//@todo if there is no .flowcat/settings file then create it with defaults
- //@todo logs should go in the .flowcat folder as debug.log and error.log each should be overwritten every time.
settings, err := os.OpenFile(dirname+"/.flowcat/config", os.O_RDONLY, 0600)
if err != nil {
logger.Warn.Println("Could not open user configuration file", dirname+"/.flowcat/config", err.Error())
@@ -218,7 +215,14 @@ func main() {
if *outputFlag != "" {
if *folderFlag != "" {
- outputFile = *folderFlag + *outputFlag
+ //If the user only supplied a filename without a path then use the filepath supplied at -f
+ dir, _ := filepath.Split(*outputFlag)
+ if dir == "" {
+ dir, _ := filepath.Split(*folderFlag)
+ outputFile = dir + *outputFlag
+ } else {
+ outputFile = *outputFlag
+ }
} else {
outputFile = *outputFlag
}
@@ -228,6 +232,7 @@ func main() {
logger.Err.Println("Could not trucate output file", outputFile, err.Error())
}
}
+ //Todo make this its own function and pass in relative information
parseFiles := func(path string, info os.FileInfo, _ error) (err error) {
if outputFile != "" {
@@ -242,8 +247,7 @@ func main() {
}
}
if info.Mode().IsRegular() {
- file, exc := checkExclude(path, outputFile, *folderFlag)
-
+ file, exc := CheckExclude(path, outputFile, *folderFlag)
//If the file does not match our exclusion regex then use it.
if !exc {
logger.Info.Println("Checking file", path)
diff --git a/main_test.go b/main_test.go
new file mode 100644
index 0000000..77ec392
--- /dev/null
+++ b/main_test.go
@@ -0,0 +1,220 @@
+package main
+
+//This file holds test performed on binaries
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+// Create the tests
+// basic tests
+var tests = []struct {
+ path string
+ outfile string
+ folderFlag string
+ exp string
+}{
+ {"test.go", "", "", "test.go false"},
+ {"todo", "", "./", "todo true"},
+}
+
+var outputfiletests = []struct {
+ text []byte
+ path string
+ showlines bool
+ outputFile string
+ exp string
+}{
+ {[]byte("//@todo some comment"), "tests/files/test.go", true, "output.txt", "tests/files/test.go\n 1)//@todo some comment\n"},
+ {[]byte("//@todo some comment"), "tests/files/test.go", true, "./output.txt", "tests/files/test.go\n 1)//@todo some comment\n"},
+}
+
+// //Testing starts
+// Performs pre-test actions like creating the binaries and a tmp folder for test files
+func TestPre(t *testing.T) {
+ //Create binaries folders
+ err := os.MkdirAll("bin/flowcat-darwin-arm64", 0775)
+ if err != nil {
+ t.Fatal("[PRE-TEST][BIN FOLDER] creating the folder bin/flowcat-darwin-arm64 failed", err.Error())
+ }
+ err = os.MkdirAll("bin/flowcat-linux-386", 0775)
+ if err != nil {
+ t.Fatal("[PRE-TEST][BIN FOLDER] creating the folder bin/flowcat-linux-386 failed", err.Error())
+ }
+ err = os.MkdirAll("bin/flowcat-linux-amd64", 0775)
+ if err != nil {
+ t.Fatal("[PRE-TEST][BIN FOLDER] creating the folder bin/flowcat-linux-amd64 failed", err.Error())
+ }
+
+ //Create tmp file folder
+ err = os.MkdirAll("tests/files", 0775)
+ if err != nil {
+ t.Fatal("Could not perform pre-test actions, creating the tmp file folder failed", err.Error())
+ }
+}
+
+// func TestCfg(t *testing.T) {
+// var c Config
+// c.Linenum := false
+// c.Match := ""
+// }
+
+func TestCheckExclude(t *testing.T) {
+ //Run the tests
+ Cfg.IgnoredItems = append(Cfg.IgnoredItems, "todo")
+ for _, e := range tests {
+ file, exc := CheckExclude(e.path, e.outfile, e.folderFlag)
+ res := file + " " + strconv.FormatBool(exc)
+ if res != e.exp {
+ t.Errorf("Got: %s Expected: %s", res, e.exp)
+ }
+ }
+}
+
+func TestOutputFile(t *testing.T) {
+ for _, e := range outputfiletests {
+ lexer = newLexer("@todo") //sets the matching string
+ err := Scan(e.text, e.path, e.showlines, e.outputFile)
+ if err != nil {
+ t.Errorf("Scan failed %s", err.Error())
+ }
+ dir, _ := filepath.Split(e.outputFile)
+ if dir == "" {
+ folder, _ := filepath.Split(e.path)
+ b, err := os.ReadFile(folder + e.outputFile) // pass path at -f plus output filename
+ if err != nil {
+ t.Errorf("Could not read output file %s %s", e.outputFile, err.Error())
+ }
+ if e.exp != string(b) {
+ t.Errorf("Got: %s Expected: %s", string(b), e.exp)
+ }
+ err = os.Remove(folder + e.outputFile)
+ if err != nil {
+ t.Errorf("Could not remove old file %s %s", folder+e.outputFile, err.Error())
+ }
+ } else {
+ b, err := os.ReadFile(e.outputFile) // just pass the output file name
+ if err != nil {
+ t.Errorf("Could not read output file %s", e.outputFile)
+ }
+ if e.exp != string(b) {
+ t.Errorf("Got: %s Expected: %s", string(b), e.exp)
+ }
+ err = os.Remove(e.outputFile)
+ if err != nil {
+ t.Errorf("Could not remove old file %s %s", e.outputFile, err.Error())
+ }
+ }
+
+ }
+}
+
+func TestReadme(t *testing.T) {
+ var buffer string
+ set := map[string]struct{}{}
+ var stdout bytes.Buffer
+ var stderr bytes.Buffer
+
+ //copy the readme.md file to readme_copy.md
+ source, err := os.Open("README.md") //open the source file
+ if err != nil {
+ panic(err)
+ }
+ defer source.Close()
+
+ destination, err := os.Create("README_COPY.md") //create the destination file
+ if err != nil {
+ panic(err)
+ }
+ _, err = io.Copy(destination, source)
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ //Update the extensions in the readme
+ file, err := os.Open("README.md")
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ buffer += scanner.Text() + "\n"
+ if strings.Contains(buffer, "#### Supported Filetypes") {
+ break
+ }
+ }
+ buffer += "\n```text\n"
+ if err := scanner.Err(); err != nil {
+ t.Errorf(err.Error())
+ }
+ //creates a set so we dont have duplicates
+ for l := range Extensions {
+ curext := Extensions[l]
+ for _, ext := range curext.Ext {
+ if ext != "" {
+ set[ext] = struct{}{}
+ }
+ }
+ }
+ keys := make([]string, 0, len(set))
+ for k := range set {
+ keys = append(keys, k)
+ }
+ //sort the keys so they are always list in the same order
+ sort.Strings(keys)
+ for _, k := range keys {
+ buffer += "." + k + "\n"
+ }
+ buffer += "```"
+ file.Close()
+ file, err = os.OpenFile("README.md", os.O_APPEND|os.O_WRONLY, os.ModeAppend)
+
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+
+ err = file.Truncate(0)
+
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+
+ _, err = file.Seek(0, 0)
+
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+
+ _, err = fmt.Fprintf(file, "%s", buffer)
+
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ //Run diff on the two files
+ cmd := exec.Command("/usr/bin/bash", "-c", "diff README.md README_COPY.md")
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+ err = cmd.Run()
+ if err != nil {
+ t.Errorf("[ERROR]Readme was autoupdated commit the changes and run the test again %s", err.Error())
+ }
+ //Remove COPY
+ err = os.Remove("README_COPY.md")
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+}
+
+//@todo init settings works
+//@todo init settings fails if ran a second time and the file is already there
+//@todo can get config settings from file
diff --git a/release_test.go b/release_test.go
new file mode 100644
index 0000000..f67052d
--- /dev/null
+++ b/release_test.go
@@ -0,0 +1,64 @@
+package main
+
+//This file holds test performed on binaries and should only be ran after the main_test.go file
+
+import (
+ "bytes"
+ "fmt"
+ "os/exec"
+ "testing"
+)
+
+// fmt.Println("Test Init when not yet inited")
+// cmd := exec.Command("/usr/bin/bash", "-c", "export PATH=$PATH:/usr/local/go/bin; go run main.go logger.go lexer.go init")
+// cmd.Stdout = &stdout
+// cmd.Stderr = &stderr
+// err = cmd.Run()
+// if err != nil {
+// t.Fatal("Error initing flowcat", err.Error())
+// }
+// if stdout.String() != "" {
+// fmt.Println(stdout.String())
+// }
+
+func TestBuildBinaries(t *testing.T) {
+ var stdout bytes.Buffer
+ var stderr bytes.Buffer
+
+ // Create the binaries
+ fmt.Println("Building binary for darwin-arm64")
+ // env GOOS=darwin GOARCH=arm64 GO111MODULE=auto go build *.go -o bin/flowcat-darwin-arm64/flowcat
+ cmd := exec.Command("/usr/bin/bash", "-c", "export PATH=$PATH:/usr/local/go/bin; env GOOS=darwin GOARCH=arm64 GO111MODULE=auto go build -o bin/flowcat-darwin-arm64/flowcat")
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+ err := cmd.Run()
+ if err != nil {
+ t.Fatal("Error compiling binary darwin-arm64", err.Error())
+ }
+ if stdout.String() != "" {
+ fmt.Println(stdout.String())
+ }
+ fmt.Println("Building binary for linux-386")
+ cmd = exec.Command("/usr/bin/bash", "-c", "export PATH=$PATH:/usr/local/go/bin; env GOOS=linux GOARCH=386 GO111MODULE=auto go build -o bin/flowcat-linux-386/flowcat")
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+ err = cmd.Run()
+ if err != nil {
+ t.Fatal("Error compiling binary linux-386", err.Error())
+ }
+ if stdout.String() != "" {
+ fmt.Println(stdout.String())
+ }
+
+ fmt.Println("Building binary for linux-amd64")
+ cmd = exec.Command("/usr/bin/bash", "-c", "export PATH=$PATH:/usr/local/go/bin; env GOOS=linux GOARCH=amd64 GO111MODULE=auto go build -o bin/flowcat-linux-amd64/flowcat")
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+ err = cmd.Run()
+ if err != nil {
+ t.Fatal("Error compiling binary linux-amd64", err.Error())
+ }
+ if stdout.String() != "" {
+ fmt.Println(stdout.String())
+ }
+}
diff --git a/scanner_test.go b/scanner_test.go
new file mode 100644
index 0000000..4569a19
--- /dev/null
+++ b/scanner_test.go
@@ -0,0 +1,82 @@
+package main
+
+import (
+ "os"
+ "testing"
+)
+
+// (text []byte, path string, showlines bool, outputFile string)
+var scantests = []struct {
+ text []byte
+ path string
+ showlines bool
+ outputFile string
+ match string
+ exp string
+}{
+ //Golang tests
+ {[]byte("//@todo some comment"), "test.go", true, "output.txt", "@todo", "test.go\n 1)//@todo some comment\n"}, //can get single line comment
+ {[]byte("some words //@todo some comment"), "test.go", true, "output.txt", "@todo", "test.go\n 1)//@todo some comment\n"}, //can get comment at end of line
+ {[]byte("//@todo some comment"), "test.go", true, "output.txt", "todo", ""}, //ignores comments when a different match is used
+ {[]byte("fmt.Println(\"//@todo some comment\")"), "test.go", true, "output.txt", "@todo", ""}, //ignores comments inside a print statement or string
+ {[]byte("/* Some multiline \n@todo comment \ncomment2 */"), "test.go", true, "output.txt", "@todo", "test.go\n 1)/* Some multiline \n@todo comment \ncomment2 */\n"}, //can get multi-line comments
+ //Python tests
+ {[]byte("#@todo some comment"), "test.py", true, "output.txt", "@todo", "test.py\n 1)#@todo some comment\n"},
+ {[]byte("some words first #@todo some comment"), "test1.py", true, "output.txt", "@todo", "test1.py\n 1)#@todo some comment\n"},
+ {[]byte("#@todo some comment"), "test2.py", true, "output.txt", "todo", ""},
+ {[]byte("print(\"#@todo some comment\")"), "test3.py", true, "output.txt", "@todo", ""},
+ {[]byte("#some multiline \n#@todo comment\n#with 3 lines"), "test4.py", true, "output.txt", "@todo", "test4.py\n 1)#some multiline \n#@todo comment\n#with 3 lines\n"},
+ //HTML tests
+ {[]byte(""), "test.html", true, "output.txt", "@todo", "test.html\n 1)\n"}, //can get single line comment
+ {[]byte(""), "test2.html", true, "output.txt", "@todo", "test2.html\n 1)\n"}, //can get comment at end of line
+ {[]byte(""), "test3.html", true, "output.txt", "note", ""}, //ignores comments when a different match is used
+ {[]byte("fmt.Println(\""), "test5.html", true, "output.txt", "@todo", "test5.html\n 1)\n"}, //can get multi-line comments
+ //LUA tests
+ {[]byte("--[[@todo some comment--]]"), "test.lua", true, "output.txt", "@todo", "test.lua\n 1)--[[@todo some comment--]]\n"}, //can get single line comment
+ {[]byte("some words --[[@todo some comment--]]"), "test2.lua", true, "output.txt", "@todo", "test2.lua\n 1)--[[@todo some comment--]]\n"}, //can get comment at end of line
+ {[]byte("--[[@todo some comment--]]"), "test3.lua", true, "output.txt", "note", ""}, //ignores comments when a different match is used
+ {[]byte("fmt.Println(\"//@todo some comment\")"), "test4.lua", true, "output.txt", "@todo", ""}, //ignores comments inside a print statement or string
+ {[]byte("--[[ Some multiline \n@todo comment \ncomment2 --]]"), "test5.lua", true, "output.txt", "@todo", "test5.lua\n 1)--[[ Some multiline \n@todo comment \ncomment2 --]]\n"}, //can get multi-line comments
+ //Ruby tests
+ {[]byte("#@todo some comment"), "test.rb", true, "output.txt", "@todo", "test.rb\n 1)#@todo some comment\n"}, //can get single line comment
+ {[]byte("some words #@todo some comment"), "test2.rb", true, "output.txt", "@todo", "test2.rb\n 1)#@todo some comment\n"}, //can get comment at end of line
+ {[]byte("#@todo some comment"), "test3.rb", true, "output.txt", "note", ""}, //ignores comments when a different match is used
+ {[]byte("fmt.Println(\"#@todo some comment\")"), "test4.rb", true, "output.txt", "@todo", ""}, //ignores comments inside a print statement or string
+ {[]byte("=begin\n Some multiline \n@todo comment \ncomment2 \n=end"), "test5.rb", true, "output.txt", "@todo", "test5.rb\n 1)=begin\n Some multiline \n@todo comment \ncomment2 \n=end\n"}, //can get multi-line comments
+ //tmpl file tests
+ {[]byte("{{/* @todo some comment */}}"), "test.tmpl", true, "output.txt", "@todo", "test.tmpl\n 1){{/* @todo some comment */}}\n"}, //can get single line comment
+ {[]byte("some words {{/* @todo some comment */}}"), "test2.tmpl", true, "output.txt", "@todo", "test2.tmpl\n 1){{/* @todo some comment */}}\n"}, //can get comment at end of line
+ {[]byte("{{/* @todo some comment */}}"), "test3.tmpl", true, "output.txt", "note", ""}, //ignores comments when a different match is used
+ {[]byte("fmt.Println(\"{{/*@todo some comment*/}}\")"), "test4.tmpl", true, "output.txt", "@todo", ""}, //ignores comments inside a print statement or string
+ {[]byte("{{/* Some multiline \n@todo comment \ncomment2 \n*/}}"), "test5.tmpl", true, "output.txt", "@todo", "test5.tmpl\n 1){{/* Some multiline \n@todo comment \ncomment2 \n*/}}\n"}, //can get multi-line comments
+}
+
+func TestScan(t *testing.T) {
+ var Cfg Config
+ Cfg.Linenum = "false"
+ for _, e := range scantests {
+ //fmt.Println("TESTING", e)
+ lexer = newLexer(e.match) //sets the matching string
+ err := Scan(e.text, e.path, e.showlines, e.outputFile) //e.text, e.path, e.showlines, e.outputFile
+ if err != nil {
+ t.Errorf("Scan failed %s", err.Error())
+ }
+ b, err := os.ReadFile(e.outputFile) // just pass the output file name
+ if err != nil {
+ t.Errorf("Could not read output file %s", e.outputFile)
+ }
+ if e.exp != string(b) {
+ t.Errorf("Got: %s Expected: %s", string(b), e.exp)
+ }
+ err = os.Truncate(e.outputFile, 0)
+ if err != nil {
+ t.Errorf("%s", err.Error())
+
+ }
+ }
+ err := os.Remove("output.txt")
+ if err != nil {
+ t.Errorf("Could not remove old test file output.txt %s", err.Error())
+ }
+}
diff --git a/tests/assets/.flowcat1 b/tests/assets/.flowcat1
deleted file mode 100644
index 5476174..0000000
--- a/tests/assets/.flowcat1
+++ /dev/null
@@ -1,6 +0,0 @@
-# Settings
-match: "Comment"
-
-# File patterns to ignore
-ignore:
- - "^\\..*"
\ No newline at end of file
diff --git a/tests/assets/.flowcatBKF b/tests/assets/.flowcatBKF
deleted file mode 100644
index 9441b99..0000000
--- a/tests/assets/.flowcatBKF
+++ /dev/null
@@ -1,8 +0,0 @@
-# Settings
-linenum: "false"
-match: "@todo"
-
-# File patterns to ignore
-ignore:
- - "\\.flowcat"
- - "^\\."
diff --git a/tests/assets/.test b/tests/assets/.test
deleted file mode 100644
index efda427..0000000
--- a/tests/assets/.test
+++ /dev/null
@@ -1,4 +0,0 @@
-//@todo test file
-#@todo test 2
-before //@todo after
-/This?
diff --git a/tests/assets/__testfile__ b/tests/assets/__testfile__
deleted file mode 100644
index f8a296f..0000000
--- a/tests/assets/__testfile__
+++ /dev/null
@@ -1,3 +0,0 @@
-//@todo test file
-#@todo test 2
-before //@todo after
diff --git a/tests/assets/multitest/test.go b/tests/assets/multitest/test.go
deleted file mode 100644
index f1006fd..0000000
--- a/tests/assets/multitest/test.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package none
-
-func main() {
- //@todo Regular comment
- println("Hello World") // Inline comment
- /* Some multiline
- @todo comment
- comment2 */
- //@todo comment 3
-}
diff --git a/tests/assets/multitest/test.php b/tests/assets/multitest/test.php
deleted file mode 100644
index 72dd9c7..0000000
--- a/tests/assets/multitest/test.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
diff --git a/tests/assets/regular b/tests/assets/regular
deleted file mode 100644
index 4187e58..0000000
--- a/tests/assets/regular
+++ /dev/null
@@ -1,3 +0,0 @@
-//@todo regular test
-#@todo test 2
-before //@todo with exclude
diff --git a/tests/assets/test.go b/tests/assets/test.go
deleted file mode 100644
index 6a47fa6..0000000
--- a/tests/assets/test.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package none
-
-// func main() {
-// //@todo Regular comment
-// println("Hello World") // Inline comment
-// println("//@todo comment in double quotes")
-// //println('//@todo comment in single quotes')
-// /* single @todo line ML comment */
-// /* Some multiline *
-// @todo comment /
-// comment2 */
-// //@todo comment 3
-// }
diff --git a/tests/assets/test.html b/tests/assets/test.html
deleted file mode 100644
index 0811d64..0000000
--- a/tests/assets/test.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tests/assets/test.lua b/tests/assets/test.lua
deleted file mode 100644
index 8205a42..0000000
--- a/tests/assets/test.lua
+++ /dev/null
@@ -1,9 +0,0 @@
--- single line comment
---@todo singleline todo comment
-
---[[
- @todo Multiline
- Comment
---]]
-
--- @todo Comment 3
\ No newline at end of file
diff --git a/tests/assets/test.php b/tests/assets/test.php
deleted file mode 100644
index ada4e29..0000000
--- a/tests/assets/test.php
+++ /dev/null
@@ -1,25 +0,0 @@
-
diff --git a/tests/assets/test.rb b/tests/assets/test.rb
deleted file mode 100644
index e866cbb..0000000
--- a/tests/assets/test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-
-print "Hello, World!\n"
-
-#@todo test only
-
-=begin
-@todo
-This is slightly long
-multi line comment in Ruby
-=end
diff --git a/tests/assets/test.rs b/tests/assets/test.rs
deleted file mode 100644
index dbeef19..0000000
--- a/tests/assets/test.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// So we’re doing something complicated here, long enough that we need
-// @todo multiple lines of comments to do it! Whew! Hopefully, this comment will
-// explain what’s going on.
-sdflkjsdflkjsdaf
-
-// @todo another todo but single line
-sdl,.fjlskdfj
-//@todo numer 3
\ No newline at end of file
diff --git a/tests/assets/test.sh b/tests/assets/test.sh
deleted file mode 100644
index d901ceb..0000000
--- a/tests/assets/test.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#@todo Regular comment
-
-a = 1 # @todo Inline comment
diff --git a/tests/assets/test.tmpl b/tests/assets/test.tmpl
deleted file mode 100644
index 79db95b..0000000
--- a/tests/assets/test.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-{{/*@todo test only*/}}
-
-{{/*
-This is slightly long
-@todo
-multi line comment in Ruby
-*/}}
\ No newline at end of file
diff --git a/tests/main_test.go b/tests/main_test.go
deleted file mode 100644
index c7dd336..0000000
--- a/tests/main_test.go
+++ /dev/null
@@ -1,175 +0,0 @@
-package main_test
-
-import (
- "fmt"
- "os"
- "os/exec"
- "strings"
- "testing"
-)
-
-// TestInitsettings tests that we can properly use the settings from the .flowcat settings file
-func TestCanChooseFile(t *testing.T) {
- dirname, err := os.UserHomeDir()
- if err != nil {
- fmt.Println(err)
- }
- curcmd := exec.Command("rm", "-f", dirname+"/.flowcat")
- _, err = curcmd.Output()
- if err != nil {
- fmt.Println(err)
- }
- curcmd = exec.Command("go", "run", "main.go", "init")
- _, err = curcmd.Output()
- if err != nil {
- fmt.Println(err)
- }
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/test.go")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/test.go //@todo Regular comment /* Some multiline @todo comment comment2 */ //@todo comment 3"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
-}
-
-func TestCanUseLineOption(t *testing.T) {
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/test.go", "-l")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/test.go 4)//@todo Regular comment 6)/* Some multiline @todo comment comment2 */ 9)//@todo comment 3"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
-
-}
-
-func TestCanUseMatching(t *testing.T) {
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/multitest/test.php", "-m", "Comment")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/multitest/test.php // Comment no todo"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
-
-}
-
-func TestCanParseMultipleFiles(t *testing.T) {
-
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/multitest/")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/multitest/test.go //@todo Regular comment /* Some multiline @todo comment comment2 */ //@todo comment 3tests/assets/multitest/test.php # @todo comment 1 //@todo comment 2 /*@todo multiline comment value */ //@todo another comment # @todo comment 5 //@todo comment 4"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
-
-}
-
-// tests that we can send the output to a file and that file is not included in the scan
-func TestCanOutputToFile(t *testing.T) {
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/multitest/", "-o", "tests/assets/multitest/output.txt")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/multitest/test.go //@todo Regular comment /* Some multiline @todo comment comment2 */ //@todo comment 3tests/assets/multitest/test.php # @todo comment 1 //@todo comment 2 /*@todo multiline comment value */ //@todo another comment # @todo comment 5 //@todo comment 4"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
- curcmd := exec.Command("rm", "-f", "tests/assets/multitest/output.txt")
- _, err = curcmd.Output()
- if err != nil {
- fmt.Println(err)
- }
-
-}
-
-func TestCanUseCustomMatchInSettingsFile(t *testing.T) {
- dirname, err := os.UserHomeDir()
- if err != nil {
- fmt.Println(err)
- }
- curcmd := exec.Command("cp", "tests/assets/.flowcat1", dirname+"/.flowcat")
- _, err = curcmd.Output()
- if err != nil {
- fmt.Println(err)
- }
- cmd := exec.Command("go", "run", "main.go", "-f", "tests/assets/multitest/")
- stdout, err := cmd.Output()
-
- if err != nil {
- fmt.Println(err.Error())
- return
- }
-
- // Print the output
- //fmt.Println(string(stdout))
- want := "tests/assets/multitest/test.php // Comment no todo"
- cur := string(stdout)
- ret := strings.Replace(cur, "\n", "", -1)
- ret = strings.Replace(ret, "\t", " ", -1)
- if want != ret {
- t.Errorf("got %s, want %s", ret, want)
- }
-
- dirname, err = os.UserHomeDir()
- if err != nil {
- fmt.Println(err)
- }
- curcmd = exec.Command("rm", "-f", dirname+"/.flowcat")
- _, err = curcmd.Output()
- if err != nil {
- fmt.Println(err)
- }
-
-}
diff --git a/tests/test_runner.sh b/tests/test_runner.sh
deleted file mode 100755
index bf2511d..0000000
--- a/tests/test_runner.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#! /bin/bash
-
-#Arch is passed in as linux-amd64, linux-i386, etc
-arch=$1
-
-cd ..
-go install -v
-go get gopkg.in/yaml.v2
-#//@todo add more archs for binaries
-case $arch in
-
- "linux-amd64")
- dirsep="/"
- echo "Building binary for linux-and64"
- env GOOS=linux GOARCH=amd64 GO111MODULE=auto go build -o bin/flowcat-linux-amd64/flowcat
- ;;
-
- "linux-386")
- dirsep="/"
- echo "Building binary for linux-386"
- env GOOS=linux GOARCH=386 GO111MODULE=auto go build -o bin/flowcat-linux-386/flowcat
- ;;
-
- "darwin-arm64")
- dirsep="/"
- echo "Building binary for darwin-arm64"
- env GOOS=darwin GOARCH=arm64 GO111MODULE=auto go build -o bin/flowcat-darwin-arm64/flowcat
- ;;
-
- *)
- echo "Unable to build for $arch" && exit 1
- ;;
-esac
-
-#Start functionality tests for all binaries
-
-res=$(go test -v)
-if [ $(echo $?) -ne 0 ]; then
- echo "Tests Failed"
- exit 1
-fi
-echo "PASSED"