nushell-plugins/nu_plugin_port_extension
Jesús Pérez 2b3e574e3d # Summary
fix: help system integration, build process optimization, and plugin rebuild efficiency

## Detailed Description

This commit addresses critical issues in the help system discoverability, build process robustness, and plugin rebuild efficiency.

### 1. Help System Integration (New Feature)

**Issue**: Version-update module recipes were not discoverable
- Not shown in `just help modules`
- Not referenced in `just help`
- Not included in help navigation system
- Users had to manually run `just --list` to find update commands

**Solution**:
- Added version-update module to all help outputs
- Updated `justfiles/help.just` to document all 30+ version-update recipes
- Created new `just commands` recipe as discoverable alias for `just --list`
- Integrated version-update into help-all workflow

**Impact**:
- Version-update commands now fully discoverable via help system
- Users can find update commands with: `just help modules`, `just help`, `just commands`
- Improved overall help system navigation

**Files Modified**:
- `justfiles/help.just` (+23 lines)
  - Added version-update module to help sections
  - Added to modules list
  - Added to help-all workflow
  - New `commands` recipe showing all recipes by group

### 2. Build Process Fixes (Phase 3: Bin Archives)

#### 2a. Plugin Archive Collection Bug

**Issue**: "No plugins found to package" warning in Phase 3
- Collected 26 plugin binaries but reported 0
- Archive creation skipped because count was wrong

**Root Cause**: `each` command returns null, so `| length` returned 0
```nushell
#  OLD - each returns null
let plugin_count = (ls nu_plugin_*/target/release/nu_plugin_* | each {|p|
    cp $p.name $"($temp_dir)/"
} | length)  # Returns 0!
```

**Solution**: Separated counting from copying with proper filtering
```nushell
#  NEW - count before operations
let plugins_to_copy = (ls nu_plugin_*/target/release/nu_plugin_* | where type == "file")
let plugin_count = ($plugins_to_copy | length)
```

**Impact**:
- Now correctly collects and reports 26 plugins
- Filters out .d dependency files automatically
- Warning eliminated

#### 2b. Tar Archive Path Handling

**Issue**: Tar command failing silently with relative paths in subshell
- `cd $temp_dir` changes context unpredictably
- Relative path `../$archive_name` fails in subshell
- Archive file not created despite exit code 0

**Root Cause**: Shell context and relative path issues in Nushell `do` block

**Solution**: Used `tar -C` with absolute paths instead of `cd`
```nushell
#  OLD - unreliable context switching
do {
    cd $temp_dir
    tar -czf ../$archive_name .
}

#  NEW - absolute paths, no context switching
tar -C $temp_dir -czf $archive_path .
```

**Additional Improvements**:
- Absolute path construction using `pwd | path join`
- Better error diagnostics with exit code and stderr output
- File verification after creation

**Impact**:
- Tar archives now created successfully
- Robust path handling across platforms
- Clear error messages for debugging

#### 2c. File Size Calculation Type Error

**Issue**: Runtime error when calculating archive size
```
Error: The '/' operator does not work on values of type 'list<filesize>'
```

**Root Cause**: `ls` returns list of records, so `.size` was a list
```nushell
#  OLD - returns list<filesize>
(ls $archive_path).size / 1024 / 1024

#  NEW - returns filesize
(ls $archive_path | get 0.size) / 1024 / 1024
```

**Impact**:
- Proper file size calculation in MB
- No more type errors

**Files Modified**:
- `scripts/create_full_distribution.nu` (+58 lines, refactored plugin collection)
  - Fixed plugin counting logic
  - Improved path handling with absolute paths
  - Enhanced error diagnostics

### 3. Plugin Rebuild Optimization

**Issue**: All plugins marked for rebuild even when dependencies unchanged
- Step 4 (`update_all_plugins.nu`) touched all Cargo.toml files at 01:00:32
- Step 5 saw all files as "newer" than binaries
- Marked ALL plugins for rebuild, though cargo only rebuilt changed ones

**Root Cause**: Script always saved files, even when no changes made
```nushell
#  OLD - always saves, touching file timestamp
$updated_content | to toml | save -f $cargo_toml
```

**Solution**: Only save if content actually changed
```nushell
#  NEW - compare before writing
let original_toml = $content | to toml
let new_toml = $updated_content | to toml

if $original_toml != $new_toml {
    $updated_content | to toml | save -f $cargo_toml
}
```

**Impact**:
- Unchanged files preserve original timestamps
- Only plugins with actual dependency changes are rebuilt
- Efficient rebuild process with accurate file modification detection

**Files Modified**:
- `scripts/update_all_plugins.nu` (+12 lines, added content comparison)
  - Only touches files with real changes
  - Preserves timestamps for efficiency
  - Clearer logic and comments

### 4. Documentation

**Files Modified**:
- `CHANGELOG.md` (+56 lines)
  - Added comprehensive 2025-10-19 entry
  - Documented all fixes with root causes
  - Listed files modified and impact summary

## Technical Details

### Nushell Patterns Used

1. **Proper List Handling**:
   - `ls` returns list of records, access with `| get 0.size`
   - Filter with `where type == "file"` to exclude metadata

2. **Absolute Path Construction**:
   - `pwd | append "path" | path join` for cross-platform paths
   - Safer than string concatenation with `/`

3. **Content Comparison**:
   - Compare TOML string representation before saving
   - Preserves file timestamps for efficiency

4. **Error Diagnostics**:
   - Capture `stderr` from commands
   - Report exit codes and error messages separately

## Testing

- [x] Help system shows version-update module
- [x] `just commands` displays all recipes by group
- [x] Phase 3 bin archive creation works
- [x] Plugin collection reports correct count (26)
- [x] Tar archives created successfully
- [x] File size calculated correctly
- [x] Plugin rebuild only touches changed files
- [x] CHANGELOG updated with all changes

## Files Changed

```
38 files changed, 2721 insertions(+), 2548 deletions(-)

Core Changes:
- justfiles/help.just                  (+23)  Help system integration
- scripts/create_full_distribution.nu  (+58)  Build process fixes
- scripts/update_all_plugins.nu        (+12)  Rebuild optimization
- CHANGELOG.md                         (+56)  Documentation

Dependency Updates:
- All plugin Cargo.toml and Cargo.lock files (version consistency)
```

## Breaking Changes

None. These are bug fixes and optimizations that maintain backward compatibility.

## Migration Notes

No migration needed. Improvements are transparent to users.

## Related Issues

- Help system discoverability
- Build process Phase 3 failures
- Unnecessary plugin rebuilds
- Build process reliability

## Checklist

- [x] Changes follow Rust/Nushell idioms
- [x] Code is well-commented
- [x] Error handling is comprehensive
- [x] Documentation is updated
- [x] All changes tested
- [x] No breaking changes introduced
2025-10-19 01:17:13 +01:00
..
2025-06-27 02:31:23 +01:00
2025-06-27 02:31:23 +01:00
2025-06-27 02:31:23 +01:00
2025-10-19 01:17:13 +01:00
2025-10-19 01:17:13 +01:00
2025-06-27 02:31:23 +01:00
2025-06-27 02:31:23 +01:00
2025-06-27 02:31:23 +01:00
2025-06-27 02:31:23 +01:00

🔌 nu_plugin_port_extension

A Nushell plugin for inspecting open ports and scanning network services. It introduces two subcommands:

  • port list: Lists all open network connections, similar to netstat.
  • port scan: Scans a target IP and port to determine if it is open.

Features

port list List Active Connections

The port list command retrieves all open connections on the network interface. It supports filtering by protocol, IP version, and listening state.

📌 Usage

port list {flags}

⚙️ Available Flags

  • -h, --help → Show help message.
  • -6, --disable-ipv4 → Exclude IPv4 connections (only show IPv6).
  • -4, --disable-ipv6 → Exclude IPv6 connections (only show IPv4).
  • -t, --disable-udp → Exclude UDP connections (only show TCP).
  • -u, --disable-tcp → Exclude TCP connections (only show UDP).
  • -l, --listeners → Show only listening connections (state == "LISTEN").
  • -p, --process-info → Include process details (name, command, binary path).

🔍 Example: Show Active Processes

port list -p | take 1

📊 Example Output

pid type ip_version local_address local_port remote_address remote_port state process_name cmd exe_path
11536 tcp 4 127.0.0.1 1093 127.0.0.1 1108 ESTABLISHED steam.exe [C:\Program Files (x86)\Steam\steam.exe, -silent] C:\Program Files (x86)\Steam\steam.exe

port scan Scan Open Ports

The port scan command checks if a specific port is open on a target IP, similar to nc -vz {ip} {port}.

⚠️ Note: Only TCP scanning is supported at the moment.

📌 Usage

port scan {flags} <target IP> <port>

⚙️ Available Flags

  • -h, --help → Show help message.
  • -t, --timeout <duration> → Set timeout before giving up (default: 60s).
  • -s, --send <string> → Send data to the target upon connection.
  • -b, --receive-byte-count <int> → Number of bytes to receive before confirming the connection is open.

🎯 Parameters

  • target IP (string) The IP address to scan.
  • port (integer) The port number to check.

🔍 Example: Check if Google's Public DNS (8.8.8.8) has Port 53 Open

port scan 8.8.8.8 53 -t 1sec

📊 Example Output

╭─────────┬─────────╮  
│ address │ 8.8.8.8 │  
│ port    │ 53      │  
│ is_open │ true    │  
│ elapsed │ 40ms    │  
╰─────────┴─────────╯  

🔄 Example: Scan a Range of Ports on 127.0.0.1 and Filter Open Ports

7880..8000 | each { |it| port scan 127.0.0.1 $it -t 1ms } | where result == Open

🔧 Installation

This method automatically handles dependencies and features.

git clone https://github.com/FMotalleb/nu_plugin_port_extension.git  
nupm install --path nu_plugin_port_extension -f  

🛠️ Manual Compilation

git clone https://github.com/FMotalleb/nu_plugin_port_extension.git  
cd nu_plugin_port_extension  
cargo build -r  
plugin add target/release/nu_plugin_port_extension  

📦 Install via Cargo (using git)

cargo install --git https://github.com/FMotalleb/nu_plugin_port_extension.git  
plugin add ~/.cargo/bin/nu_plugin_port_extension  

Since I live in Iran and crates.io often restricts package updates, the version there might be outdated.

cargo install nu_plugin_port_extension  
plugin add ~/.cargo/bin/nu_plugin_port_extension