8/02/2014

repo 내부의 manifest.xml 구성 및 분석

1. manifest.xml 이란? 

repo를 이용하여 repo init하여 설정할 경우, .repo 구조가 생성이되면서 안에  manifest.xml이 안에 존재하는데, 이 xml 기반으로 소스를 가져온다.
이는 repo의 한 구성이며 이를 기반으로 git를 사용하기에 사용방법을 정확히 인지해야한다.


1.1 manifest.xml 기본구조

manifest.xml은 기본적으로 default.xml로 링크되어 있으며, 기본구성은 XML형태의 구조이며,
아래와 같이 XML이 구성이 되므로, 각 구조의 의미를 알아야한다.

  • manifest.xml 전체기본구조
   
 <!DOCTYPE manifest [

/*
        * ELEMENT : XML 내부의 각 element로 이런식으로 구성 <element >
        * ATTLIST : 각 ELEMENT의 속성리스트로 ELEMENT 내에 설정값 
        * REQUIRED : 필수로 들어가야 하는 값 
        * IMPLIED : 옵션이라고 생각하면 되겠음.
*/

/*
 <manifest > 로 시작한 후 아래의 element들로 구성되며 그 속성설정을 이해하자.
  세부내용은 각 ELEMENT에서 설명
*/

    <!ELEMENT manifest (notice?,
                        remote*,    
                        default?,   
                        manifest-server?,
                        remove-project*, 
                        project*,    
                        extend-project*,
                        repo-hooks?,
                        include*)> //다른 manifest.xml 포함가능하지만 .repo/local_manifests/*.xml`로 쉽게추가

    <!ELEMENT notice (#PCDATA)>

// <remote >  구성되며, 보통 Google의 AOSP와 더불어 다른 것들과 같이 구성 ATTLIST로 각 설정가능

    <!ELEMENT remote EMPTY>
    <!ATTLIST remote name       ID    #REQUIRED> //각 project의 .git/config remote 이름로 사용 (git fetch/push 가능)
    <!ATTLIST remote alias        CDATA #IMPLIED>
    <!ATTLIST remote fetch      CDATA #REQUIRED> // ./repo/projects or ./repo/project-object 안에 git로 구성됨 
    <!ATTLIST remote pushurl      CDATA #IMPLIED>   //remote "push" 가능 
    <!ATTLIST remote review      CDATA #IMPLIED>   // review 으로 Gerrit server 설정시 'repo upload' 가능 
    <!ATTLIST remote revision    CDATA #IMPLIED>   // Git 의 tag 와 branch name 

// <default >  거의 1개만 구성되며, ATTLIST 중 remote 와 revision은 각 default 값 설정

    <!ELEMENT default EMPTY> 
    <!ATTLIST default remote      IDREF #IMPLIED> // 상위 remote element 의 name 중 1개 적용(보통 Google)
    <!ATTLIST default revision    CDATA #IMPLIED> // Git branch/tag , 이 값은 모든 project elelement의 기본값설정
    <!ATTLIST default dest-branch CDATA #IMPLIED> // Name of a Git branch (e.g. `master`), 설정하지 않으면, revision과 동일주소
    <!ATTLIST default upstream    CDATA #IMPLIED>
    <!ATTLIST default sync-j      CDATA #IMPLIED> // 보통 병렬작업을 하기 위해 Job 갯수 
    <!ATTLIST default sync-c      CDATA #IMPLIED> // 받은 Git Branch Sync 설정 true  (revision 속성)
    <!ATTLIST default sync-s      CDATA #IMPLIED> // Sub Project Sync 설정 true
    <!ATTLIST default sync-tags   CDATA #IMPLIED> // 받은 Git Branch Sync 설정 false (revision 속성)

    <!ELEMENT manifest-server EMPTY>
    <!ATTLIST manifest-server url CDATA #REQUIRED>

// 상위의 remote 안에 존재하는 모든 project git을 download 후 < project >  구성되며, ATTLIST 설정가능  

    <!ELEMENT project (annotation*,   
                       project*,                 
                       copyfile*,
                       linkfile*)>
    <!ATTLIST project name        CDATA #REQUIRED> // 실제 상위 remote 중  Git 의 project name이며 unique 해야함                                                         
    <!ATTLIST project path        CDATA #IMPLIED>  // 상위 Git Project을 download 하면 실제 Local PATH 
    <!ATTLIST project remote     IDREF #IMPLIED> // 상위 remote element 의 name에 적용
    <!ATTLIST project revision    CDATA #IMPLIED> // 설정이 없다면 상위 default element 값
    <!ATTLIST project dest-branch  CDATA #IMPLIED>
    <!ATTLIST project groups       CDATA #IMPLIED> // Project가 속한 그룹 , 설정을 안하면, name과 동일
    <!ATTLIST project sync-c       CDATA #IMPLIED> // Number of parallel jobs (git sync)
    <!ATTLIST project sync-s       CDATA #IMPLIED> // Sub Project Sync 설정 true
    <!ATTLIST default sync-tags    CDATA #IMPLIED>
    <!ATTLIST project upstream     CDATA #IMPLIED>
    <!ATTLIST project clone-depth  CDATA #IMPLIED>
    <!ATTLIST project force-path   CDATA #IMPLIED>

/*
< project > 의 Sub 작업으로 동작하며 각 Git Project를 세부 Control 작업 
       < annotation >     
       < copyfile >       파일복사
       < linkfile >       링크파일생성
       < extend-project >     확장
*/

      <!ELEMENT annotation EMPTY> 
      <!ATTLIST annotation name  CDATA #REQUIRED>
      <!ATTLIST annotation value CDATA #REQUIRED>
      <!ATTLIST annotation keep  CDATA "true">

      <!ELEMENT copyfile EMPTY> 
      <!ATTLIST copyfile src  CDATA #REQUIRED>
      <!ATTLIST copyfile dest CDATA #REQUIRED>

      <!ELEMENT linkfile EMPTY>  
      <!ATTLIST linkfile src CDATA #REQUIRED>
      <!ATTLIST linkfile dest CDATA #REQUIRED>

      <!ELEMENT extend-project EMPTY>
      <!ATTLIST extend-project name CDATA #REQUIRED>
      <!ATTLIST extend-project path CDATA #IMPLIED>
      <!ATTLIST extend-project groups CDATA #IMPLIED>
      <!ATTLIST extend-project revision CDATA #IMPLIED>

/*
       ELEMENT-project 제거기능으로 
        - 이름이 중복될때 사용될경우 필요 할 것 같음
        - 불필요한 project 제거할 것 같음 (remote에서 전체 project를 받기때문에 필요 없는 것은제거)
*/

    <!ELEMENT remove-project EMPTY> 
    <!ATTLIST remove-project name  CDATA #REQUIRED>

    <!ELEMENT repo-hooks EMPTY>
    <!ATTLIST repo-hooks in-project CDATA #REQUIRED>
    <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED>

/* 
  다른 manifest.xml을 include가능하여 확장기능 
  이외 localmanifest 도 존재
 */ 

    <!ELEMENT include EMPTY> 
    <!ATTLIST include name CDATA #REQUIRED>
  ]>


  • manifest.xml 에 local_manifests.xml 추가방법
`$TOP_DIR/.repo/local_manifests/*.xml`  추가적으로 element project 와 remote를 확장하기 위해서 local_manifest.xml를 별도로 확장

// element remote 와 project 관련 사항만 가능한것 같음 (remove-project도 확인) 
$ ls .repo/manifests  //다양한 manifests.xml로 구성  
....xml

$ ls .repo/manifests.xml   //manifests.xml (MAIN) include 사용하여 .repo/manifests 중 선택가능 

$ ls .repo/local_manifests
local_manifest.xml         // 2nd 추가됨 (알파벳 순서)  
another_local_manifest.xml // 1st 추가됨 (알파벳 순서)  

$ cat .repo/local_manifests/local_manifest.xml // local_manifest.xml 예제 (remote or project를 추가) 
  <?xml version="1.0" encoding="UTF-8"?>
  <manifest>
    <project path="manifest"
             name="tools/manifest" />
    <project path="platform-manifest"
             name="platform/manifest" />
  </manifest>

더이상 $TOP_DIR/.repo/local_manifest.xml 는 미지원한다고 한다. 

        name   : remote의  unique한 ID설정, 다른곳에서 이 ID를 참조하여 적용
        fetch     : source를  받아올 주소 (git fetch )
        review   : review site로 이전 odroid version에는 존재했음. (repo upload 가능)
        revision  : git branch/tag 의 이름  (e.g. master , 'refs/heads/master')
        push     : git push 

     일단 Git 기반으로 하는 것이며, ./repo 안에 download를 하면, name으로 검색가능 

        remote:   이전에 선언된 remote name 중 설정 (기본값 설정)
        revision:  git branch or tag로 element project의 revision의 기본설정값 
        syn-j:  repo sync시 동시에 여러 작업있는 갯수 설정.
        syn-c:  true 이면, 오직 전체를 sync하는 것이 아니라, git branch만 sync 한다고한다.
                 효율적면에서 사용하는것 같다.
        syn-s: true이면 sub-project와 sync를 한다고 한다.

   *element default는 project의 attribute가 remote가 선언이 되지 않았다면, default사용 

  • element project
  • path:  repo sync후 Local의 PATH 구성 
    name:  unique한 이름, remote의 fetch의 Git repository name 
    remote: remote의 설정하며, 만약없다면, element default 정보사용.
    group: group의 list를 말하며, 선언이 되어 있지 않다면 "notdefault" 설정
        모든 project 선언시는  "all"  각 개별 project group 선택시에는 "pdk" or "pdk,linux"
        repo sync -g로 sync 여부를 결정가능하다.
    revision:  sync가 된후, git의 branch 이름,만약없다면, element default 정보사용.
    기본적으로 repo로 download되어 있으면, local path 기반    


Google의 Repo 관련 세부 Manual 
  https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md


  • Google의 remote 기본구조
기본 remote Google의 AOSP 는 https://android.googlesource.com 구성은 다음과 같이 구성이 되어지며, 각 슬래시로 구분되어진다.
이는 repo sync를 할 경우 ,  ./repo/projects or ./repo/project-object 로 가는데 거의 ./repo/projects 로 안에 존재한다.

일반 Github일 경우는 그냥 project name으로만 찾으면된다. 

{remote_fetch}/${project_name}.git 

아래의 설정이 특히해서 링크 
  https://stackoverflow.com/questions/18251358/repo-manifest-xml-what-does-the-fetch-mean

ODROID manifest.xml 분석