o
    s                     @   s   d Z ddlmZ ddlm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
 dd	lmZ ddlZdd
lmZ G dd deZdd ZdS )zKContains utilities for comparing RELEASE_NOTES between Cloud SDK versions.
    )absolute_import)division)unicode_literalsN)config)log)render_document)
installers)StringIOc                   @   sF   e Zd ZdZdZdZedddZdd Zd	d
 Z	dd Z
dd ZdS )ReleaseNotesa  Represents a parsed RELEASE_NOTES file.

  The file should have the general structure of:

  # Google Cloud SDK - Release Notes

  Copyright 2014-2015 Google LLC. All rights reserved.

  ## 0.9.78 (2015/09/16)

  *   Note
  *   Note 2

  ## 0.9.77 (2015/09/09)

  *   Note 3
  z6(?<=\n)\n## +(?P<version>\S+).*\n(?:\n.*(?!\n\n## ))+.   Nc                 C   sj   zt ||}|du rW dS |j}|tjjkrW dS | |jW S  ty4   tj	dj
|ddd Y dS w )a  Parses release notes from the given URL using the requests library.

    Any error in downloading or parsing release notes is logged and swallowed
    and None is returned.

    Args:
      url: str, The URL to download and parse.
      command_path: str, The command that is calling this for instrumenting the
        user agent for the download.

    Returns:
      ReleaseNotes, the parsed release notes or None if an error occurred.
    NzFailed to download [{url}])urlT)exc_info)r   MakeRequeststatus_coderequestscodesoktext	Exceptionr   debugformat)clsr   command_pathresponsecode r   F/tmp/google-cloud-sdk/lib/googlecloudsdk/core/updater/release_notes.pyFromURLA   s   zReleaseNotes.FromURLc                 C   sN   | dd| _g }ttj| jD ]}||d|  f q|| _	dS )zParse the release notes from the given text.

    Args:
      text: str, The text of the release notes to parse.

    Returns:
      ReleaseNotes, the parsed release notes.
    z

versionN)
replace_textrefinditerr
   _VERSION_SPLIT_REGEXappendgroupstrip	_versions)selfr   versionsmr   r   r   __init__`   s
   	
zReleaseNotes.__init__c                 C   s$   |  |}|du rdS | j| d S )zGets the release notes text for the given version.

    Args:
      version: str, The version to get the release notes for.

    Returns:
      str, The release notes or None if the version does not exist.
    N   )_GetVersionIndexr(   )r)   r   indexr   r   r   GetVersionTexts   s   
	zReleaseNotes.GetVersionTextc                 C   s,   t | jD ]\}\}}||kr|  S qdS )zGets the index of the given version in the list of parsed versions.

    Args:
      version: str, The version to get the index for.

    Returns:
      int, The index of the given version or None if not found.
    N)	enumerater(   )r)   r   iv_r   r   r   r.      s
   	zReleaseNotes._GetVersionIndexc                 C   sT   |r|  |}|du rdS nd}|r|  |}|du rdS nt| j}| j|| S )a	  Creates a diff of the release notes between the two versions.

    The release notes are returned in reversed order (most recent first).

    Args:
      start_version: str, The version at which to start the diff.  This should
        be the later of the two versions.  The diff will start with this version
        and go backwards in time until end_version is hit.  If None, the diff
        will start at the most recent entry.
      end_version: str, The version at which to stop the diff.  This should be
        the version you are currently on.  The diff is accumulated until this
        version it hit.  This version is not included in the diff.  If None,
        the diff will include through the end of all release notes.

    Returns:
      [(version, text)], The list of release notes in the diff from most recent
      to least recent.  Each item is a tuple of the version string and the
      release notes text for that version.  Returns None if either of the
      versions are not present in the release notes.
    Nr   )r.   lenr(   )r)   start_versionend_versionstart_index	end_indexr   r   r   Diff   s   


zReleaseNotes.Diff)N)__name__
__module____qualname____doc__r$   MAX_DIFFclassmethodr   r,   r0   r.   r:   r   r   r   r   r
   "   s    r
   c                 C   s   | r|r|rt | }|r|||}nd}nd}|s(tjdtjj	 dS t
|t jkr<tjdtjj	 dS tjdtjj	 t }|D ]\}}|| |d qL|d td|tj tj  dS )a	  Prints the release notes diff based on your current version.

  If any of the arguments are None, a generic message will be printed telling
  the user to go to the web to view the release notes.  If the release_notes_url
  is also None, it will print the developers site page for the SDK.

  Args:
    release_notes_url: str, The URL to download the latest release notes from.
    current_version: str, The current version of the SDK you have installed.
    latest_version: str, The version you are about to update to.
  Nz8For the latest full release notes, please visit:
  {0}

zcA lot has changed since your last upgrade.  For the latest full release notes,
please visit:
  {0}
zThe following release notes are new in this upgrade.
Please read carefully for information about new features, breaking changes,
and bugs fixed.  The latest full release notes can be viewed at:
  {0}
r   r   r   )r
   r   r:   r   statuswriter   r   INSTALLATION_CONFIGrelease_notes_urlr5   r?   Printr	   seekr   RenderDocument)rD   current_versionlatest_versionnotesrelease_notes_diff	full_textr4   r   r   r   r   PrintReleaseNotesDiff   s8   




rM   )r>   
__future__r   r   r   r"   googlecloudsdk.corer   r   &googlecloudsdk.core.document_renderersr   googlecloudsdk.core.updaterr   r   	six.movesr	   objectr
   rM   r   r   r   r   <module>   s    