
    $iw.                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZ e G d	 d
             Ze
eeeegef   Ze
ee   gef   ZdZ ed      Z G d d      Zy)u  
core/evolution/gitops_pr_creator.py

Story 8.07: GitOpsPRCreator — GitHub PR Automation

Opens a GitHub PR with proposed architectural changes and Shadow Arena results.
Creates a branch, writes proposed files, commits them, pushes, and opens a PR
via the GitHub REST API.

All external I/O (HTTP calls and git subprocess calls) is dependency-injected
so this class is fully testable without any real network or git access.

Usage::

    creator = GitOpsPRCreator(
        github_token=os.environ["GITHUB_TOKEN"],
        github_repo=os.environ["GITHUB_REPO"],
    )
    pr_result = creator.create_pr(proposal, arena_result, epoch_id="epoch_042")
    print(pr_result.pr_url)
    )annotationsN)	dataclass)Path)AnyCallableOptional)CodeProposal)ArenaResultc                  0    e Zd ZU dZded<   ded<   ded<   y)PRResultzResult of a GitHub PR creation.

    Attributes:
        pr_url:      Full HTTPS URL of the opened pull request.
        branch_name: The feature branch that was created and pushed.
        pr_number:   The pull request number within the repository.
    strpr_urlbranch_nameint	pr_numberN)__name__
__module____qualname____doc____annotations__     9/mnt/e/genesis-system/core/evolution/gitops_pr_creator.pyr   r   &   s     KNr   r   zhttps://api.github.comz/mnt/e/genesis-systemc                      e Zd ZdZ	 	 	 	 d		 	 	 	 	 	 	 	 	 d
dZ	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 ddZddZe	 	 	 	 	 	 	 	 	 	 dd       Z	edd       Z
y)GitOpsPRCreatora  Creates GitHub PRs for Genesis auto-refactor proposals.

    Orchestrates:
    1. Creating a new branch from ``main``.
    2. Writing the proposed source and test files to the repo.
    3. Git add, commit, and push.
    4. Opening a PR via the GitHub REST API.

    All external dependencies are dependency-injected so tests can exercise
    every code path without real git or HTTP access.

    Args:
        github_token: GitHub personal access token with ``repo`` scope.
                      Falls back to the ``GITHUB_TOKEN`` environment variable
                      if not provided.
        github_repo:  Repository in ``owner/repo`` format.
                      Falls back to the ``GITHUB_REPO`` environment variable
                      if not provided.
        http_client:  Callable matching the signature
                      ``(method: str, url: str, headers: dict, json: dict) -> dict``.
                      When ``None``, a built-in ``urllib`` implementation is used.
        git_runner:   Callable matching the signature
                      ``(args: list[str]) -> str``.
                      When ``None``, subprocess git calls against ``_REPO_ROOT``
                      are used.
    Nc                    |xs  t         j                  j                  dd      | _        |xs  t         j                  j                  dd      | _        |xs | j
                  | _        |xs | j                  | _        y )NGITHUB_TOKEN GITHUB_REPOz
owner/repo)	osenvirongettokenrepo_default_http_clienthttp_default_git_runnergit)selfgithub_tokengithub_repohttp_client
git_runners        r   __init__zGitOpsPRCreator.__init__c   s^     'L"**..*L
$S

}l(S	"-"J1J1J	 * Fd.F.Fr   c           
        d| }| j                  dd|dg       | j                  |j                  |j                         | j                  |j                  |j
                         | j                  d|j                  |j                  g       | j                  ddd|j                   d	| g       | j                  d
d|g       d|j                   d	| }| j                  |||      }| j                  dt         d| j                   dd| j                   ddd|||dd      }t        |j                  dd      |t        |j                  dd                  S )a  Create a GitHub PR for the given proposal.

        Steps
        -----
        1. Derive branch name from epoch_id.
        2. Checkout new branch from ``main`` via ``git_runner``.
        3. Write proposed source and test files to the E: drive repo.
        4. Git add + commit + push.
        5. Open PR via GitHub REST API using ``http_client``.
        6. Return a ``PRResult`` with the PR URL, branch name, and number.

        Args:
            proposal:     The ``CodeProposal`` containing paths and code content.
            arena_result: The ``ArenaResult`` from the Shadow Arena evaluation.
            epoch_id:     Unique epoch identifier (e.g. ``"epoch_042"``).

        Returns:
            ``PRResult`` with ``pr_url``, ``branch_name``, and ``pr_number``.
        zgenesis-auto-refactor-checkoutz-bmainaddcommitz-mz[Genesis Auto] u    — Epoch pushoriginPOSTz/repos/z/pullszBearer zapplication/vnd.github.v3+jsonzapplication/json)AuthorizationAcceptzContent-Type)titlebodyheadbase)headersjsonhtml_urlr   numberr   )r   r   r   )r(   _write_file	file_pathcode_contenttest_file_pathtest_content_build_pr_bodyr&   _GITHUB_API_BASEr$   r#   r   r"   r   )r)   proposalarena_resultepoch_idbranchr9   pr_bodyresponses           r   	create_przGitOpsPRCreator.create_prs   s~   2 *(4 	*dFF34 	++X-B-BC00(2G2GH 	%++X-D-DEF!("4"4!5[
K	
 	&(F+, "("4"4!5[
K%%hhG99 		{&9#*4::,!7: 2 	  
  <<
B/(,,x34
 	
r   c                *   |j                   j                  dg       }|rdj                  |      nd}|j                  }|rdj                  |      nd}|j                  }g }	|j                         D ]E  \  }
}t        |t              r|	j                  d|
 d|d       /|	j                  d|
 d|        G |	rdj                  |	      nd}d	| d
|j                   d|j                   d|j                  dd|j                   d| d| d| d| dS )a  Build the PR body markdown string.

        Includes Shadow Arena results and improved metrics for reviewer context.

        Args:
            proposal:     The ``CodeProposal`` containing bottleneck scar IDs
                          (via ``config_changes`` if present).
            arena_result: The arena evaluation result.
            epoch_id:     The evolution epoch identifier.

        Returns:
            A formatted markdown string suitable for a GitHub PR body.
        scar_idsz, Nonez- **z**: z.4f
z- No metrics recordedu#   ## Genesis Auto-Refactor — Epoch z#

### Proposed Change
- **File**: `z`
- **Test File**: `z-`

### Shadow Arena Results
- **Pass Rate**: z.1%z
- **Ready for PR**: z
- **Axiom Violations**: z

### Improved Metrics
z

### Bottleneck Scar IDs
u<   

---
*Auto-generated by Genesis Evolution Engine — Epoch z*
)config_changesr"   joinaxiom_violationsimproved_metricsitems
isinstancefloatappendrB   rD   	pass_rateready_for_pr)r)   rH   rI   rJ   rP   scar_ids_str
violationsviolations_strmetricsmetrics_lineskeyvaluemetrics_strs                r   rF   zGitOpsPRCreator._build_pr_body   sb   ( **..z2>.6tyy*F "22
2<:.& //#%!--/ 	>JC%'$$tC5U3K%@A$$tC5UG%<=		>
 3@dii.E\6xj A   ! "**+ , ((- .!../ 0'( )    7 8@j A% 	r   c                v    t         |z  }|j                  j                  dd       |j                  |d       y)a,  Write content to a file under the repo root (E: drive).

        Creates parent directories as needed.

        Args:
            relative_path: Path relative to the repo root (e.g.
                           ``"core/interceptors/fix.py"``).
            content:       File content to write.
        T)parentsexist_okutf-8)encodingN)
_REPO_ROOTparentmkdir
write_text)r)   relative_pathcontenttargets       r   rA   zGitOpsPRCreator._write_file   s8     m+D48'G4r   c                z   ddl }ddl}|j                  |      j                  d      }|j                  j                  ||||       }	 |j                  j                  |d      5 }|j                         j                  d      }	|j                  |	      cddd       S # 1 sw Y   yxY w# t        $ r i cY S w xY w)ae  Built-in HTTP client using ``urllib`` (no external dependencies).

        Args:
            method:  HTTP method string (e.g. ``"POST"``).
            url:     Full URL to request.
            headers: Request headers dict.
            json:    JSON body dict.

        Returns:
            Parsed JSON response dict.  Returns ``{}`` on any error.
        r   Nrh   )datar=   method   )timeout)r>   urllib.requestdumpsencoderequestRequesturlopenreaddecodeloads	Exception)
rs   urlr=   r>   _jsonurllibpayloadreqrespr:   s
             r   r%   z$GitOpsPRCreator._default_http_client
  s    $ 	++d#**73nn$$	 % 
	''R'8 )Dyy{))'2{{4() ) )  	I	s0   	B, &0B 	B,  B)%B, )B, ,B:9B:c                   ddl }|j                  dg| z   t        t              dd      }|j                  |j
                  z   }|j                  dk7  r-t        ddj                  |        d|j                   d	|       |S )
az  Built-in git runner using subprocess.

        Runs ``git`` in the ``_REPO_ROOT`` directory (E: drive).

        Args:
            args: List of git arguments (e.g. ``["checkout", "-b", "my-branch"]``).

        Returns:
            Combined stdout + stderr output as a string.

        Raises:
            RuntimeError: If the git command returns a non-zero exit code.
        r   Nr(   T)cwdcapture_outputtextzgit  z failed (exit z):
)	
subprocessrunr   rj   stdoutstderr
returncodeRuntimeErrorrT   )argsr   resultoutputs       r   r'   z#GitOpsPRCreator._default_git_runner-  s     	GdNJ	   
 .!sxx~&nV5F5F4GtF8T  r   )NNNN)
r*   Optional[str]r+   r   r,   zOptional[HttpClientFn]r-   zOptional[GitRunnerFn]returnrQ   )rH   r	   rI   r
   rJ   r   r   r   )rH   r	   rI   r
   rJ   r   r   r   )rn   r   ro   r   r   rQ   )
rs   r   r   r   r=   dict[str, Any]r>   r   r   r   )r   z	list[str]r   r   )r   r   r   r   r.   rN   rF   rA   staticmethodr%   r'   r   r   r   r   r   G   s	   : '+%).2,0
G#
G #
G ,	
G
 *
G 

G E
E
 "E
 	E

 
E
V88 "8 	8
 
8t5$        	 
 
   D  r   r   )r   
__future__r   r    dataclassesr   pathlibr   typingr   r   r   core.evolution.code_proposerr	   core.evolution.shadow_arenar
   r   r   dictHttpClientFnlistGitRunnerFnrG   rj   r   r   r   r   <module>r      s   , # 	 !  * * 5 3   & c4.45 S	{C'( , )*
B Br   