Skip to content

Commit

Permalink
Enhance ContentReader with New Formatting Options and Code Refactoring (
Browse files Browse the repository at this point in the history
#38)

* refact(options): improve var names and cli args

The variable names are now more intuitive, and the use of versionStr in GetVersion makes the logic easier to follow.

* feat(options): add new flags and configuration options

- Added flags for HTML, Markdown, MimeType, and LineNumbers formatting
- Introduced ShouldFormat flag to determine if any formatting options are enabled
- Updated ParseFlags to parse new command-line flags and set default values

* feat(reader): enhance content reading and formatting capabilities

- Added ContentReader struct holding a reference to Config for configuration-based content reading and formatting
- Implemented ReadAll to read content from files or stdin and aggregate results
- Introduced ReadFilesAsync for concurrent file reading using goroutines
- Added JoinAll to aggregate content from multiple sources into a single string
- Implemented ReadFile for reading and formatting content from a single file
- Added Readable to check file readability and accessibility
- Implemented IOReader for reading content from an io.Reader
- Added CreateContent to apply formatting based on configuration
- Implemented Format for HTML, Markdown, MIME type inclusion, and line numbering

* refactor(clipper): update Run function to use new ContentReader

- Updated Run to utilize the new ContentReader for reading and processing content
- Improved error handling and aggregation of content from multiple sources

* feat(cli): update main to use ContentReader and improve readability

- Replaced direct instantiation of ContentReader with configuration-driven instantiation
- Enhanced readability by defining reader and passing it to clipper.Run

* test(reader): add comprehensive tests for ContentReader functionalities

- Added tests for ReadAll with multiple files
- Added tests for ReadFile to ensure proper file reading
- Added tests for Readable to verify file accessibility checks
- Added tests for IOReader to handle reading from io.Reader
- Added tests for CreateContent with and without formatting options (HTML, Markdown)
- Added tests for JoinAll to aggregate multiple content strings

* chore(deps): update dependencies in go.mod

- Added github.com/gabriel-vasile/mimetype v1.4.4 for MIME type detection.
- Added github.com/stretchr/testify v1.9.0 for testing assertions.

Also updated indirect dependencies:
- github.com/davecgh/go-spew v1.1.1
- github.com/pmezard/go-difflib v1.0.0
- golang.org/x/net v0.26.0
- gopkg.in/yaml.v3 v3.0.1

* docs: Update README.md with new features and installation options

- Updated README.md file to include new features such as Mimetype & Codeblock.
- Revised installation instructions to provide clearer guidance on using the install script and manual installation methods.

* refactor(reader): improve code documentation and optimize error handling

- Enhanced comments across ContentReader functions for better clarity and understanding.
- Moved error check inside the goroutine before the mu.Lock() call in ReadFilesAsync to reduce mutex hold time and improve efficiency.

* refactor(reader): improve comments and add tests for JoinAll with empty contents

- Enhanced comments for better documentation in reader.go and tests.
- Added tests to cover scenarios where JoinAll receives empty contents, ensuring no extra new line is added for empty contents.
  • Loading branch information
supitsdu authored Jul 4, 2024
1 parent ed7d6bd commit 215b33d
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 280 deletions.
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Clipper is a lightweight command-line tool written in Go for copying contents to
- **Cross-Platform Compatibility:** Clipper works seamlessly on **Linux**, **macOS**, and **Windows**, providing consistent clipboard functionality across different operating systems.
- **Simple Usage:** With a straightforward command-line interface, Clipper makes it easy to copy file contents to the clipboard with just a single command.
- **Fast and Efficient:** Clipper is designed for performance and efficiency, allowing you to copy contents to the clipboard quickly and without unnecessary overhead.
- **Convenient:** Directly copy text, command output, or file contents to the clipboard in a consistent way across all supported platforms.
- **Convenient:** Directly copy text, command output, or file contents to the clipboard consistently across all supported platforms.

## Installation

Expand All @@ -16,7 +16,7 @@ Clipper is a lightweight command-line tool written in Go for copying contents to
You can install Clipper using the following command:

```sh
curl -sSL https://raw.githubusercontent.com/supitsdu/clipper/main/install.sh | sh -c
curl -sSL https://raw.githubusercontent.com/supitsdu/clipper/main/install.sh | sh
```

Or:
Expand All @@ -25,56 +25,68 @@ Or:
wget -qO- https://raw.githubusercontent.com/supitsdu/clipper/main/install.sh | sh
```

> Note: If you prefer not to use `curl ... | sh`, you can manually download and install Clipper as described below.
> [!NOTE]
> If you prefer not to use `curl ... | sh`, you can manually download and install Clipper as described below.
### Manual Installation

To use Clipper, download the appropriate binary for your operating system from the [releases page](https://github.com/supitsdu/clipper/releases) and place it in your desired location. Add the location of the binary to your system's PATH environment variable to access Clipper from anywhere on your system.
To use Clipper, download the appropriate binary for your operating system from the [releases page](https://github.com/supitsdu/clipper/releases) and place it in your desired location.

> [!IMPORTANT]
> Add the location of the binary to your system's PATH environment variable to access Clipper from anywhere on your system.
## Usage

Copy the contents of a file to the clipboard:

```sh
```shell
clipper ~/.ssh/id_ed25519.pub
```

Copy the output of any command:

```sh
```shell
go version | clipper
```

Directly copy text:

```sh
```shell
clipper -c "My awesome content!"
```

### Mimetype & Codeblock

![Code Snippet Preview](docs/assets/snippet-preview.png)

```shell
clipper -Mime -Markdown path/to/your-file.js
```

## Contributing 🤝

Contributions to Clipper are welcome! Here are a few ways you can contribute:

- **Report Bugs:** If you encounter any bugs or unexpected behavior while using Clipper, please [open an issue](https://github.com/supitsdu/clipper/issues) on GitHub to report it.
- **Request Features:** Have an idea for a new feature or improvement? [Open an issue](https://github.com/supitsdu/clipper/issues) to share your suggestion and start a discussion.
- **Submit Pull Requests:** If you're comfortable with Go programming, you can contribute directly to the development of Clipper by submitting pull requests. Fork the repository, make your changes, and submit a pull request for review.
- **Submit Pull Requests:** If you're comfortable with Go programming, you can contribute directly to the development of Clipper by submitting pull requests. Fork the repository, make changes, and submit a pull request for review.

## Building from Source

To build Clipper from source, you'll need to have Go installed on your system, as well as the Make tool.
To build Clipper from source, you'll need to have Go installed on your system and the Make tool.

### Requirements

- **Go Lang:** Clipper is written in Go, so you'll need to have Go installed on your system. You can download and install it from the [official Go website](https://golang.org/).
- **Go Lang:** Clipper is written in Go, so you'll need Go installed on your system. You can download and install it from the [official Go website](https://golang.org/).
- **Make Tool:** Building Clipper from source requires the Make tool to automate the build process. Make is commonly pre-installed on Unix-like systems, but you may need to install it manually on Windows.

Once you have the necessary requirements installed, clone the repository and run the following command in the project directory:
Once you have the requirements installed, clone the repository and run the following command in the project directory:

```sh
make
```

This command will build binaries for Windows, Linux, and macOS in the `bin` directory.
This command will build Clipper for Windows, Linux, and macOS inside the `bin` directory.

## License

Expand Down
9 changes: 3 additions & 6 deletions cli/clipper/clipper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/atotto/clipboard"
"github.com/supitsdu/clipper/cli/options"
"github.com/supitsdu/clipper/cli/reader"
)

Expand All @@ -22,13 +21,11 @@ func (c DefaultClipboardWriter) Write(content string) error {
}

// Run executes the core logic of the Clipper tool.
func Run(config *options.Config, writer ClipboardWriter) (string, error) {
readers := reader.GetReaders(config.Args...)

func Run(reader reader.ContentReader, writer ClipboardWriter) (string, error) {
// Aggregate the content from the provided sources.
content, err := reader.ParseContent(config.DirectText, readers...)
content, err := reader.ReadAll()
if err != nil {
return "", fmt.Errorf("parsing content: %w", err)
return "", err
}

// Write the parsed content to the provided clipboard.
Expand Down
7 changes: 5 additions & 2 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/supitsdu/clipper/cli/clipper"
"github.com/supitsdu/clipper/cli/options"
"github.com/supitsdu/clipper/cli/reader"
)

func main() {
Expand All @@ -18,10 +19,12 @@ func main() {

writer := clipper.DefaultClipboardWriter{} // Create the default clipboard writer

msg, err := clipper.Run(config, writer) // Run the main Clipper logic
reader := reader.ContentReader{Config: config}

msg, err := clipper.Run(reader, writer) // Run the main Clipper logic
if err != nil {
fmt.Printf("Error %s\n", err)
os.Exit(1) // Exit with an error code
os.Exit(1)
}

fmt.Println(msg)
Expand Down
42 changes: 30 additions & 12 deletions cli/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package options
import (
"flag"
"fmt"
"os"
"strings"
)

type Config struct {
DirectText string
ShowVersion bool
Args []string
Text string
FilePaths []string
Html bool
Markdown bool
MimeType bool
LineNumbers bool
ShouldFormat bool
ShowVersion bool
}

// Package-level variables for version information (set at build time or default)
Expand All @@ -20,33 +26,45 @@ var (

// GetVersion formats the version string for display
func GetVersion() string {
versionStr := strings.TrimSpace(Version)

if BuildMetadata != "" {
return strings.TrimSpace(Version) + " " + strings.TrimSpace(BuildMetadata)
} else {
return strings.TrimSpace(Version)
versionStr += " " + strings.TrimSpace(BuildMetadata)
}

return versionStr
}

// ParseFlags parses the command-line flags and arguments.
func ParseFlags() *Config {
directText := flag.String("c", "", "Copy text directly from command line argument")
text := flag.String("c", "", "Copy text directly from command line argument")
htmlWrap := flag.Bool("Html", false, "Each file data is put within an HTML5 codeblock.")
markdownWrap := flag.Bool("Markdown", false, "Each file data is put within an Markdown codeblock.")
mimeType := flag.Bool("Mime", false, "Include mimetype for each file")
lineNumbers := flag.Bool("LineNumbers", false, "Add line numbers to the content.")
showVersion := flag.Bool("v", false, "Show the current version of the clipper tool")

flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Clipper is a lightweight command-line tool for copying contents to the clipboard.\n")
fmt.Fprintf(flag.CommandLine.Output(), "\nUsage:\n")
fmt.Fprintf(flag.CommandLine.Output(), " clipper [arguments] [file ...]\n")
fmt.Fprintf(flag.CommandLine.Output(), "\nArguments:\n")
fmt.Fprintf(flag.CommandLine.Output(), " -c <string> Copy text directly from command line argument\n")
fmt.Fprintf(flag.CommandLine.Output(), " -v Show the current version of the clipper tool\n")
flag.PrintDefaults()
fmt.Fprintf(flag.CommandLine.Output(), "\nIf no file or text is provided, reads from standard input.\n")
}

flag.CommandLine.SetOutput(os.Stderr)

flag.Parse()

return &Config{
DirectText: *directText,
ShowVersion: *showVersion,
Args: flag.Args(),
Text: *text,
FilePaths: flag.Args(),
Html: *htmlWrap,
Markdown: *markdownWrap,
MimeType: *mimeType,
LineNumbers: *lineNumbers,
ShowVersion: *showVersion,
ShouldFormat: *htmlWrap || *mimeType || *markdownWrap || *lineNumbers,
}
}
Loading

0 comments on commit 215b33d

Please sign in to comment.