Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,38 @@ jobs:
# Test that wrapper works with current version
./mvx version

- name: Check for website changes
uses: dorny/paths-filter@v3
id: website-changes
with:
filters: |
website:
- 'website/**'

- name: Set up JDK 21 for website
if: steps.website-changes.outputs.website == 'true'
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven

- name: Check website build
if: steps.website-changes.outputs.website == 'true'
run: |
OWNER=$(echo "$GITHUB_REPOSITORY" | cut -d '/' -f 1)
REPO=$(echo "$GITHUB_REPOSITORY" | cut -d '/' -f 2)
SITE_URL="https://${OWNER}.github.io"
SITE_PATH="/${REPO}/"
echo "SITE_URL=$SITE_URL" >> $GITHUB_ENV
echo "SITE_PATH=$SITE_PATH" >> $GITHUB_ENV
echo "GITHUB_REPOSITORY=$GITHUB_REPOSITORY SITE_DIR=$SITE_DIR SITE_URL=$SITE_URL SITE_PATH=$SITE_PATH"
# Build website to catch template syntax errors
cd website
QUARKUS_ROQ_GENERATOR_BATCH=true mvn clean package quarkus:run -DskipTests --no-transfer-progress \
-Dquarkus.http.root-path=$SITE_PATH \
-Dsite.url=$SITE_URL

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Imagine cloning any project and running:
# Or use tools directly with natural syntax
./mvx mvn -V clean install # Maven with version flag
./mvx --verbose mvn -X test # mvx verbose + Maven debug

# Execute shell commands in mvx environment
./mvx shell 'echo $JAVA_HOME' # Show Java home with mvx tools
./mvx shell 'java -version' # Run Java with mvx environment
```

No more "works on my machine" - every developer gets the exact same environment.
Expand Down Expand Up @@ -54,6 +58,7 @@ mvx provides seamless Maven integration with transparent argument passing:
- **πŸ”„ Transparent wrapper**: mvx acts like `mvnw` but with enhanced tool management
- **⚑ No learning curve**: Existing Maven knowledge applies directly
- **πŸ›‘οΈ Backward compatible**: Existing scripts continue to work
- **🏒 Enterprise ready**: URL replacements for corporate networks and mirrors

## πŸ“¦ mvx Bootstrap

Expand Down Expand Up @@ -199,6 +204,37 @@ cd mvx
./mvx test
```

## πŸ”„ Shell Activation

For a seamless development experience, enable shell activation to automatically set up your environment when entering project directories:

**Bash** - Add to `~/.bashrc`:
```bash
eval "$(mvx activate bash)"
```

**Zsh** - Add to `~/.zshrc`:
```bash
eval "$(mvx activate zsh)"
```

**Fish** - Add to `~/.config/fish/config.fish`:
```bash
mvx activate fish | source
```

With shell activation enabled, tools become available automatically:

```bash
cd my-project
# mvx: activating environment in /Users/you/my-project

java -version # Uses mvx-managed Java
mvn -version # Uses mvx-managed Maven
```

**Learn more**: See the [Shell Activation Guide](https://gnodet.github.io/mvx/shell-activation/) for detailed documentation.

## 🎯 Shell Completion

mvx supports shell completion for commands and arguments across multiple shells (bash, zsh, fish, powershell):
Expand Down Expand Up @@ -354,6 +390,7 @@ The bootstrap scripts (`mvx` and `mvx.cmd`) are **shell/batch scripts** (not bin
- [x] `mvx build` - Execute configured build commands
- [x] `mvx test` - Execute configured test commands
- [x] `mvx run` - Execute custom commands from configuration
- [x] `mvx shell` - Execute shell commands in mvx environment
- [x] `mvx tools` - Tool management and discovery
- [x] `mvx info` - Detailed command information

Expand Down Expand Up @@ -397,6 +434,12 @@ The bootstrap scripts (`mvx` and `mvx.cmd`) are **shell/batch scripts** (not bin
- [x] **Intelligent interpreter selection** - Automatic selection based on script complexity
- [x] **Cross-platform compatibility** - Commands work consistently across operating systems

#### Enterprise & Network Support

- [x] **URL replacements** - Redirect downloads through corporate proxies, mirrors, or alternative sources
- [x] **Global configuration** - System-wide settings for enterprise environments
- [x] **Regex-based URL transformations** - Advanced URL rewriting for complex enterprise setups

### 🚧 Planned Features

#### Extended Tool Support
Expand Down
148 changes: 148 additions & 0 deletions cmd/activate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package cmd

import (
"fmt"
"os"
"path/filepath"

"github.com/gnodet/mvx/pkg/shell"
"github.com/spf13/cobra"
)

// activateCmd represents the activate command
var activateCmd = &cobra.Command{
Use: "activate [shell]",
Short: "Generate shell integration code for automatic environment activation",
Long: `Generate shell integration code that automatically activates mvx when entering
directories with .mvx configuration.

This command outputs shell-specific code that should be evaluated in your shell's
configuration file (e.g., ~/.bashrc, ~/.zshrc, ~/.config/fish/config.fish).

When activated, mvx will:
- Detect when you enter a directory with .mvx configuration
- Automatically update PATH with mvx-managed tools
- Set up environment variables from your configuration
- Cache the environment to avoid repeated setup

Supported shells:
- bash
- zsh
- fish
- powershell

Examples:
# Bash - add to ~/.bashrc
eval "$(mvx activate bash)"

# Zsh - add to ~/.zshrc
eval "$(mvx activate zsh)"

# Fish - add to ~/.config/fish/config.fish
mvx activate fish | source

# PowerShell - add to $PROFILE
Invoke-Expression (mvx activate powershell | Out-String)

After adding to your shell configuration, restart your shell or source the file:
source ~/.bashrc # bash
source ~/.zshrc # zsh
source ~/.config/fish/config.fish # fish

Configuration:
MVX_VERBOSE=true # Enable verbose output to see what mvx is doing`,

Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
shellType := args[0]

// Validate shell type
validShells := []string{"bash", "zsh", "fish", "powershell"}
isValid := false
for _, s := range validShells {
if s == shellType {
isValid = true
break
}
}

if !isValid {
printError("Unsupported shell: %s", shellType)
printError("Supported shells: bash, zsh, fish, powershell")
os.Exit(1)
}

// Get the path to the mvx binary
mvxPath, err := getMvxBinaryPath()
if err != nil {
printError("Failed to determine mvx binary path: %v", err)
os.Exit(1)
}

// Generate shell hook
hook, err := shell.GenerateHook(shellType, mvxPath)
if err != nil {
printError("Failed to generate shell hook: %v", err)
os.Exit(1)
}

// Output the hook (this will be evaluated by the shell)
fmt.Print(hook)
},
}

// deactivateCmd represents the deactivate command
var deactivateCmd = &cobra.Command{
Use: "deactivate",
Short: "Deactivate mvx shell integration",
Long: `Deactivate mvx shell integration for the current shell session.

This command is automatically available after running 'mvx activate' and
removes mvx-managed tools from PATH and unsets mvx environment variables.

Note: This only affects the current shell session. To permanently disable
mvx activation, remove the 'eval "$(mvx activate ...)"' line from your
shell configuration file.

Examples:
mvx deactivate # Remove mvx from current session`,

Run: func(cmd *cobra.Command, args []string) {
// This command is primarily handled by the shell hook itself
// When called directly, we just provide information
printInfo("To deactivate mvx in your current shell session:")
printInfo("")
printInfo(" Bash/Zsh:")
printInfo(" Run: mvx_deactivate")
printInfo("")
printInfo(" Fish:")
printInfo(" Run: mvx_deactivate")
printInfo("")
printInfo(" PowerShell:")
printInfo(" Run: mvx-deactivate")
printInfo("")
printInfo("To permanently disable mvx activation, remove the activation")
printInfo("line from your shell configuration file:")
printInfo(" - Bash: ~/.bashrc")
printInfo(" - Zsh: ~/.zshrc")
printInfo(" - Fish: ~/.config/fish/config.fish")
printInfo(" - PowerShell: $PROFILE")
},
}

// getMvxBinaryPath returns the path to the mvx binary
func getMvxBinaryPath() (string, error) {
// Try to get the path from the current executable
exePath, err := os.Executable()
if err != nil {
return "", fmt.Errorf("failed to get executable path: %w", err)
}

// Resolve symlinks
exePath, err = filepath.EvalSymlinks(exePath)
if err != nil {
return "", fmt.Errorf("failed to resolve symlinks: %w", err)
}

return exePath, nil
}
Loading