(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: 
            {
              (SQ <'gitweb as standalone script (parsing script output).\n'> <'\n'> 
                <'This test runs gitweb (git web interface) as a CGI script from the\n'> <'commandline, and checks that it produces the correct output, either\n'> 
                <'in the HTTP header or the actual script output.'>
              )
            }
          spids: [13]
        )
      ]
    )
    (C {<.>} {<'./gitweb-lib.sh'>})
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_DGreat '>>'> loc:(redir_loc.Fd fd:1) arg:{<gitweb_config.perl>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.MultiLine
              here_begin: {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\E'>) <OF>}
              here_end_span_id: 54
              stdin_parts: [
                <'\n'>
                <'$known_snapshot_formats{\'tar\'} = {\n'>
                <'\t\'display\' => \'tar\',\n'>
                <'\t\'type\' => \'application/x-tar\',\n'>
                <'\t\'suffix\' => \'.tar\',\n'>
                <'\t\'format\' => \'tar\',\n'>
                <'};\n'>
                <'\n'>
                <'$feature{\'snapshot\'}{\'default\'} = [\'tar\'];\n'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (command.ShFunction
      name: check_snapshot
      body: 
        (BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:basename)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [85]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:prefix)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (braced_var_sub
                        token: <Id.VSub_Number 2>
                        suffix_op: 
                          (suffix_op.Unary
                            op_id: Id.VTest_ColonHyphen
                            arg_word: {(DQ ($ Id.VSub_Number '$1'))}
                          )
                      )
                    }
                  spids: [89]
                )
              ]
            )
            (C {<echo>} {(DQ <'basename='> ($ Id.VSub_DollarName '$basename'))})
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [
                    {<grep>}
                    {(DQ <'filename=.*'> ($ Id.VSub_DollarName '$basename') <.tar>)}
                    {<gitweb.headers>}
                  ]
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {<'/dev/null'>}
                    )
                    (redir
                      op: <Id.Redir_GreatAnd '2>&'>
                      loc: (redir_loc.Fd fd:2)
                      arg: {<1>}
                    )
                  ]
                  do_fork: T
                )
                (command.Simple
                  words: [{(DQ ($ Id.VSub_DollarName '$TAR'))} {<tf>} {<gitweb.body>}]
                  redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<file_list>})]
                  do_fork: T
                )
                (command.Pipeline
                  children: [
                    (C {<grep>} {<-v>} {<-e>} 
                      {(DQ <'^'> ($ Id.VSub_DollarName '$prefix') <Id.Lit_Other '$'>)} {<-e>} {(DQ <'^'> ($ Id.VSub_DollarName '$prefix') <'/'>)} {<-e>} 
                      {(DQ <'^pax_global_header'> <Id.Lit_Other '$'>)} {<file_list>}
                    )
                  ]
                  negated: T
                )
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\ttest_commit first foo &&\n'> <'\tgit branch xx/test &&\n'> 
          <'\tFULL_ID=$(git rev-parse --verify HEAD) &&\n'> <'\tSHORT_ID=$(git rev-parse --verify --short=7 HEAD)\n'>
        )
      }
    )
    (C {<test_debug>} 
      {(SQ <'\n'> <'\techo "FULL_ID  = $FULL_ID"\n'> <'\techo "SHORT_ID = $SHORT_ID"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'snapshot: full sha1'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=$FULL_ID;sf=tar" &&\n'> 
          <'\tcheck_snapshot ".git-$SHORT_ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: shortened sha1'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=$SHORT_ID;sf=tar" &&\n'> 
          <'\tcheck_snapshot ".git-$SHORT_ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: almost full sha1'>)} 
      {
        (SQ <'\n'> <'\tID=$(git rev-parse --short=30 HEAD) &&\n'> 
          <'\tgitweb_run "p=.git;a=snapshot;h=$ID;sf=tar" &&\n'> <'\tcheck_snapshot ".git-$SHORT_ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: HEAD'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=HEAD;sf=tar" &&\n'> 
          <'\tcheck_snapshot ".git-HEAD-$SHORT_ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: short branch name (master)'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=master;sf=tar" &&\n'> 
          <'\tID=$(git rev-parse --verify --short=7 master) &&\n'> <'\tcheck_snapshot ".git-master-$ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: short tag name (first)'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=first;sf=tar" &&\n'> 
          <'\tID=$(git rev-parse --verify --short=7 first) &&\n'> <'\tcheck_snapshot ".git-first-$ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: full branch name (refs/heads/master)'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=refs/heads/master;sf=tar" &&\n'> 
          <'\tID=$(git rev-parse --verify --short=7 master) &&\n'> <'\tcheck_snapshot ".git-master-$ID"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: full tag name (refs/tags/first)'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=refs/tags/first;sf=tar" &&\n'> 
          <'\tcheck_snapshot ".git-first"\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers && cat file_list'>)})
    (C {<test_expect_success>} {(SQ <'snapshot: hierarchical branch name (xx/test)'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=.git;a=snapshot;h=xx/test;sf=tar" &&\n'> 
          <'\t! grep "filename=.*/" gitweb.headers\n'>
        )
      }
    )
    (C {<test_debug>} {(SQ <'cat gitweb.headers'>)})
    (C {<test_expect_success>} {(SQ <'forks: setup'>)} 
      {
        (SQ <'\n'> <'\tgit init --bare foo.git &&\n'> <'\techo file > file &&\n'> 
          <'\tgit --git-dir=foo.git --work-tree=. add file &&\n'> <'\tgit --git-dir=foo.git --work-tree=. commit -m "Initial commit" &&\n'> 
          <'\techo "foo" > foo.git/description &&\n'> <'\tgit clone --bare foo.git foo.bar.git &&\n'> <'\techo "foo.bar" > foo.bar.git/description &&\n'> 
          <'\tgit clone --bare foo.git foo_baz.git &&\n'> <'\techo "foo_baz" > foo_baz.git/description &&\n'> <'\trm -fr   foo &&\n'> <'\tmkdir -p foo &&\n'> 
          <'\t(\n'> <'\t\tcd foo &&\n'> <'\t\tgit clone --shared --bare ../foo.git foo-forked.git &&\n'> 
          <'\t\techo "fork of foo" > foo-forked.git/description\n'> <'\t)\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'forks: not skipped unless "forks" feature enabled'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "a=project_list" &&\n'> 
          <'\tgrep -q ">\\\\.git<"               gitweb.body &&\n'> <'\tgrep -q ">foo\\\\.git<"            gitweb.body &&\n'> 
          <'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n'> <'\tgrep -q ">foo\\\\.bar\\\\.git<"      gitweb.body &&\n'> 
          <'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n'> <'\tgrep -q ">foo/foo-forked\\\\.git<" gitweb.body &&\n'> 
          <'\tgrep -q ">fork of .*<"           gitweb.body\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'enable forks feature'>)} 
      {
        (SQ <'\n'> <'\tcat >>gitweb_config.perl <<-\\EOF\n'> 
          <'\t$feature{"forks"}{"default"} = [1];\n'> <'\tEOF\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'forks: forks skipped if "forks" feature enabled'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "a=project_list" &&\n'> 
          <'\tgrep -q ">\\\\.git<"               gitweb.body &&\n'> <'\tgrep -q ">foo\\\\.git<"            gitweb.body &&\n'> 
          <'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n'> <'\tgrep -q ">foo\\\\.bar\\\\.git<"      gitweb.body &&\n'> 
          <'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n'> <'\tgrep -v ">foo/foo-forked\\\\.git<" gitweb.body &&\n'> 
          <'\tgrep -v ">fork of .*<"           gitweb.body\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'forks: "forks" action for forked repository'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=foo.git;a=forks" &&\n'> 
          <'\tgrep -q ">foo/foo-forked\\\\.git<" gitweb.body &&\n'> <'\tgrep -q ">fork of foo<"          gitweb.body\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'forks: can access forked repository'>)} 
      {
        (SQ <'\n'> <'\tgitweb_run "p=foo/foo-forked.git;a=summary" &&\n'> 
          <'\tgrep -q "200 OK"        gitweb.headers &&\n'> <'\tgrep -q ">fork of foo<" gitweb.body\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'forks: project_index lists all projects (incl. forks)'>)} 
      {
        (SQ <'\n'> <'\tcat >expected <<-\\EOF &&\n'> <'\t.git\n'> <'\tfoo.bar.git\n'> <'\tfoo.git\n'> 
          <'\tfoo/foo-forked.git\n'> <'\tfoo_baz.git\n'> <'\tEOF\n'> <'\tgitweb_run "a=project_index" &&\n'> 
          <'\tsed -e "s/ .*//" <gitweb.body | sort >actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (command.ShFunction
      name: xss
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{<echo>} {(DQ <'Checking '> ($ Id.VSub_Number '$1') <...>)}]
                  redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})]
                  do_fork: T
                )
                (C {<gitweb_run>} {(DQ ($ Id.VSub_Number '$1'))})
                (command.If
                  arms: [
                    (if_arm
                      cond: [
                        (command.Sentence
                          child: (C {<grep>} {(DQ ($ Id.VSub_DollarName '$TAG'))} {<gitweb.body>})
                          terminator: <Id.Op_Semi _>
                        )
                      ]
                      action: [
                        (command.Simple
                          words: [
                            {<echo>}
                            {
                              (DQ <'xss: '> ($ Id.VSub_DollarName '$TAG') 
                                <' should have been quoted in output'>
                              )
                            }
                          ]
                          redirects: [
                            (redir
                              op: <Id.Redir_GreatAnd '>&'>
                              loc: (redir_loc.Fd fd:1)
                              arg: {<2>}
                            )
                          ]
                          do_fork: T
                        )
                        (command.ControlFlow
                          token: <Id.ControlFlow_Return return>
                          arg_word: {<1>}
                        )
                      ]
                      spids: [535 546]
                    )
                  ]
                )
              ]
            )
            (command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<0>})
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'xss checks'>)} 
      {
        (SQ <'\n'> <'\tTAG="<magic-xss-tag>" &&\n'> <'\txss "a=rss&p=$TAG" &&\n'> 
          <'\txss "a=rss&p=foo.git&f=$TAG"\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)