Crates.io | oss_porter_cli |
lib.rs | oss_porter_cli |
version | 0.1.1 |
source | src |
created_at | 2025-04-27 20:16:07.671272+00 |
updated_at | 2025-06-04 20:51:08.668355+00 |
description | Command-line interface for OSS Porter: A tool to extract and sync projects from internal to public Git repositories. |
homepage | https://github.com/normano/oss_porter |
repository | https://github.com/normano/oss_porter |
max_upload_size | |
id | 1651446 |
size | 75,711 |
oss-porter
)This directory contains the code for the oss-porter
command-line interface. This tool helps extract projects from internal Git repositories for open-sourcing and provides an interactive workflow to sync updates afterwards.
(Note: Ensure you have Rust and Cargo installed: rustup.rs)
From Crates.io (Recommended when published):
# Replace 'oss-porter' if the final published name is different
cargo install oss-porter
From Source:
git clone https://github.com/YOUR_USERNAME/oss-porter.git
cd oss-porter
cargo install --path cli
This will build the oss-porter
binary and place it in your ~/.cargo/bin
directory (if it's in your PATH).Alternatively, to build and run directly for development, navigate to the project root and use:
cargo run -p oss_porter_cli -- --help
git
command-line tool must be installed and accessible in your system's PATH.git-filter-repo
(Optional): Required only if using the extract --mode preserve
option. Install via pip (pip install git-filter-repo
) or your system's package manager.~/.oss-porter.toml
)oss-porter
relies on a configuration file to define the projects it manages.
~/.oss-porter.toml
(a hidden file in your home directory).--config <PATH_TO_FILE>
option before any command to specify a different location.oss-porter config init
to create a default file at the default location if it doesn't exist.File Format (TOML - using snake_case
keys):
# ~/.oss-porter.toml
# Optional global settings table
[settings]
# default_license = "MIT" # Default license SPDX ID
# Main table containing project definitions
[projects.your-project-id]
# REQUIRED Fields:
internal_repo_path = "/path/to/internal/repo/root" # Absolute path to the Git repository root
project_subdir = "relative/path/to/project" # Path within the repo (use "." for repo root)
output_path = "/path/for/public/version" # Absolute path for the extracted/synced public repo clone
# OPTIONAL Fields:
public_repo_url = "git@github.com:your-org/your-repo.git" # Needed for `push`
history_mode = "clean_slate" # "clean_slate" (default) or "preserve"
license = "Apache-2.0" # SPDX ID for this project
internal_branch = "main" # Internal branch for `update` (default: "main")
public_branch = "main" # Public branch for `push` (default: "main")
[projects.another-project]
# ... other project settings ...
Key Configuration Fields (using snake_case
in the TOML file):
internal_repo_path
: Required. Absolute path to the Git repository containing the internal project.project_subdir
: Required. Path relative to internal_repo_path
pointing to the directory to extract/sync. Use .
if the entire repository is the project.output_path
: Required. Absolute path to a directory where oss-porter
creates/manages the local clone of the public version. Should ideally be empty before first extract
.public_repo_url
: Optional. Git URL (SSH/HTTPS) of the public repository. Needed for push
.history_mode
: Optional. "clean_slate"
(default) or "preserve"
.license
: Optional. SPDX license identifier (e.g., "MIT"). extract
adds a placeholder file if missing.internal_branch
: Optional (defaults to "main"
). Branch in the internal repo used by update
.public_branch
: Optional (defaults to "main"
). Branch in the public repo used by push
.Run oss-porter --help
for a list of commands or oss-porter <COMMAND> --help
for details on a specific command.
config init
: Creates the default config file (~/.oss-porter.toml
).config add
: Interactively adds a new project to the config file.config remove <ID>
: Interactively removes a project from the config.config list
: Lists configured project IDs.config show <ID>
: Displays configuration for one project.config validate
: Checks if the config file can be parsed.extract <ID> [--mode <MODE>]
: Performs the initial extraction (creating output-path
). --mode
can be clean_slate
or preserve
. Requires manual review.update <ID>
: Interactively reviews and applies new commits from the internal repo (internal-branch
) to the public repo clone (output-path
). Requires .oss_porter_state.toml
in the internal subdir. Requires careful manual review.check <ID>
: Runs basic checks (dependencies, license, basic secrets) on the project in output-path
.push <ID> [-f|--force]
: Pushes the output-path
repository (configured public_branch
) to the configured public_repo_url
. -f
skips confirmation.These are the primary ways to use oss-porter
:
This workflow takes a project currently only existing inside an internal repository and prepares it for its first public release.
Initialize Config (if first time):
oss-porter config init
Define Project: Add your project's details to ~/.oss-porter.toml
. You can do this manually (using snake_case
keys), or interactively:
oss-porter config add
Follow the prompts to specify paths, branches, history mode, etc.
Perform Extraction: Run the extract command, specifying your project ID. Choose the history mode carefully.
# Using default 'clean-slate' mode
oss-porter extract your-project-id
# OR attempting history preservation (requires git-filter-repo)
oss-porter extract your-project-id --mode preserve
This creates the directory specified by output_path
and populates it with either a clean copy or filtered history, initializing it as a Git repository.
CRITICAL: Manual Review and Cleanup: This is the most important step to prevent exposing sensitive information.
cd /path/to/your/output-path
(the one specified in the config).preserve
mode): This is challenging but essential if you preserved history.
git log
, git log -p
, git grep
to search commits.trufflehog git file://.
to scan the history in the output-path
.git filter-repo
again, BFG Repo-Cleaner
) or consider abandoning history preservation and re-extracting with clean-slate
mode for safety.Cargo.toml
. Ensure all [dependencies]
, [dev-dependencies]
, etc., point to publicly available crates (e.g., from crates.io) or Git URLs. Remove or replace any path = "..."
dependencies that point to other internal-only projects. oss-porter check
can help identify these.LICENSE
file (e.g., LICENSE-MIT
, LICENSE-APACHE
) exists and contains the correct text for your chosen open-source license. Add one if missing. Check your Cargo.toml
license
field.README.md
. Explain what the project is, how to build it (cargo build
), how to run it, how to contribute (if applicable), targeting an external audience..gitignore
: Ensure it includes standard Rust ignores (/target
, Cargo.lock
if it's a library).output-path
directory to stage and commit any changes made during this review process:
git add .
git commit -m "Clean up secrets and prepare for initial release"
# Or use more granular commits
Run Final Checks:
oss-porter check your-project-id
Review the output for any remaining warnings (basic secrets, path dependencies, missing license). Address them if necessary (go back to step 4).
Prepare State File (Crucial for Future Updates):
git log
in your internal repo, perhaps filtering by the project_subdir
..oss_porter_state.toml
inside the project_subdir
within your internal repository.# .oss_porter_state.toml - Commit this to the internal repo!
last_synced_internal_commit = "hash_of_internal_commit_at_extract_time"
.oss_porter_state.toml
file to your internal repository:
# Inside the internal repository working directory
git add path/to/project_subdir/.oss_porter_state.toml
git commit -m "chore(oss-porter): Add initial sync state for <your-project-id>"
# Push this internal commit if applicable
Push to Public Repository:
public_repo_url
is correctly set in your ~/.oss-porter.toml
.oss-porter push your-project-id
Confirm the prompt (unless -f
is used). This will add the remote origin
and push your cleaned-up local output-path
repository (the configured public_branch
) to the public host.Use this workflow after the initial release to bring new changes made in the internal repository out to the public one.
Prerequisites:
.oss_porter_state.toml
file must exist and be committed within the internal project subdirectory (internal_repo_path
/project_subdir
), containing the correct hash of the last commit successfully synced to the public repo.Internal Development: Make changes and commit them within the internal repository, modifying files inside the project_subdir
. Ensure these commits are pushed to the internal_branch
specified in the config (or the default "main").
Run Interactive Update:
oss-porter update your-project-id
Review and Apply Commits:
project_subdir
.[Y]es
: Apply this commit to the local public clone (output-path
) using git am
.[n]o
: Skip this commit permanently for this session. It will likely be shown again on the next update
run unless the state advances past it.[s]kip
: Skip this commit temporarily. It will be shown again later in this session or on the next run.[A]ll
: Use with extreme caution. Apply all remaining commits non-interactively. This bypasses individual review. Stops immediately if any commit fails to apply (e.g., conflict).[q]uit
: Stop the update process now. The state file will be updated to the last successfully applied commit.Handle Conflicts: If git am
fails due to conflicts during a [Y]es
or [A]ll
action:
output_path
directory.git status
, git diff
, and your editor to resolve the conflicts in the affected files.git add .
git am --continue
(or abort with git am --abort
).oss-porter update your-project-id
. The tool will read the last successfully applied state and continue processing any remaining commits.Commit State Update: After reviewing all commits (or quitting/conflicting), the tool will show the last internal commit hash that was successfully applied.
.oss_porter_state.toml
file in your internal repository's working directory.[Y]es
(recommended) or [n]o
(you'll need to commit it manually later).CRITICAL: Manual Review and Test: The update process applies patches, but you still need to verify the result.
output_path
.cargo build
(or cargo build --release
).cargo test
.[A]ll
option.Run Checks (Optional):
oss-porter check your-project-id
Push Updates: Once satisfied with the state of the output-path
repository:
oss-porter push your-project-id
Confirm the prompt (unless -f
is used).