#303 WIP Rewrite copr-cli to use APIv3
Closed 5 years ago by frostyx. Opened 5 years ago by frostyx.
copr/ frostyx/copr apiv3-cli  into  master

@@ -204,11 +204,11 @@ 

          rlRun "copr-cli edit-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 --delete-comps"

          rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | grep '\"comps_name\": null'"

          rlRun "copr-cli edit-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 --repos 'http://foo/repo http://bar/repo' --packages 'gcc'"

-         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | grep '\"repos\": \"http://foo/repo http://bar/repo\"'"

-         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | grep '\"buildroot_pkgs\": \"gcc\"'"

+         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | jq '.repos == [\"http://foo/repo\", \"http://bar/repo\"]'"

+         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | jq '.buildroot_pkgs == [\"gcc\"]'"

          rlRun "copr-cli edit-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 --repos '' --packages ''"

-         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | grep '\"repos\": \"\"'"

-         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | grep '\"buildroot_pkgs\": \"\"'"

+         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | jq '.repos == []'"

+         rlRun "copr-cli get-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_64 | jq '.buildroot_pkgs == []'"

          rlRun "copr-cli edit-chroot ${NAME_PREFIX}EditChrootProject/fedora-27-x86_65" 1

          rm $TMPCOMPS

  
@@ -248,154 +248,97 @@ 

  

          ## test package creation and editing

          OUTPUT=`mktemp`

-         SOURCE_JSON=`mktemp`

+         SOURCE_DICT=`mktemp`

  

          # create special repo for our test

          rlRun "copr-cli create --chroot $CHROOT ${NAME_PREFIX}Project4"

  

-         # invalid package data

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project4 --name test_package_tito --git-url invalid_url" 1

- 

-         # Tito package creation

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project4 --name test_package_tito --git-url http://github.com/clime/example.git --test on --webhook-rebuild on --git-branch foo --git-dir bar"

-         rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_tito > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

-         rlAssertEquals "package.name == \"test_package_tito\"" `cat $OUTPUT | jq '.name'` '"test_package_tito"'

-         rlAssertEquals "package.webhook_rebuild == \"true\"" `cat $OUTPUT | jq '.webhook_rebuild'` 'true'

-         rlAssertEquals "package.source_type == \"scm\"" `cat $OUTPUT | jq '.source_type'` '"scm"'

-         rlAssertEquals "package.source_json.srpm_build_method == \"tito_test"\" `cat $SOURCE_JSON | jq '.srpm_build_method'` '"tito_test"'

-         rlAssertEquals "package.source_json.clone_url == \"http://github.com/clime/example.git\"" `cat $SOURCE_JSON | jq '.clone_url'` '"http://github.com/clime/example.git"'

-         rlAssertEquals "package.source_json.committish == \"foo\"" `cat $SOURCE_JSON | jq '.committish'` '"foo"'

-         rlAssertEquals "package.source_json.subdirectory == \"bar\"" `cat $SOURCE_JSON | jq '.subdirectory'` '"bar"'

- 

-         # Tito package editing

-         rlRun "copr-cli edit-package-tito ${NAME_PREFIX}Project4 --name test_package_tito --git-url http://github.com/clime/example2.git --test off --webhook-rebuild off --git-branch bar --git-dir foo"

-         rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_tito > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

-         rlAssertEquals "package.name == \"test_package_tito\"" `cat $OUTPUT | jq '.name'` '"test_package_tito"'

-         rlAssertEquals "package.webhook_rebuild == \"false\"" `cat $OUTPUT | jq '.webhook_rebuild'` 'false'

-         rlAssertEquals "package.source_type == \"scm\"" `cat $OUTPUT | jq '.source_type'` '"scm"'

-         rlAssertEquals "package.source_json.srpm_build_method == \"tito\"" `cat $SOURCE_JSON | jq '.srpm_build_method'` '"tito"'

-         rlAssertEquals "package.source_json.clone_url == \"http://github.com/clime/example2.git\"" `cat $SOURCE_JSON | jq '.clone_url'` '"http://github.com/clime/example2.git"'

-         rlAssertEquals "package.source_json.committish == \"bar\"" `cat $SOURCE_JSON | jq '.committish'` '"bar"'

-         rlAssertEquals "package.source_json.subdirectory == \"foo\"" `cat $SOURCE_JSON | jq '.subdirectory'` '"foo"'

- 

-         ## Package listing

-         rlAssertEquals "len(package_list) == 1" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 1

- 

          # PyPI package creation

          rlRun "copr-cli add-package-pypi ${NAME_PREFIX}Project4 --name test_package_pypi --packagename pyp2rpm --packageversion 1.5 --pythonversions 3 2"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_pypi > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.name == \"test_package_pypi\"" `cat $OUTPUT | jq '.name'` '"test_package_pypi"'

          rlAssertEquals "package.source_type == \"pypi\"" `cat $OUTPUT | jq '.source_type'` '"pypi"'

-         rlRun `cat $SOURCE_JSON | jq '.python_versions == ["3", "2"]'` 0 "package.source_json.python_versions == [\"3\", \"2\"]"

-         rlAssertEquals "package.source_json.pypi_package_name == \"pyp2rpm\"" `cat $SOURCE_JSON | jq '.pypi_package_name'` '"pyp2rpm"'

-         rlAssertEquals "package.source_json.pypi_package_version == \"bar\"" `cat $SOURCE_JSON | jq '.pypi_package_version'` '"1.5"'

+         rlRun `cat $SOURCE_DICT | jq '.python_versions == ["3", "2"]'` 0 "package.source_dict.python_versions == [\"3\", \"2\"]"

+         rlAssertEquals "package.source_dict.pypi_package_name == \"pyp2rpm\"" `cat $SOURCE_DICT | jq '.pypi_package_name'` '"pyp2rpm"'

+         rlAssertEquals "package.source_dict.pypi_package_version == \"bar\"" `cat $SOURCE_DICT | jq '.pypi_package_version'` '"1.5"'

  

          # PyPI package editing

          rlRun "copr-cli edit-package-pypi ${NAME_PREFIX}Project4 --name test_package_pypi --packagename motionpaint --packageversion 1.4 --pythonversions 2 3"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_pypi > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.name == \"test_package_pypi\"" `cat $OUTPUT | jq '.name'` '"test_package_pypi"'

          rlAssertEquals "package.source_type == \"pypi\"" `cat $OUTPUT | jq '.source_type'` '"pypi"'

-         rlRun `cat $SOURCE_JSON | jq '.python_versions == ["2", "3"]'` 0 "package.source_json.python_versions == [\"2\", \"3\"]"

-         rlAssertEquals "package.source_json.pypi_package_name == \"motionpaint\"" `cat $SOURCE_JSON | jq '.pypi_package_name'` '"motionpaint"'

-         rlAssertEquals "package.source_json.pypi_package_version == \"bar\"" `cat $SOURCE_JSON | jq '.pypi_package_version'` '"1.4"'

-         rlAssertEquals "package.source_json.spec_template == \"\"" `cat $SOURCE_JSON | jq '.spec_template'` '""'

+         rlRun `cat $SOURCE_DICT | jq '.python_versions == ["2", "3"]'` 0 "package.source_dict.python_versions == [\"2\", \"3\"]"

+         rlAssertEquals "package.source_dict.pypi_package_name == \"motionpaint\"" `cat $SOURCE_DICT | jq '.pypi_package_name'` '"motionpaint"'

+         rlAssertEquals "package.source_dict.pypi_package_version == \"bar\"" `cat $SOURCE_DICT | jq '.pypi_package_version'` '"1.4"'

+         rlAssertEquals "package.source_dict.spec_template == \"\"" `cat $SOURCE_DICT | jq '.spec_template'` '""'

  

          # PyPI package templates

          rlRun "copr-cli edit-package-pypi ${NAME_PREFIX}Project4 --name test_package_pypi --template fedora"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_pypi > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

-         rlAssertEquals "package.source_json.spec_template == \"fedora\"" `cat $SOURCE_JSON | jq '.spec_template'` '"fedora"'

- 

-         ## Package listing

-         rlAssertEquals "len(package_list) == 2" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 2

- 

-         # MockSCM package creation

-         rlRun "copr-cli add-package-mockscm ${NAME_PREFIX}Project4 --name test_package_mockscm --scm-type git --scm-url http://github.com/clime/example.git --scm-branch foo --spec example.spec"

-         rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_mockscm > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

-         rlAssertEquals "package.name == \"test_package_mockscm\"" `cat $OUTPUT | jq '.name'` '"test_package_mockscm"'

-         rlAssertEquals "package.source_type == \"scm\"" `cat $OUTPUT | jq '.source_type'` '"scm"'

-         rlAssertEquals "package.source_json.type == \"git\"" `cat $SOURCE_JSON | jq '.type'` '"git"'

-         rlAssertEquals "package.source_json.clone_url == \"http://github.com/clime/example.git\"" `cat $SOURCE_JSON | jq '.clone_url'` '"http://github.com/clime/example.git"'

-         rlAssertEquals "package.source_json.committish == \"foo\"" `cat $SOURCE_JSON | jq '.committish'` '"foo"'

-         rlAssertEquals "package.source_json.spec == \"example.spec\"" `cat $SOURCE_JSON | jq '.spec'` '"example.spec"'

-         rlAssertEquals "package.source_json.srpm_build_method == \"rpkg\"" `cat $SOURCE_JSON | jq '.srpm_build_method'` '"rpkg"'

- 

-         # MockSCM package editing

-         rlRun "copr-cli edit-package-mockscm ${NAME_PREFIX}Project4 --name test_package_mockscm --scm-type svn --scm-url http://github.com/clime/example2.git --scm-branch bar --spec example2.spec"

-         rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_mockscm > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

-         rlAssertEquals "package.name == \"test_package_mockscm\"" `cat $OUTPUT | jq '.name'` '"test_package_mockscm"'

-         rlAssertEquals "package.source_type == \"scm\"" `cat $OUTPUT | jq '.source_type'` '"scm"'

-         rlAssertEquals "package.source_json.type == \"svn\"" `cat $SOURCE_JSON | jq '.type'` '"svn"'

-         rlAssertEquals "package.source_json.clone_url == \"http://github.com/clime/example2.git\"" `cat $SOURCE_JSON | jq '.clone_url'` '"http://github.com/clime/example2.git"'

-         rlAssertEquals "package.source_json.committish == \"bar\"" `cat $SOURCE_JSON | jq '.committish'` '"bar"'

-         rlAssertEquals "package.source_json.spec == \"example2.spec\"" `cat $SOURCE_JSON | jq '.spec'` '"example2.spec"'

-         rlAssertEquals "package.source_json.srpm_build_method == \"rpkg\"" `cat $SOURCE_JSON | jq '.srpm_build_method'` '"rpkg"'

+         cat $OUTPUT | jq '.source_dict' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_DICT

+         rlAssertEquals "package.source_dict.spec_template == \"fedora\"" `cat $SOURCE_DICT | jq '.spec_template'` '"fedora"'

  

          ## Package listing

-         rlAssertEquals "len(package_list) == 3" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 3

+         rlAssertEquals "len(package_list) == 1" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 1

  

          # RubyGems package creation

          rlRun "copr-cli add-package-rubygems ${NAME_PREFIX}Project4 --name xxx --gem yyy"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name xxx > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.name == \"xxx\"" `cat $OUTPUT | jq '.name'` '"xxx"'

          rlAssertEquals "package.source_type == \"rubygems\"" `cat $OUTPUT | jq '.source_type'` '"rubygems"'

-         rlAssertEquals "package.source_json.gem_name == \"yyy\"" `cat $SOURCE_JSON | jq '.gem_name'` '"yyy"'

+         rlAssertEquals "package.source_dict.gem_name == \"yyy\"" `cat $SOURCE_DICT | jq '.gem_name'` '"yyy"'

  

          # RubyGems package editing

          rlRun "copr-cli edit-package-rubygems ${NAME_PREFIX}Project4 --name xxx --gem zzz"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name xxx > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.name == \"xxx\"" `cat $OUTPUT | jq '.name'` '"xxx"'

          rlAssertEquals "package.source_type == \"rubygems\"" `cat $OUTPUT | jq '.source_type'` '"rubygems"'

-         rlAssertEquals "package.source_json.gem_name == \"zzz\"" `cat $SOURCE_JSON | jq '.gem_name'` '"zzz"'

+         rlAssertEquals "package.source_dict.gem_name == \"zzz\"" `cat $SOURCE_DICT | jq '.gem_name'` '"zzz"'

  

          ## Package listing

-         rlAssertEquals "len(package_list) == 4" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 4

+         rlAssertEquals "len(package_list) == 2" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 2

  

          ## Package reseting

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project4 --name test_package_reset --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}Project4 --name test_package_reset --clone-url http://github.com/clime/example.git"

  

          # before reset

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_reset > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.source_type == \"scm\"" `cat $OUTPUT | jq '.source_type'` '"scm"'

-         rlAssertEquals "package.source_json.clone_url == \"http://github.com/clime/example.git\"" `cat $SOURCE_JSON | jq '.clone_url'` '"http://github.com/clime/example.git"'

+         rlAssertEquals "package.source_dict.clone_url == \"http://github.com/clime/example.git\"" `cat $SOURCE_DICT | jq '.clone_url'` '"http://github.com/clime/example.git"'

  

          # _do_ reset

          rlRun "copr-cli reset-package ${NAME_PREFIX}Project4 --name test_package_reset"

  

          # after reset

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_reset > $OUTPUT"

-         cat $OUTPUT | jq '.source_json' | sed -r 's/"(.*)"/\1/g' | sed -r 's/\\(.)/\1/g' > $SOURCE_JSON

+         cat $OUTPUT | jq '.source_dict' > $SOURCE_DICT

          rlAssertEquals "package.source_type == \"unset\"" `cat $OUTPUT | jq '.source_type'` '"unset"'

-         rlAssertEquals "package.source_json == \"{}\"" `cat $OUTPUT | jq '.source_json'` '"{}"'

+         rlAssertEquals "package.source_dict == \"{}\"" `cat $OUTPUT | jq '.source_dict'` '{}'

  

          ## Package listing

-         rlAssertEquals "len(package_list) == 5" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 5

+         rlAssertEquals "len(package_list) == 3" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 3

  

          ## Package deletion

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project4 --name test_package_delete --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}Project4 --name test_package_delete --clone-url http://github.com/clime/example.git"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_delete > /dev/null"

  

          ## Package listing

-         rlAssertEquals "len(package_list) == 6" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 6

+         rlAssertEquals "len(package_list) == 4" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 4

  

          rlRun "copr-cli delete-package ${NAME_PREFIX}Project4 --name test_package_delete"

          rlRun "copr-cli get-package ${NAME_PREFIX}Project4 --name test_package_delete" 1 # package cannot be fetched now (cause it is deleted)

  

          ## Package listing

-         rlAssertEquals "len(package_list) == 5" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 5

+         rlAssertEquals "len(package_list) == 3" `copr-cli list-packages ${NAME_PREFIX}Project4 | jq '. | length'` 3

  

          ## Test package listing attributes

          rlRun "copr-cli create --chroot $CHROOT ${NAME_PREFIX}Project5"

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project5 --name example --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}Project5 --name example --clone-url http://github.com/clime/example.git"

  

          BUILDS=`mktemp`

          LATEST_BUILD=`mktemp`
@@ -412,10 +355,10 @@ 

          rlAssertEquals "And there is no latest succeeded build." `cat $LATEST_SUCCEEDED_BUILD` 'null'

  

          # run the build and wait

-         rlRun "copr-cli buildtito --git-url http://github.com/clime/example.git ${NAME_PREFIX}Project5 | grep 'Created builds:' | sed 's/Created builds: \([0-9][0-9]*\)/\1/g' > succeeded_example_build_id"

+         rlRun "copr-cli buildscm --clone-url http://github.com/clime/example.git ${NAME_PREFIX}Project5 | grep 'Created builds:' | sed 's/Created builds: \([0-9][0-9]*\)/\1/g' > succeeded_example_build_id"

  

          # this build should fail

-         rlRun "copr-cli buildtito --git-url http://github.com/clime/example.git --git-branch noluck --test on ${NAME_PREFIX}Project5 | grep 'Created builds:' | sed 's/Created builds: \([0-9][0-9]*\)/\1/g' > failed_example_build_id"

+         rlRun "copr-cli buildscm --clone-url http://github.com/clime/example.git --commit noluck ${NAME_PREFIX}Project5 | grep 'Created builds:' | sed 's/Created builds: \([0-9][0-9]*\)/\1/g' > failed_example_build_id"

  

          # run the tests after build

          rlRun "copr-cli get-package ${NAME_PREFIX}Project5 --name example --with-all-builds --with-latest-build --with-latest-succeeded-build > $OUTPUT"
@@ -441,11 +384,11 @@ 

          # create special repo for our test

          rlRun "copr-cli create --chroot $CHROOT --chroot fedora-27-x86_64 ${NAME_PREFIX}Project6"

  

-         # create tito package

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project6 --name test_package_tito --git-url http://github.com/clime/example.git --test on"

+         # create a package

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}Project6 --name test_package_scm --clone-url http://github.com/clime/example.git"

  

          # build the package

-         rlRun "copr-cli build-package --name test_package_tito ${NAME_PREFIX}Project6 --timeout 10000 -r $CHROOT" # TODO: timeout not honored

+         rlRun "copr-cli build-package --name test_package_scm ${NAME_PREFIX}Project6 --timeout 10000 -r $CHROOT" # TODO: timeout not honored

  

          # create pyp2rpm package

          rlRun "copr-cli add-package-pypi ${NAME_PREFIX}Project6 --name test_package_pypi --template fedora --packagename motionpaint --pythonversions 3 2"
@@ -478,7 +421,7 @@ 

          rlRun "copr-cli create --chroot $CHROOT --chroot fedora-27-x86_64 ${NAME_PREFIX}Project9" && sleep 65

          rlRun "curl -X POST $FRONTEND_URL/coprs/update_search_index/"

          rlRun "curl $FRONTEND_URL/coprs/fulltext/?fulltext=${NAME_VAR}Project9 --silent | grep -E \"href=.*${NAME_VAR}Project9.*\"" 1 # search results _not_ returned

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}Project9 --name test_package_tito --git-url http://github.com/clime/example.git --test on" # insert package to the copr

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}Project9 --name test_package_scm --clone-url http://github.com/clime/example.git" # insert package to the copr

          rlRun "curl -X POST $FRONTEND_URL/coprs/update_search_index/" # update the index again

          rlRun "curl $FRONTEND_URL/coprs/fulltext/?fulltext=${NAME_VAR}Project9 --silent | grep -E \"href=.*${NAME_VAR}Project9.*\"" 0 # search results are returned now

  
@@ -543,7 +486,7 @@ 

          # FIXME: this test is not a reliable reproducer. Depends on timing as few others.

          # TODO: Remove this.

          rlRun "copr-cli create ${NAME_PREFIX}TestConsequentDeleteActions --chroot $CHROOT" 0

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}TestConsequentDeleteActions --name example --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}TestConsequentDeleteActions --name example --clone-url http://github.com/clime/example.git"

          rlRun "copr-cli build-package --name example ${NAME_PREFIX}TestConsequentDeleteActions"

          rlAssertEquals "Test that the project was successfully created on backend" `curl -w '%{response_code}' -silent -o /dev/null $BACKEND_URL/results/${NAME_PREFIX}TestConsequentDeleteActions/` 200

          rlRun "python <<< \"from copr.client import CoprClient; client = CoprClient.create_from_file_config('/root/.config/copr'); client.delete_package('${NAME_VAR}TestConsequentDeleteActions', 'example', '$OWNER'); client.delete_project('${NAME_VAR}TestConsequentDeleteActions', '$OWNER')\""
@@ -552,7 +495,7 @@ 

  

          # Bug 1368259 - Deleting a build from a group project doesn't delete backend files

          rlRun "copr-cli create ${NAME_PREFIX}TestDeleteGroupBuild --chroot $CHROOT" 0

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}TestDeleteGroupBuild --name example --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}TestDeleteGroupBuild --name example --clone-url http://github.com/clime/example.git"

          rlRun "copr-cli build-package --name example ${NAME_PREFIX}TestDeleteGroupBuild | grep 'Created builds:' | sed 's/Created builds: \([0-9][0-9]*\)/\1/g' > TestDeleteGroupBuild_example_build_id.txt"

          BUILD_ID=`cat TestDeleteGroupBuild_example_build_id.txt`

          MYTMPDIR=`mktemp -d -p .` && cd $MYTMPDIR
@@ -578,15 +521,15 @@ 

  

          # Bug 1370704 - Internal Server Error (too many values to unpack)

          rlRun "copr-cli create ${NAME_PREFIX}TestBug1370704 --chroot $CHROOT" 0

-         rlRun "copr-cli add-package-tito ${NAME_PREFIX}TestBug1370704 --name example --git-url http://github.com/clime/example.git"

+         rlRun "copr-cli add-package-scm ${NAME_PREFIX}TestBug1370704 --name example --clone-url http://github.com/clime/example.git"

          rlRun "copr-cli build-package --name example ${NAME_PREFIX}TestBug1370704"

          rlAssertEquals "Test OK return code from the monitor API" `curl -w '%{response_code}' -silent -o /dev/null ${FRONTEND_URL}/api/coprs/${NAME_PREFIX}TestBug1370704/monitor/` 200

  

          # Bug 1393361 - get_project_details returns incorrect yum_repos

          rlRun "copr-cli create ${NAME_PREFIX}TestBug1393361-1 --chroot fedora-27-x86_64" 0

          rlRun "copr-cli create ${NAME_PREFIX}TestBug1393361-2 --chroot fedora-27-x86_64" 0

-         rlRun "copr-cli buildtito ${NAME_PREFIX}TestBug1393361-2 --git-url https://github.com/clime/example.git" 0

-         rlRun "copr-cli buildtito ${NAME_PREFIX}TestBug1393361-1 --git-url https://github.com/clime/example.git" 0

+         rlRun "copr-cli buildscm ${NAME_PREFIX}TestBug1393361-2 --clone-url https://github.com/clime/example.git" 0

+         rlRun "copr-cli buildscm ${NAME_PREFIX}TestBug1393361-1 --clone-url https://github.com/clime/example.git" 0

          rlRun "curl --silent ${FRONTEND_URL}/api/coprs/${NAME_PREFIX}TestBug1393361-1/detail/ | grep TestBug1393361-1/fedora-27-x86_64" 0

          rlRun "curl --silent ${FRONTEND_URL}/api/coprs/${NAME_PREFIX}TestBug1393361-2/detail/ | grep TestBug1393361-2/fedora-27-x86_64" 0

  

file modified
+2 -2
@@ -29,7 +29,7 @@ 

  BuildRequires: util-linux

  

  %if %{with python3}

- Requires:      python3-copr >= 1.63

+ Requires:      python3-copr >= 1.89

  Requires:      python3-jinja2

  Requires:      python3-simplejson

  
@@ -43,7 +43,7 @@ 

  BuildRequires: python3-setuptools

  BuildRequires: python3-simplejson

  %else

- Requires:      python-copr >= 1.63

+ Requires:      python-copr >= 1.89

  Requires:      python-jinja2

  Requires:      python-simplejson

  

file modified
+229 -308
@@ -13,9 +13,9 @@ 

  

  import logging

  if six.PY2:

-     from urlparse import urlparse

+     from urlparse import urlparse, urljoin

  else:

-     from urllib.parse import urlparse

+     from urllib.parse import urlparse, urljoin

  

  if sys.version_info < (2, 7):

      class NullHandler(logging.Handler):
@@ -31,7 +31,10 @@ 

  from copr.client.responses import CoprResponse

  import copr.exceptions as copr_exceptions

  

- from .util import ProgressBar

+ from copr.v3 import (Client, config_from_file, CoprException, CoprRequestException, CoprNoConfigException,

+                      CoprConfigException, CoprNoResultException)

+ 

+ from .util import ProgressBar, json_dumps

  from .build_config import MockProfile

  

  import pkg_resources
@@ -57,24 +60,24 @@ 

      pass

  

  class Commands(object):

-     def __init__(self, config):

-         self.config = config

+     def __init__(self, config_path):

          try:

-             self.client = CoprClient.create_from_file_config(config)

-         except (copr_exceptions.CoprNoConfException,

-                 copr_exceptions.CoprConfigException):

-             sys.stderr.write(no_config_warning.format(config or "~/.config/copr"))

-             self.client = CoprClient(

-                 copr_url=u"http://copr.fedoraproject.org",

-                 no_config=True

-             )

+             self.config_path = config_path

+             self.config = config_from_file(config_path)

+ 

+         except (CoprNoConfigException,

+                 CoprConfigException):

+             sys.stderr.write(no_config_warning.format(config_path or "~/.config/copr"))

+             self.config = {"copr_url": "http://copr.fedoraproject.org", "no_config": True}

+ 

+         self.client = Client(self.config)

  

      def requires_api_auth(func):

          """ Decorator that checks config presence

          """

  

          def wrapper(self, args):

-             if self.client.no_config:

+             if "no_config" in self.config:

                  sys.stderr.write("Error: Operation requires api authentication\n")

                  sys.exit(6)

  
@@ -89,13 +92,13 @@ 

          """

  

          def wrapper(self, args):

-             if self.client.no_config and args.username is None:

+             if "no_config" in self.config and args.username is None:

                  sys.stderr.write(

                      "Error: Operation requires username\n"

                      "Pass username to command or create `~/.config/copr`\n")

                  sys.exit(6)

  

-             if args.username is None and self.client.username is None:

+             if args.username is None and self.config["username"] is None:

                  sys.stderr.write(

                      "Error: Operation requires username\n"

                      "Pass username to command or add it to `~/.config/copr`\n")
@@ -107,6 +110,15 @@ 

          wrapper.__name__ = func.__name__

          return wrapper

  

+     def parse_name(self, name):

+         m = re.match(r"([^/]+)/(.*)", name)

+         if m:

+             owner = m.group(1)

+             name = m.group(2)

+         else:

+             owner = self.config["username"]

+         return owner, name

+ 

      def _watch_builds(self, build_ids):

          """

          :param build_ids: list of build IDs
@@ -125,27 +137,21 @@ 

                      if build_id in done:

                          continue

  

-                     build_details = self.client.get_build_details(build_id)

- 

-                     if build_details.output != "ok":

-                         errmsg = "  Build {1}: Unable to get build status: {0}". \

-                             format(build_details.error, build_id)

-                         raise copr_exceptions.CoprRequestException(errmsg)

- 

+                     build_details = self.client.build_proxy.get(build_id)

                      now = datetime.datetime.now()

-                     if prevstatus[build_id] != build_details.status:

-                         prevstatus[build_id] = build_details.status

+                     if prevstatus[build_id] != build_details.state:

+                         prevstatus[build_id] = build_details.state

                          print("  {0} Build {2}: {1}".format(

                              now.strftime("%H:%M:%S"),

-                             build_details.status, build_id))

+                             build_details.state, build_id))

                          sys.stdout.flush()

  

-                     if build_details.status in ["failed"]:

+                     if build_details.state in ["failed"]:

                          failed_ids.append(build_id)

-                     if build_details.status in ["succeeded", "skipped",

-                                                 "failed", "canceled"]:

+                     if build_details.state in ["succeeded", "skipped",

+                                                "failed", "canceled"]:

                          done.add(build_id)

-                     if build_details.status == "unknown":

+                     if build_details.state == "unknown":

                          raise copr_exceptions.CoprBuildException(

                              "Unknown status.")

  
@@ -166,7 +172,7 @@ 

          """

          Simply print out the current user as defined in copr config.

          """

-         print(self.client.username)

+         print(self.config["username"])

  

      def action_new_webhook_secret(self, args):

          """
@@ -194,28 +200,28 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         self.client.authentication_check()

+         self.client.build_proxy.auth_check()

  

          bar = None

          progress_callback = None

+         build_function = self.client.build_proxy.create_from_url

          builds = []

  

          for pkg in args.pkgs:

              if os.path.exists(pkg):

                  bar = ProgressBar(max=os.path.getsize(pkg))

+                 build_function = self.client.build_proxy.create_from_file

+                 data = {"path": pkg}

  

                  # pylint: disable=function-redefined

                  def progress_callback(monitor):

                      bar.next(n=8192)

  

                  print('Uploading package {0}'.format(pkg))

+             else:

+                 data = {"url": pkg}

  

-             data = {

-                 "pkgs": [pkg],

-                 "progress_callback": progress_callback,

-             }

- 

-             builds.append(self.process_build(args, self.client.create_new_build, data, bar=bar))

+             builds.append(self.process_build(args, build_function, data, bar=bar, progress_callback=progress_callback))

  

          return builds

  
@@ -226,45 +232,13 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         username, copr = parse_name(args.copr)

- 

          data = {

              "pypi_package_name": args.packagename,

              "pypi_package_version": args.packageversion,

              "spec_template": args.spec_template,

              "python_versions": args.pythonversions,

          }

-         return self.process_build(args, self.client.create_new_build_pypi, data)

- 

-     @requires_api_auth

-     def action_build_tito(self, args):

-         """

-         Method called when the 'buildtito' action has been selected by the user.

- 

-         :param args: argparse arguments provided by the user

-         """

-         data = {

-             "git_url": args.git_url,

-             "git_dir": args.git_dir,

-             "git_branch": args.git_branch,

-             "tito_test": args.tito_test,

-         }

-         return self.process_build(args, self.client.create_new_build_tito, data)

- 

-     @requires_api_auth

-     def action_build_mock(self, args):

-         """

-         Method called when the 'build-mock' action has been selected by the user.

- 

-         :param args: argparse arguments provided by the user

-         """

-         data = {

-             "scm_type": args.scm_type,

-             "scm_url": args.scm_url,

-             "scm_branch": args.scm_branch,

-             "spec": args.spec,

-         }

-         return self.process_build(args, self.client.create_new_build_mock, data)

+         return self.process_build(args, self.client.build_proxy.create_from_pypi, data)

  

      @requires_api_auth

      def action_build_scm(self, args):
@@ -279,9 +253,9 @@ 

              "subdirectory": args.subdirectory,

              "spec": args.spec,

              "scm_type": args.scm_type,

-             "srpm_build_method": args.srpm_build_method,

+             "source_build_method": args.srpm_build_method,

          }

-         return self.process_build(args, self.client.create_new_build_scm, data)

+         return self.process_build(args, self.client.build_proxy.create_from_scm, data)

  

      @requires_api_auth

      def action_build_rubygems(self, args):
@@ -291,7 +265,7 @@ 

          :param args: argparse arguments provided by the user

          """

          data = {"gem_name": args.gem_name}

-         return self.process_build(args, self.client.create_new_build_rubygems, data)

+         return self.process_build(args, self.client.build_proxy.create_from_rubygems, data)

  

      @requires_api_auth

      def action_build_custom(self, args):
@@ -306,7 +280,7 @@ 

          for arg in ['script_chroot', 'script_builddeps',

                      'script_resultdir']:

              data[arg] = getattr(args, arg)

-         return self.process_build(args, self.client.create_new_build_custom, data)

+         return self.process_build(args, self.client.build_proxy.create_from_custom, data)

  

      @requires_api_auth

      def action_build_distgit(self, args):
@@ -315,29 +289,36 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         data = {"clone_url": args.clone_url, "branch": args.branch}

-         return self.process_build(args, self.client.create_new_build_distgit, data)

+         data = {"clone_url": args.clone_url, "committish": args.branch}

+         return self.process_build(args, self.client.build_proxy.create_from_scm, data)

  

-     def process_build(self, args, build_function, data, bar=None):

-         username, copr = parse_name(args.copr)

+     def process_build(self, args, build_function, data, bar=None, progress_callback=None):

+         username, copr = self.parse_name(args.copr)

  

          try:

-             result = build_function(username=username, projectname=copr, chroots=args.chroots, memory=args.memory,

-                                     timeout=args.timeout, background=args.background, **data)

-         finally:

-             if bar:

-                 bar.finish()

+             buildopts = {"memory": args.memory, "timeout": args.timeout, "chroots": args.chroots,

+                          "background": args.background, "progress_callback": progress_callback}

+             result = build_function(ownername=username, projectname=copr, buildopts=buildopts, **data)

  

-         if result.output != "ok":

-             sys.stderr.write(result.error + "\n")

-             return

-         print(result.message)

+             builds = result if type(result) == list else [result]

+             print("Build was added to {0}:".format(builds[0].projectname))

+ 

+             for build in builds:

+                 url = urljoin(self.config["copr_url"], "/coprs/build/{}".format(build.id))

+                 print("  {}".format(url))

+ 

+             build_ids = [build.id for build in builds]

+             print("Created builds: {0}".format(" ".join(map(str, build_ids))))

  

-         build_ids = [bw.build_id for bw in result.builds_list]

-         print("Created builds: {0}".format(" ".join(map(str, build_ids))))

+             if not args.nowait:

+                 self._watch_builds(build_ids)

  

-         if not args.nowait:

-             self._watch_builds(build_ids)

+         except CoprException as ex:

+             sys.stderr.write(str(ex) + "\n")

+             sys.exit(1)

+         finally:

+             if bar:

+                 bar.finish()

  

  

      @requires_api_auth
@@ -348,19 +329,19 @@ 

          :param args: argparse arguments provided by the user

  

          """

-         username, copr = parse_name(args.name)

-         result = self.client.create_project(

-             username=username, projectname=copr, description=args.description,

+         username, copr = self.parse_name(args.name)

+         project = self.client.project_proxy.add(

+             ownername=username, projectname=copr, description=args.description,

              instructions=args.instructions, chroots=args.chroots,

-             repos=args.repos, initial_pkgs=args.initial_pkgs,

-             disable_createrepo=args.disable_createrepo,

+             additional_repos=args.repos, # packages=args.initial_pkgs, @TODO remove packages

+             devel_mode=args.disable_createrepo,

              unlisted_on_hp=ON_OFF_MAP[args.unlisted_on_hp],

              enable_net=ON_OFF_MAP[args.enable_net],

              persistent=args.persistent,

              auto_prune=ON_OFF_MAP[args.auto_prune],

              use_bootstrap_container=ON_OFF_MAP[args.use_bootstrap_container],

          )

-         print(result.message)

+         print("New project was successfully created.")

  

      @requires_api_auth

      def action_modify_project(self, args):
@@ -369,11 +350,11 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         username, copr = parse_name(args.name)

-         result = self.client.modify_project(

-             username=username, projectname=copr,

+         username, copr = self.parse_name(args.name)

+         project = self.client.project_proxy.edit(

+             ownername=username, projectname=copr,

              description=args.description, instructions=args.instructions,

-             repos=args.repos, disable_createrepo=args.disable_createrepo,

+             additional_repos=args.repos, devel_mode=args.disable_createrepo,

              unlisted_on_hp=ON_OFF_MAP[args.unlisted_on_hp],

              enable_net=ON_OFF_MAP[args.enable_net],

              auto_prune=ON_OFF_MAP[args.auto_prune],
@@ -388,9 +369,9 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         username, copr = parse_name(args.copr)

-         result = self.client.delete_project(username=username, projectname=copr)

-         print(result.message)

+         username, copr = self.parse_name(args.copr)

+         project = self.client.project_proxy.delete(ownername=username, projectname=copr)

+         print("Project {} has been deleted.".format(project.name))

  

      @requires_api_auth

      def action_fork(self, args):
@@ -399,29 +380,34 @@ 

  

          :param args: argparse arguments provided by the user

          """

-         username, copr = parse_name(args.dst)

-         result = self.client.fork_project(source=args.src, username=username, projectname=copr, confirm=args.confirm)

-         print(result.message)

+         srcownername, srcprojectname = self.parse_name(args.src)

+         dstownername, dstprojectname = self.parse_name(args.dst)

  

+         try:

+             dst = self.client.project_proxy.get(ownername=dstownername, projectname=dstprojectname)

+         except CoprNoResultException:

+             dst = None

+ 

+         project = self.client.project_proxy.fork(ownername=srcownername, projectname=srcprojectname,

+                                                  dstownername=dstownername, dstprojectname=dstprojectname,

+                                                  confirm=args.confirm)

+         if not dst:

+             print("Forking project {}/{} for you into {}.\nPlease be aware that it may take a few minutes "

+                   "to duplicate backend data.".format(srcownername, srcprojectname, project.full_name))

+         else:

+             print("Updating packages in {} from {}/{}.\nPlease be aware that it may take a few minutes "

+                   "to duplicate backend data.".format(project.full_name, srcownername, srcprojectname))

  

      def action_mock_config(self, args):

-         """ Method called when the 'list' action has been selected by the

+         """ Method called when the 'mock-config' action has been selected by the

          user.

  

          :param args: argparse arguments provided by the user

  

          """

-         username = self.client.username

-         project = args.project.split("/")

-         if len(project) != 2:

-             args.project = username + "/" + args.project

- 

-         result = self.client.get_build_config(args.project, args.chroot)

-         if result.output != "ok":

-             sys.stderr.write(result.error + "\n")

-             sys.stderr.write("Un-expected data returned, please report this issue\n")

- 

-         print(MockProfile(result.build_config))

+         ownername, projectname = self.parse_name(args.project)

+         build_config = self.client.project_chroot_proxy.get_build_config(ownername, projectname, args.chroot)

+         print(MockProfile(build_config))

  

  

      @check_username_presence
@@ -432,28 +418,37 @@ 

          :param args: argparse arguments provided by the user

  

          """

-         username = args.username or self.client.username

-         result = self.client.get_projects_list(username)

-         # import ipdb; ipdb.set_trace()

-         if result.output != "ok":

-             sys.stderr.write(result.error + "\n")

+         username = args.username or self.config["username"]

+         try:

+             projects = self.client.project_proxy.get_list(username)

+             if not projects:

+                 sys.stderr.write("No copr retrieved for user: '{0}'\n".format(username))

+                 return

+ 

+             for project in projects:

+                 print("Name: {}".format(project.name))

+                 print("  Description: {}".format(project.description))

+                 if project.chroot_repos:

+                     print("  Repo(s):")

+                     for name, url in project.chroot_repos.items():

+                         print("    {}: {}".format(name, url))

+                 if project.additional_repos:

+                     print("  Additional repo: {}".format(" ".join(project.additional_repos)))

+                 print("")

+ 

+         except CoprRequestException as ex:

+             sys.stderr.write(str(ex) + "\n")

              sys.stderr.write("Un-expected data returned, please report this issue\n")

-         elif not result.projects_list:

-             sys.stderr.write("No copr retrieved for user: '{0}'\n".format(username))

-             return

- 

-         for prj in result.projects_list:

-             print(prj)

  

      def action_status(self, args):

-         result = self.client.get_build_details(args.build_id)

-         print(result.status)

+         build = self.client.build_proxy.get(args.build_id)

+         print(build.state)

  

      def action_download_build(self, args):

-         result = self.client.get_build_details(args.build_id)

-         base_len = len(os.path.split(result.results))

+         build = self.client.build_proxy.get(args.build_id)

+         base_len = len(os.path.split(build.results))

  

-         for chroot, url in result.results_by_chroot.items():

+         for chroot, url in build.results_by_chroot.items():

              if args.chroots and chroot not in args.chroots:

                  continue

  
@@ -469,15 +464,15 @@ 

          user.

          :param args: argparse arguments provided by the user

          """

-         result = self.client.cancel_build(args.build_id)

-         print(result.status)

+         build = self.client.build_proxy.cancel(args.build_id)

+         print(build.state)

  

      def action_watch_build(self, args):

          self._watch_builds(args.build_id)

  

      def action_delete_build(self, args):

-         result = self.client.delete_build(args.build_id)

-         print(result.status)

+         build = self.client.build_proxy.delete(args.build_id)

+         print("Build deleted")

  

      #########################################################

      ###                   Chroot actions                  ###
@@ -491,12 +486,12 @@ 

          :param args: argparse arguments provided by the user

          """

          owner, copr, chroot = parse_chroot_path(args.coprchroot)

-         result = self.client.edit_chroot(

+         project_chroot = self.client.project_chroot_proxy.edit(

              ownername=owner, projectname=copr, chrootname=chroot,

-             upload_comps=args.upload_comps, delete_comps=args.delete_comps,

-             packages=args.packages, repos=args.repos

+             comps=args.upload_comps, delete_comps=args.delete_comps,

+             additional_packages=args.packages, additional_repos=args.repos

          )

-         print(result.message)

+         print("Edit chroot operation was successful.")

  

      def action_get_chroot(self, args):

          """ Method called when the 'get-chroot' action has been selected by the
@@ -505,35 +500,18 @@ 

          :param args: argparse arguments provided by the user

          """

          owner, copr, chroot = parse_chroot_path(args.coprchroot)

-         result = self.client.get_chroot(

+         project_chroot = self.client.project_chroot_proxy.get(

              ownername=owner, projectname=copr, chrootname=chroot

          )

-         print(simplejson.dumps(result.chroot, indent=4, sort_keys=True, for_json=True))

+         print(json_dumps(project_chroot))

  

      #########################################################

      ###                   Package actions                 ###

      #########################################################

  

      @requires_api_auth

-     def action_add_or_edit_package_tito(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = {

-             "package_name": args.name,

-             "git_url": args.git_url,

-             "git_dir": args.git_dir,

-             "git_branch": args.git_branch,

-             "tito_test": ON_OFF_MAP[args.tito_test],

-             "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

-         }

-         if args.create:

-             result = self.client.add_package_tito(ownername=ownername, projectname=projectname, **data)

-         else:

-             result = self.client.edit_package_tito(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

- 

-     @requires_api_auth

      def action_add_or_edit_package_pypi(self, args):

-         ownername, projectname = parse_name(args.copr)

+         ownername, projectname = self.parse_name(args.copr)

          data = {

              "package_name": args.name,

              "pypi_package_name": args.packagename,
@@ -543,31 +521,14 @@ 

              "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

          }

          if args.create:

-             result = self.client.add_package_pypi(ownername=ownername, projectname=projectname, **data)

-         else:

-             result = self.client.edit_package_pypi(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

- 

-     @requires_api_auth

-     def action_add_or_edit_package_mockscm(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = {

-             "package_name": args.name,

-             "scm_type": args.scm_type,

-             "scm_url": args.scm_url,

-             "scm_branch": args.scm_branch,

-             "spec": args.spec,

-             "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

-         }

-         if args.create:

-             result = self.client.add_package_mockscm(ownername=ownername, projectname=projectname, **data)

+             package = self.client.package_proxy.add(ownername, projectname, args.name, "pypi", data)

          else:

-             result = self.client.edit_package_mockscm(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+             package = self.client.package_proxy.edit(ownername, projectname, args.name, "pypi", data)

+         print("Create or edit operation was successful.")

  

      @requires_api_auth

      def action_add_or_edit_package_scm(self, args):

-         ownername, projectname = parse_name(args.copr)

+         ownername, projectname = self.parse_name(args.copr)

          data = {

              "package_name": args.name,

              "clone_url": args.clone_url,
@@ -575,32 +536,32 @@ 

              "subdirectory": args.subdirectory,

              "spec": args.spec,

              "scm_type": args.scm_type,

-             "srpm_build_method": args.srpm_build_method,

+             "source_build_method": args.srpm_build_method,

              "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

          }

          if args.create:

-             result = self.client.add_package_scm(ownername=ownername, projectname=projectname, **data)

+             package = self.client.package_proxy.add(ownername, projectname, args.name, "scm", data)

          else:

-             result = self.client.edit_package_scm(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+             package = self.client.package_proxy.edit(ownername, projectname, args.name, "scm", data)

+         print("Create or edit operation was successful.")

  

      @requires_api_auth

      def action_add_or_edit_package_rubygems(self, args):

-         ownername, projectname = parse_name(args.copr)

+         ownername, projectname = self.parse_name(args.copr)

          data = {

              "package_name": args.name,

              "gem_name": args.gem_name,

              "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

          }

          if args.create:

-             result = self.client.add_package_rubygems(ownername=ownername, projectname=projectname, **data)

+             package = self.client.package_proxy.add(ownername, projectname, args.name, "rubygems", data)

          else:

-             result = self.client.edit_package_rubygems(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+             package = self.client.package_proxy.edit(ownername, projectname, args.name, "rubygems", data)

+         print("Create or edit operation was successful.")

  

      @requires_api_auth

      def action_add_or_edit_package_custom(self, args):

-         ownername, projectname = parse_name(args.copr)

+         ownername, projectname = self.parse_name(args.copr)

          data = {

              "package_name": args.name,

              "script": ''.join(args.script.readlines()),
@@ -610,80 +571,91 @@ 

              "webhook_rebuild": ON_OFF_MAP[args.webhook_rebuild],

          }

          if args.create:

-             result = self.client.add_package_custom(ownername=ownername, projectname=projectname, **data)

+             package = self.client.package_proxy.add(ownername, projectname, args.name, "custom", data)

          else:

-             result = self.client.edit_package_custom(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+             package = self.client.package_proxy.edit(ownername, projectname, args.name, "custom", data)

+         print("Create or edit operation was successful.")

  

      def action_list_packages(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = {

-             "with_latest_build": args.with_latest_build,

-             "with_latest_succeeded_build": args.with_latest_succeeded_build,

-             "with_all_builds": args.with_all_builds,

-         }

-         result = self.client.get_packages_list(ownername=ownername, projectname=projectname, **data)

-         print(simplejson.dumps(result.packages_list, indent=4, sort_keys=True, for_json=True))

+         ownername, projectname = self.parse_name(args.copr)

+         packages = self.client.package_proxy.get_list(ownername=ownername, projectname=projectname)

+         packages_with_builds = [self._package_with_builds(p, args) for p in packages]

+         print(json_dumps(packages_with_builds))

  

      def action_list_package_names(self, args):

-         ownername, projectname = parse_name(args.copr)

-         result = self.client.get_packages_list(ownername=ownername, projectname=projectname)

-         for package in result.packages_list:

+         ownername, projectname = self.parse_name(args.copr)

+         packages = self.client.package_proxy.get_list(ownername=ownername, projectname=projectname)

+         for package in packages:

              print(package.name)

  

      def action_get_package(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = {

-             "pkg_name": args.name,

-             "with_latest_build": args.with_latest_build,

-             "with_latest_succeeded_build": args.with_latest_succeeded_build,

-             "with_all_builds": args.with_all_builds,

-         }

-         result = self.client.get_package(ownername=ownername, projectname=projectname, **data)

-         print(simplejson.dumps(result.package, indent=4, sort_keys=True, for_json=True))

+         ownername, projectname = self.parse_name(args.copr)

+         package = self.client.package_proxy.get(ownername=ownername, projectname=projectname, packagename=args.name)

+         package = self._package_with_builds(package, args)

+         print(json_dumps(package))

+ 

+     def _package_with_builds(self, package, args):

+         ownername, projectname = self.parse_name(args.copr)

+         kwargs = {"ownername": ownername, "projectname": projectname, "packagename": package.name}

+         pagination = {"limit": 1, "order": "id", "order_type": "DESC"}

+ 

+         if args.with_latest_build:

+             builds = self.client.build_proxy.get_list(pagination=pagination, **kwargs)

+             package["latest_build"] = builds[0] if builds else None

+ 

+         if args.with_latest_succeeded_build:

+             builds = self.client.build_proxy.get_list(status="succeeded", pagination=pagination, **kwargs)

+             package["latest_succeeded_build"] = builds[0] if builds else None

+ 

+         if args.with_all_builds:

+             builds = self.client.build_proxy.get_list(**kwargs)

+             package["builds"] = builds

+ 

+         return package

  

      def action_delete_package(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = { "pkg_name": args.name }

-         result = self.client.delete_package(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+         ownername, projectname = self.parse_name(args.copr)

+         package = self.client.package_proxy.delete(ownername=ownername, projectname=projectname, packagename=args.name)

+         print("Package was successfully deleted.")

  

      def action_reset_package(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = { "pkg_name": args.name }

-         result = self.client.reset_package(ownername=ownername, projectname=projectname, **data)

-         print(result.message)

+         ownername, projectname = self.parse_name(args.copr)

+         package = self.client.package_proxy.reset(ownername=ownername, projectname=projectname, packagename=args.name)

+         print("Package's default source was successfully reseted.")

  

      def action_build_package(self, args):

-         ownername, projectname = parse_name(args.copr)

-         data = {

-             "pkg_name": args.name,

+         ownername, projectname = self.parse_name(args.copr)

+         buildopts = {

              "chroots": args.chroots,

              #"memory": args.memory,

              "timeout": args.timeout

          }

+         try:

+             build = self.client.package_proxy.build(ownername=ownername, projectname=projectname,

+                                                      packagename=args.name, buildopts=buildopts)

+             print("Build was added to {0}.".format(build.projectname))

+             print("Created builds: {0}".format(build.id))

  

-         result = self.client.build_package(ownername=ownername, projectname=projectname, **data)

- 

-         if result.output != "ok":

-             sys.stderr.write(result.error + "\n")

-             return

-         print(result.message)

- 

-         build_ids = [bw.build_id for bw in result.builds_list]

-         print("Created builds: {0}".format(" ".join(map(str, build_ids))))

- 

-         if not args.nowait:

-             self._watch_builds(build_ids)

+             if not args.nowait:

+                 self._watch_builds([build.id])

+         except CoprRequestException as ex:

+             sys.stderr.write(str(ex) + "\n")

  

      def action_build_module(self, args):

          """

          Build module via Copr MBS

          """

-         ownername, projectname = parse_name(args.copr)

-         modulemd = open(args.yaml, "rb") if args.yaml else args.url

-         response = self.client.build_module(modulemd, ownername, projectname)

-         print(response.message if response.output == "ok" else response.error)

+         ownername, projectname = self.parse_name(args.copr)

+ 

+         try:

+             if args.yaml:

+                 module = self.client.module_proxy.build_from_file(ownername, projectname, args.yaml)

+             else:

+                 module = self.client.module_proxy.build_from_url(ownername, projectname, args.url)

+             print("Created module {}".format(module.nsv))

+ 

+         except CoprRequestException as ex:

+             print(ex)

  

  

  def setup_parser():
@@ -766,7 +738,7 @@ 

                                 help="Description of the copr")

      parser_create.add_argument("--instructions",

                                 help="Instructions for the copr")

-     parser_create.add_argument("--disable_createrepo",

+     parser_create.add_argument("--disable_createrepo", type=str2bool,

                                 help="Disable metadata auto generation")

      parser_create.add_argument("--enable-net", choices=["on", "off"], default="off",

                                 help="If net should be enabled for builds in this project (default is off)")
@@ -793,7 +765,7 @@ 

                                 help="Instructions for the copr")

      parser_modify.add_argument("--repo", dest="repos", action="append",

                                 help="Repository to add to this copr")

-     parser_modify.add_argument("--disable_createrepo",

+     parser_modify.add_argument("--disable_createrepo", type=str2bool,

                                 help="Disable metadata auto generation")

      parser_modify.add_argument("--enable-net", choices=["on", "off"],

                                 help="If net should be enabled for builds in this project (default is \"don't change\")")
@@ -822,16 +794,6 @@ 

      ###             Source-type related options           ###

      #########################################################

  

-     parser_tito_args_parent = argparse.ArgumentParser(add_help=False)

-     parser_tito_args_parent.add_argument("--git-url", metavar="URL", dest="git_url", required=True,

-                                          help="URL to a project managed by Tito")

-     parser_tito_args_parent.add_argument("--git-dir", metavar="DIRECTORY", dest="git_dir",

-                                          help="Relative path from Git root to directory containing .spec file")

-     parser_tito_args_parent.add_argument("--git-branch", metavar="BRANCH", dest="git_branch",

-                                          help="Git branch that you want to build from")

-     parser_tito_args_parent.add_argument("--test", dest="tito_test", choices=["on", "off"],

-                                          help="Build the last commit instead of the last release tag")

- 

      parser_pypi_args_parent = argparse.ArgumentParser(add_help=False)

      parser_pypi_args_parent.add_argument("--pythonversions", nargs="*", type=int, metavar="VERSION", default=[3, 2],

                                           help="For what Python versions to build (by default: 3 2)")
@@ -842,15 +804,6 @@ 

      parser_pypi_args_parent.add_argument("--template", "-t", dest="spec_template",

                                           help="Spec template to be used to build srpm with pyp2rpm")

  

-     parser_mockscm_args_parent = argparse.ArgumentParser(add_help=False)

-     parser_mockscm_args_parent.add_argument("--scm-type", metavar="TYPE", dest="scm_type", choices=["git", "svn"], default="git",

-                                             help="specify versioning tool, default is 'git'")

-     parser_mockscm_args_parent.add_argument("--scm-url", metavar="URL", dest="scm_url",

-                                             help="url to a project versioned by Git or SVN, required")

-     parser_mockscm_args_parent.add_argument("--scm-branch", metavar="BRANCH", dest="scm_branch", help="")

-     parser_mockscm_args_parent.add_argument("--spec", dest="spec", metavar="FILE",

-                                             help="relative path from SCM root to .spec file, required")

- 

      parser_scm_args_parent = argparse.ArgumentParser(add_help=False)

      parser_scm_args_parent.add_argument("--clone-url", required=True,

                                          help="clone url to a project versioned by Git or SVN, required")
@@ -940,16 +893,6 @@ 

                                                    help="DEPRECATED. Use SCM source type instead.")

      parser_build_distgit.set_defaults(func="action_build_distgit")

  

-     # create the parser for the "buildtito" command

-     parser_build_tito = subparsers.add_parser("buildtito", parents=[parser_tito_args_parent, parser_build_parent],

-                                               help="DEPRECATED. Use SCM source type instead.")

-     parser_build_tito.set_defaults(func="action_build_tito")

- 

-     # create the parser for the "buildmock" command

-     parser_build_mock = subparsers.add_parser("buildmock", parents=[parser_mockscm_args_parent, parser_build_parent],

-                                               help="DEPRECATED. Use SCM source type instead.")

-     parser_build_mock.set_defaults(func="action_build_mock")

- 

      # create the parser for the "buildscm" command

      parser_build_scm = subparsers.add_parser("buildscm", parents=[parser_scm_args_parent, parser_build_parent],

                                                help="Builds package from Git/DistGit/SVN repository.")
@@ -1025,17 +968,6 @@ 

      parser_add_or_edit_package_parent.add_argument("--webhook-rebuild",

                                                     choices=["on", "off"], help="Enable auto-rebuilding.")

  

-     # Tito edit/create

-     parser_add_package_tito = subparsers.add_parser("add-package-tito",

-                                                     help="DEPRECATED. Use SCM source type instead.",

-                                                     parents=[parser_tito_args_parent, parser_add_or_edit_package_parent])

-     parser_add_package_tito.set_defaults(func="action_add_or_edit_package_tito", create=True)

- 

-     parser_edit_package_tito = subparsers.add_parser("edit-package-tito",

-                                                      help="DEPRECATED. Use SCM source type instead.",

-                                                      parents=[parser_tito_args_parent, parser_add_or_edit_package_parent])

-     parser_edit_package_tito.set_defaults(func="action_add_or_edit_package_tito", create=False)

- 

      # PyPI edit/create

      parser_add_package_pypi = subparsers.add_parser("add-package-pypi",

                                                      help="Creates a new PyPI package",
@@ -1047,16 +979,6 @@ 

                                                       parents=[parser_pypi_args_parent, parser_add_or_edit_package_parent])

      parser_edit_package_pypi.set_defaults(func="action_add_or_edit_package_pypi", create=False)

  

-     # MockSCM edit/create

-     parser_add_package_mockscm = subparsers.add_parser("add-package-mockscm",

-                                                        help="DEPRECATED. Use SCM source type instead.",

-                                                        parents=[parser_mockscm_args_parent, parser_add_or_edit_package_parent])

-     parser_add_package_mockscm.set_defaults(func="action_add_or_edit_package_mockscm", create=True)

- 

-     parser_edit_package_mockscm = subparsers.add_parser("edit-package-mockscm",

-                                                         help="DEPRECATED. Use SCM source type instead.",

-                                                         parents=[parser_mockscm_args_parent, parser_add_or_edit_package_parent])

-     parser_edit_package_mockscm.set_defaults(func="action_add_or_edit_package_mockscm", create=False)

  

      # SCM edit/create

      parser_add_package_scm = subparsers.add_parser("add-package-scm",
@@ -1171,16 +1093,6 @@ 

      return parser

  

  

- def parse_name(name):

-     m = re.match(r"([^/]+)/(.*)", name)

-     if m:

-         owner = m.group(1)

-         name = m.group(2)

-     else:

-         owner = None

-     return owner, name

- 

- 

  def parse_chroot_path(path):

      m = re.match(r"(([^/]+)/)?([^/]+)/(.*)", path)

      if m:
@@ -1197,6 +1109,15 @@ 

      sys.stderr.write("#  Debug log enabled  #\n")

  

  

+ def str2bool(v):

+     if v.lower() in ("yes", "true", "on", "t", "y", "1"):

+         return True

+     elif v.lower() in ("no", "false", "off", "f", "n", "0"):

+         return False

+     else:

+         raise argparse.ArgumentTypeError("Boolean value expected.")

+ 

+ 

  def main(argv=sys.argv[1:]):

      try:

          # Set up parser for global args
@@ -1222,14 +1143,14 @@ 

      except copr_exceptions.CoprUnknownResponseException as e:

          sys.stderr.write("\nError: {0}\n".format(e))

          sys.exit(5)

-     except copr_exceptions.CoprRequestException as e:

+     except (CoprRequestException, CoprNoResultException) as e:

          sys.stderr.write("\nSomething went wrong:")

          sys.stderr.write("\nError: {0}\n".format(e))

          sys.exit(1)

      except argparse.ArgumentTypeError as e:

          sys.stderr.write("\nError: {0}".format(e))

          sys.exit(2)

-     except copr_exceptions.CoprException as e:

+     except CoprException as e:

          sys.stderr.write("\nError: {0}\n".format(e))

          sys.exit(3)

  

file modified
+15
@@ -1,5 +1,8 @@ 

  # coding: utf-8

  

+ import simplejson

+ 

+ 

  try:

      from progress.bar import Bar

  except ImportError:
@@ -50,3 +53,15 @@ 

          suffix = "%(downloaded)s %(download_speed)s eta %(eta_td)s"

  else:

      ProgressBar = DummyBar

+ 

+ 

+ def serializable(result):

+     if isinstance(result, dict):

+         new_result = result.copy()

+         new_result.pop("__response__", None)

+         return new_result

+     return result

+ 

+ 

+ def json_dumps(result):

+     return simplejson.dumps(serializable(result), indent=4, sort_keys=True, for_json=True)

@@ -1,11 +1,11 @@ 

  Name: perl516

    Description: A recent stable release of Perl with a number of additional utilities, scripts, and database connectors for MySQL and PostgreSQL. This version provides a large number of new features and enhancements, including new debugging options, improved Unicode support, and better performance.

-   Yum repo(s):

+   Repo(s):

      epel-6-x86_64: http://copr-be.cloud.fedoraproject.org/results/rhscl/perl516/epel-6-x86_64/

    Additional repo: http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/ http://people.redhat.com/~msuchy/rhscl-1.1-rhel-6-candidate-perl516/

  

  Name: ruby193

    Description: A recent stable release of Ruby with Rails 3.2.8 and a large collection of Ruby gems. This Software Collection gives developers on Red Hat Enterprise Linux 6 access to Ruby 1.9, which provides a number of new features and enhancements, including improved Unicode support, enhanced threading, and faster load times.

-   Yum repo(s):

+   Repo(s):

      epel-6-x86_64: http://copr-be.cloud.fedoraproject.org/results/rhscl/ruby193/epel-6-x86_64/

    Additional repo: http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/rhscl/v8314/epel-6-$basearch/

@@ -1,1 +1,28 @@ 

- {"output": "ok", "repos": [{"yum_repos": {"epel-6-x86_64": "http://copr-be.cloud.fedoraproject.org/results/rhscl/perl516/epel-6-x86_64/"}, "additional_repos": "http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/ http://people.redhat.com/~msuchy/rhscl-1.1-rhel-6-candidate-perl516/", "description": "A recent stable release of Perl with a number of additional utilities, scripts, and database connectors for MySQL and PostgreSQL. This version provides a large number of new features and enhancements, including new debugging options, improved Unicode support, and better performance.", "name": "perl516", "instructions": ""}, {"yum_repos": {"epel-6-x86_64": "http://copr-be.cloud.fedoraproject.org/results/rhscl/ruby193/epel-6-x86_64/"}, "additional_repos": "http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/ http://copr-be.cloud.fedoraproject.org/results/rhscl/v8314/epel-6-$basearch/", "description": "A recent stable release of Ruby with Rails 3.2.8 and a large collection of Ruby gems. This Software Collection gives developers on Red Hat Enterprise Linux 6 access to Ruby 1.9, which provides a number of new features and enhancements, including improved Unicode support, enhanced threading, and faster load times.", "name": "ruby193", "instructions": ""}]} 

\ No newline at end of file

+ [

+   {

+     "chroot_repos": {

+       "epel-6-x86_64": "http://copr-be.cloud.fedoraproject.org/results/rhscl/perl516/epel-6-x86_64/"

+     },

+     "additional_repos": [

+       "http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/",

+       "http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/",

+       "http://people.redhat.com/~msuchy/rhscl-1.1-rhel-6-candidate-perl516/"

+     ],

+     "description": "A recent stable release of Perl with a number of additional utilities, scripts, and database connectors for MySQL and PostgreSQL. This version provides a large number of new features and enhancements, including new debugging options, improved Unicode support, and better performance.",

+     "name": "perl516",

+     "instructions": ""

+   },

+   {

+     "chroot_repos": {

+       "epel-6-x86_64": "http://copr-be.cloud.fedoraproject.org/results/rhscl/ruby193/epel-6-x86_64/"

+     },

+     "additional_repos": [

+       "http://copr-be.cloud.fedoraproject.org/results/msuchy/scl-utils/epel-6-$basearch/",

+       "http://copr-be.cloud.fedoraproject.org/results/rhscl/httpd24/epel-6-$basearch/",

+       "http://copr-be.cloud.fedoraproject.org/results/rhscl/v8314/epel-6-$basearch/"

+     ],

+     "description": "A recent stable release of Ruby with Rails 3.2.8 and a large collection of Ruby gems. This Software Collection gives developers on Red Hat Enterprise Linux 6 access to Ruby 1.9, which provides a number of new features and enhancements, including improved Unicode support, enhanced threading, and faster load times.",

+     "name": "ruby193",

+     "instructions": ""

+   }

+ ]

file modified
+163 -294
@@ -1,20 +1,12 @@ 

  import os

  import argparse

- from collections import defaultdict

  import json

- from pprint import pprint

  import pytest

+ from munch import Munch

  

  import six

- import time

  import copr

- from copr.client.parsers import ProjectListParser, CommonMsgErrorOutParser

- from copr.client.responses import CoprResponse

- from copr.exceptions import CoprConfigException, CoprNoConfException, \

-     CoprRequestException, CoprUnknownResponseException, CoprException, \

-     CoprBuildException

- from copr.client import CoprClient

- import copr_cli

+ from copr.exceptions import CoprUnknownResponseException, CoprBuildException

  from copr_cli.main import no_config_warning

  

  
@@ -46,17 +38,26 @@ 

  from copr_cli import main

  

  

- def test_parse_name():

-     assert main.parse_name("foo") == (None, "foo")

-     assert main.parse_name("frostyx/foo") == ("frostyx", "foo")

-     assert main.parse_name("@copr/foo") == ("@copr", "foo")

+ mock_config = {

+     "username": None,

+     "copr_url": "http://copr/",

+     "login": "",

+     "token": "",

+ }

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_keyboard_interrupt(mock_cc, capsys):

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.side_effect = KeyboardInterrupt()

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_parse_name(config_from_file):

+     cmd = main.Commands(config_path=None)

+     assert cmd.parse_name("foo") == (None, "foo")

+     assert cmd.parse_name("frostyx/foo") == ("frostyx", "foo")

+     assert cmd.parse_name("@copr/foo") == ("@copr", "foo")

+ 

+ 

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_error_keyboard_interrupt(config_from_file, build_proxy_get, capsys):

+     build_proxy_get.side_effect = KeyboardInterrupt()

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["status", "123"])
@@ -66,13 +67,11 @@ 

      assert "Interrupted by user" in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_copr_request(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_error_copr_request(config_from_file, build_proxy_get, capsys):

      error_msg = "error message"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.side_effect = CoprRequestException(error_msg)

-     mock_cc.create_from_file_config.return_value = mock_client

+     build_proxy_get.side_effect = copr.v3.CoprRequestException(error_msg)

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["status", "123"])
@@ -84,13 +83,9 @@ 

  

  

  @mock.patch('copr_cli.main.setup_parser')

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_argument_error(mock_cc, mock_setup_parser, capsys):

+ def test_error_argument_error(mock_setup_parser, capsys):

      error_msg = "error message"

  

-     mock_client = MagicMock(no_config=False)

-     mock_cc.create_from_file_config.return_value = mock_client

- 

      mock_setup_parser.return_value.parse_args.side_effect = \

          argparse.ArgumentTypeError(error_msg)

  
@@ -102,11 +97,7 @@ 

      assert error_msg in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_no_args(mock_cc, capsys):

-     mock_client = MagicMock(no_config=False)

-     mock_cc.create_from_file_config.return_value = mock_client

- 

+ def test_error_no_args(capsys):

      for func_name in ["status", "build", "delete", "create"]:

          with pytest.raises(SystemExit) as err:

              main.main(argv=[func_name])
@@ -117,14 +108,11 @@ 

          assert "usage: copr" in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_copr_common_exception(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_error_copr_common_exception(config_from_file, build_proxy_get, capsys):

      error_msg = "error message"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.side_effect = \

-         CoprException(error_msg)

-     mock_cc.create_from_file_config.return_value = mock_client

+     build_proxy_get.side_effect = copr.v3.CoprException(error_msg)

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["status", "123"])
@@ -134,14 +122,11 @@ 

      assert error_msg in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_copr_build_exception(mock_cc, capsys):

+ @mock.patch('copr_cli.main.Commands.action_build')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_error_copr_build_exception(config_from_file, action_build, capsys):

      error_msg = "error message"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.side_effect = \

-         CoprBuildException(error_msg)

-     mock_cc.create_from_file_config.return_value = mock_client

+     action_build.side_effect = CoprBuildException(error_msg)

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["build", "prj1", "src1"])
@@ -151,14 +136,11 @@ 

      assert error_msg in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_error_copr_unknown_response(mock_cc, capsys):

+ @mock.patch('copr_cli.main.Commands.action_status')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_error_copr_unknown_response(config_from_file, action_status, capsys):

      error_msg = "error message"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.side_effect = \

-         CoprUnknownResponseException(error_msg)

-     mock_cc.create_from_file_config.return_value = mock_client

+     action_status.side_effect = CoprUnknownResponseException(error_msg)

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["status", "123"])
@@ -168,9 +150,9 @@ 

      assert error_msg in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_cancel_build_no_config(mock_cc, capsys):

-     mock_cc.create_from_file_config.side_effect = CoprNoConfException()

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_cancel_build_no_config(config_from_file, capsys):

+     config_from_file.side_effect = copr.v3.CoprNoConfigException()

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["cancel", "123400"])
@@ -185,13 +167,11 @@ 

      assert expected_warning in err

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_cancel_build_response(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.build.BuildProxy.cancel')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_cancel_build_response(config_from_file, build_proxy_cancel, capsys):

      response_status = "foobar"

- 

-     mock_client = MagicMock(no_config=False, )

-     mock_client.cancel_build.return_value = MagicMock(status=response_status)

-     mock_cc.create_from_file_config.return_value = mock_client

+     build_proxy_cancel.return_value = MagicMock(state=response_status)

  

      main.main(argv=["cancel", "123"])

      out, err = capsys.readouterr()
@@ -204,22 +184,18 @@ 

      return open(filepath).read()

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_list_project(mock_cc, capsys):

+ @mock.patch('copr_cli.main.config_from_file')

+ @mock.patch('copr.v3.proxies.project.ProjectProxy.get_list')

+ def test_list_project(get_list, config_from_file, capsys):

      response_data = json.loads(read_res('list_projects_response.json'))

      expected_output = read_res('list_projects_expected.txt')

  

      # no config

-     mock_cc.create_from_file_config.side_effect = CoprNoConfException()

-     mocked_client = MagicMock(CoprClient(no_config=True))

- 

-     control_response = CoprResponse(client=None, method="", data=response_data,

-                                     parsers=[ProjectListParser, CommonMsgErrorOutParser])

-     mocked_client.get_projects_list.return_value = control_response

-     mock_cc.return_value = mocked_client

+     config_from_file.side_effect = copr.v3.CoprNoConfigException()

+     control_response = [Munch(x) for x in response_data]

+     get_list.return_value = control_response

  

      main.main(argv=["list", "rhscl"])

- 

      out, err = capsys.readouterr()

      assert expected_output in out

  
@@ -227,9 +203,9 @@ 

      assert expected_warning in err

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_list_project_no_username(mock_cc, capsys):

-     mock_cc.create_from_file_config.side_effect = CoprNoConfException()

+ @mock.patch('copr_cli.main.config_from_file')

+ def test_list_project_no_username(config_from_file, capsys):

+     config_from_file.side_effect = copr.v3.CoprNoConfigException()

  

      with pytest.raises(SystemExit) as err:

          main.main(argv=["list"])
@@ -239,10 +215,8 @@ 

      assert "Pass username to command or create `~/.config/copr`" in err

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_list_project_no_username2(mock_cc, capsys):

-     mock_cc.create_from_file_config.return_value = CoprClient()

- 

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_list_project_no_username2(config_from_file, capsys):

      with pytest.raises(SystemExit) as err:

          main.main(argv=["list"])

  
@@ -251,31 +225,10 @@ 

      assert "Pass username to command or add it to `~/.config/copr`" in err

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_list_project_error_msg(mock_cc, capsys):

-     mock_client = MagicMock(no_config=False, username="dummy")

-     mock_cc.create_from_file_config.return_value = mock_client

- 

-     mock_response = MagicMock(response=CoprResponse(None, None, None),

-                               output="notok", error="error_msg",

-                               projects_list=[])

- 

-     mock_client.get_projects_list.return_value = mock_response

-     main.main(argv=["list", "projectname"])

- 

-     out, err = capsys.readouterr()

-     assert "error_msg" in err

- 

- 

- @mock.patch('copr_cli.main.CoprClient')

- def test_list_project_empty_list(mock_cc, capsys):

-     mock_client = MagicMock(no_config=False, username="dummy")

-     mock_cc.create_from_file_config.return_value = mock_client

- 

-     mock_response = MagicMock(response=CoprResponse(None, None, None),

-                               output="ok", projects_list=[])

- 

-     mock_client.get_projects_list.return_value = mock_response

+ @mock.patch('copr.v3.proxies.project.ProjectProxy.get_list')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_list_project_empty_list(config_from_file, get_list, capsys):

+     get_list.return_value = []

      main.main(argv=["list", "projectname"])

  

      out, err = capsys.readouterr()
@@ -283,28 +236,22 @@ 

      assert "No copr retrieved for user: dummy"

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_status_response(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_status_response(config_from_file, build_proxy_get, capsys):

      response_status = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.return_value = \

-         MagicMock(status=response_status)

-     mock_cc.create_from_file_config.return_value = mock_client

+     build_proxy_get.return_value = MagicMock(state=response_status)

  

      main.main(argv=["status", "123"])

      out, err = capsys.readouterr()

      assert "{0}\n".format(response_status) in out

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_debug_by_status_response(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_debug_by_status_response(config_from_file, build_proxy_get, capsys):

      response_status = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.return_value = \

-         MagicMock(status=response_status)

-     mock_cc.create_from_file_config.return_value = mock_client

+     build_proxy_get.return_value = MagicMock(state=response_status)

  

      main.main(argv=["--debug", "status", "123"])

      stdout, stderr = capsys.readouterr()
@@ -312,11 +259,7 @@ 

      assert "Debug log enabled " in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_status_response_no_args(mock_cc, capsys):

-     mock_client = MagicMock(no_config=False)

-     mock_cc.create_from_file_config.return_value = mock_client

- 

+ def test_status_response_no_args(capsys):

      with pytest.raises(SystemExit) as err:

          main.main(argv=["status"])

  
@@ -326,25 +269,21 @@ 

      assert "usage: copr" in stderr

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_delete_project(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.delete_project.return_value = \

-         MagicMock(message=response_message)

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.project.ProjectProxy.delete')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_delete_project(config_from_file, project_proxy_delete, capsys):

+     project_proxy_delete.return_value = Munch(name="foo")

  

      main.main(argv=["delete", "foo"])

      out, err = capsys.readouterr()

-     assert "{0}\n".format(response_message) in out

+     assert out == "Project foo has been deleted.\n"

  

  

  @mock.patch('copr_cli.main.subprocess')

- @mock.patch('copr_cli.main.CoprClient')

- def test_download_build(mock_cc, mock_sp, capsys):

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.return_value = \

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_download_build(config_from_file, build_proxy_get, mock_sp, capsys):

+     build_proxy_get.return_value = \

          MagicMock(

              data={"chroots": {

                  u'epel-6-x86_64': u'succeeded', u'epel-6-i386': u'succeeded'
@@ -355,7 +294,6 @@ 

                  u'epel-6-i386': u'http://example.com/results/epel-6-i386/python-copr-1.50-1.fc20',

              }

          )

-     mock_cc.create_from_file_config.return_value = mock_client

  

      mock_sp.call.return_value = None

      main.main(argv=["download-build", "foo"])
@@ -379,10 +317,10 @@ 

  

  

  @mock.patch('copr_cli.main.subprocess')

- @mock.patch('copr_cli.main.CoprClient')

- def test_download_build_select_chroot(mock_cc, mock_sp, capsys):

-     mock_client = MagicMock(no_config=False)

-     mock_client.get_build_details.return_value = \

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_download_build_select_chroot(config_from_file, build_proxy_get, mock_sp, capsys):

+     build_proxy_get.return_value = \

          MagicMock(

              data={"chroots": {

                  u'epel-6-x86_64': u'succeeded', u'epel-6-i386': u'succeeded'
@@ -393,7 +331,6 @@ 

                  u'epel-6-i386': u'http://example.com/results/epel-6-i386/python-copr-1.50-1.fc20',

              }

          )

-     mock_cc.create_from_file_config.return_value = mock_client

  

      mock_sp.call.return_value = None

      main.main(argv=["download-build", "foo", "-r", "epel-6-x86_64"])
@@ -409,15 +346,9 @@ 

      assert mock_sp.call.call_args_list == expected_sp_call_args

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_project(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_project.return_value = \

-         MagicMock(message=response_message)

-     mock_cc.create_from_file_config.return_value = mock_client

- 

+ @mock.patch('copr.v3.proxies.project.ProjectProxy.add')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_create_project(config_from_file, project_proxy_add, capsys):

      main.main(argv=[

          "create", "foo",

          "--chroot", "f20", "--chroot", "f21",
@@ -429,24 +360,22 @@ 

  

      stdout, stderr = capsys.readouterr()

  

-     mock_client.create_project.assert_called_with(auto_prune=True,

-         username=None, persistent=False, projectname="foo", description="desc string",

+     project_proxy_add.assert_called_with(auto_prune=True,

+         ownername=None, persistent=False, projectname="foo", description="desc string",

          instructions="instruction string", chroots=["f20", "f21"],

-         repos=["repo1", "repo2"], initial_pkgs=["pkg1"],

-         unlisted_on_hp=None, disable_createrepo=None, enable_net=False,

+         additional_repos=["repo1", "repo2"],

+         unlisted_on_hp=None, devel_mode=None, enable_net=False,

          use_bootstrap_container=None)

  

-     assert "{0}\n".format(response_message) in stdout

+     assert stdout == "New project was successfully created.\n"

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_no_wait_ok(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(output="ok", message=response_message)

- 

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ @mock.patch('copr_cli.main.Commands._watch_builds')

+ def test_create_build_no_wait_ok(watch_builds, config_from_file, create_from_url, auth_check, capsys):

+     create_from_url.return_value = Munch(projectname="foo", id=123)

  

      main.main(argv=[

          "build", "--nowait",
@@ -454,78 +383,57 @@ 

      ])

  

      stdout, stderr = capsys.readouterr()

-     assert response_message in stdout

      assert "Created builds" in stdout

- 

-     assert not mock_client._watch_build.called

+     assert "Build was added to foo" in stdout

+     assert not watch_builds.called

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_no_wait_error(mock_cc, capsys):

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ @mock.patch('copr_cli.main.Commands._watch_builds')

+ def test_create_build_no_wait_error(watch_builds, config_from_file,create_from_url, autch_check, capsys):

      response_message = "foobar"

+     create_from_url.side_effect = copr.v3.CoprRequestException(response_message)

  

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(output="notok", error=response_message)

- 

-     mock_cc.create_from_file_config.return_value = mock_client

- 

-     main.main(argv=[

-         "build", "--nowait",

-         "copr_name", "http://example.com/pkgs.srpm"

-     ])

+     with pytest.raises(SystemExit) as err:

+         main.main(argv=[

+             "build", "--nowait",

+             "copr_name", "http://example.com/pkgs.srpm"

+         ])

  

      stdout, stderr = capsys.readouterr()

      assert response_message in stderr

- 

-     assert not mock_client._watch_build.called

+     assert not watch_builds.called

  

  

  @mock.patch('copr_cli.main.time')

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_wait_succeeded_no_sleep(mock_cc, mock_time, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(

-         output="ok",

-         message=response_message,

-         builds_list=[

-             MagicMock(build_id=x)

-             for x in range(3)

-         ])

-     mock_client.get_build_details.return_value = MagicMock(

-         status="succeeded", output="ok"

-     )

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_create_build_wait_succeeded_no_sleep(config_from_file, build_proxy_get,

+                                               create_from_url, auth_check, mock_time, capsys):

+     create_from_url.return_value = Munch(projectname="foo", id=123)

+     build_proxy_get.return_value = Munch(state="succeeded")

      main.main(argv=[

          "build",

          "copr_name", "http://example.com/pkgs.srpm"

      ])

  

      stdout, stderr = capsys.readouterr()

- 

-     assert response_message in stdout

      assert "Created builds" in stdout

      assert "Watching build" in stdout

      assert not mock_time.sleep.called

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_wait_error_status(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(

-         output="ok",

-         message=response_message,

-         builds_list=[

-             MagicMock(build_id=x)

-             for x in ["1", "2", "3"]

-         ])

-     mock_client.get_build_details.return_value = MagicMock(

-         output="notok"

-     )

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_create_build_wait_error_status(config_from_file, build_proxy_get, create_from_url, auth_check, capsys):

+     create_from_url.return_value = Munch(projectname="foo", id=123)

+     build_proxy_get.side_effect = copr.v3.CoprRequestException()

      with pytest.raises(SystemExit) as err:

          main.main(argv=[

              "build",
@@ -534,27 +442,17 @@ 

          assert exit_wrap(err.value) == 1

  

      stdout, stderr = capsys.readouterr()

-     assert response_message in stdout

      assert "Created builds" in stdout

      assert "Watching build" in stdout

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_wait_unknown_build_status(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(

-         output="ok",

-         message=response_message,

-         builds_list=[

-             MagicMock(build_id=x)

-             for x in ["1", "2", "3"]

-         ])

-     mock_client.get_build_details.return_value = MagicMock(

-         output="ok", status="unknown"

-     )

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_create_build_wait_unknown_build_status(config_from_file, build_proxy_get, create_from_url, auth_check, capsys):

+     create_from_url.return_value = Munch(projectname="foo", id=123)

+     build_proxy_get.return_value = Munch(state="unknown")

      with pytest.raises(SystemExit) as err:

          main.main(argv=[

              "build",
@@ -563,26 +461,17 @@ 

          assert exit_wrap(err.value) == 1

  

      stdout, stderr = capsys.readouterr()

-     assert response_message in stdout

      assert "Created builds" in stdout

      assert "Watching build" in stdout

  

  

- @mock.patch('copr_cli.main.CoprClient')

- def test_create_build_wait_keyboard_interrupt(mock_cc, capsys):

-     response_message = "foobar"

- 

-     mock_client = MagicMock(no_config=False)

-     mock_client.create_new_build.return_value = MagicMock(

-         output="ok",

-         message=response_message,

-         builds_list=[

-             MagicMock(build_id=x)

-             for x in ["1", "2", "3"]

-         ])

-     mock_client.get_build_details.side_effect = KeyboardInterrupt

- 

-     mock_cc.create_from_file_config.return_value = mock_client

+ @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+ @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+ @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

+ def test_create_build_wait_keyboard_interrupt(config_from_file, build_proxy_get, create_from_url, autch_check, capsys):

+     create_from_url.return_value = Munch(projectname="foo", id=123)

+     build_proxy_get.side_effect = KeyboardInterrupt

  

      main.main(argv=[

          "build",
@@ -590,26 +479,20 @@ 

      ])

  

      stdout, stderr = capsys.readouterr()

-     assert response_message in stdout

      assert "Created builds" in stdout

      assert "Watching build" in stdout

  

  

  @mock.patch('copr_cli.main.time')

- @mock.patch('copr_cli.main.CoprClient')

+ @mock.patch('copr_cli.main.config_from_file', return_value=mock_config)

  class TestCreateBuild(object):

-     def test_create_build_wait_succeeded_complex(self, mock_cc, mock_time, capsys):

-         response_message = "foobar"

- 

-         mock_client = MagicMock(no_config=False)

-         mock_client.create_new_build.return_value = MagicMock(

-             output="ok",

-             message=response_message,

-             builds_list=[

-                 MagicMock(build_id=x)

-                 for x in range(3)

-             ])

  

+     @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+     @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+     @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+     def test_create_build_wait_succeeded_complex(self, build_proxy_get, create_from_url, auth_check,

+                                                  config_from_file, mock_time, capsys):

+         create_from_url.return_value = Munch(projectname="foo", id=1)

          self.stage = 0

  

          def incr(*args, **kwargs):
@@ -617,21 +500,19 @@ 

  

          def result_map(build_id, *args, **kwargs):

              if self.stage == 0:

-                 return MagicMock(status="pending", output="ok")

+                 return Munch(state="pending")

              elif self.stage == 1:

                  smap = {0: "pending", 1: "starting", 2: "running"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

              elif self.stage == 2:

                  smap = {0: "starting", 1: "running", 2: "succeeded"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

              elif self.stage == 3:

                  smap = {0: "skipped", 1: "succeeded", 2: "succeeded"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

  

          mock_time.sleep.side_effect = incr

- 

-         mock_client.get_build_details.side_effect = result_map

-         mock_cc.create_from_file_config.return_value = mock_client

+         build_proxy_get.side_effect = result_map

  

          main.main(argv=[

              "build",
@@ -639,24 +520,16 @@ 

          ])

  

          stdout, stderr = capsys.readouterr()

- 

-         assert response_message in stdout

          assert "Created builds" in stdout

          assert "Watching build" in stdout

          assert len(mock_time.sleep.call_args_list) == 3

  

-     def test_create_build_wait_failed_complex(self, mock_cc, mock_time, capsys):

-         response_message = "foobar"

- 

-         mock_client = MagicMock(no_config=False)

-         mock_client.create_new_build.return_value = MagicMock(

-             output="ok",

-             message=response_message,

-             builds_list=[

-                 MagicMock(build_id=x)

-                 for x in range(3)

-             ])

- 

+     @mock.patch('copr.v3.proxies.BaseProxy.auth_check', return_value=True)

+     @mock.patch('copr.v3.proxies.build.BuildProxy.create_from_url')

+     @mock.patch('copr.v3.proxies.build.BuildProxy.get')

+     def test_create_build_wait_failed_complex(self, build_proxy_get, create_from_url, auth_check,

+                                               config_from_file, mock_time, capsys):

+         create_from_url.return_value = Munch(projectname="foo", id=1)

          self.stage = 0

  

          def incr(*args, **kwargs):
@@ -664,21 +537,19 @@ 

  

          def result_map(build_id, *args, **kwargs):

              if self.stage == 0:

-                 return MagicMock(status="pending", output="ok")

+                 return Munch(state="pending")

              elif self.stage == 1:

                  smap = {0: "pending", 1: "starting", 2: "running"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

              elif self.stage == 2:

                  smap = {0: "failed", 1: "running", 2: "succeeded"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

              elif self.stage == 3:

                  smap = {0: "failed", 1: "failed", 2: "succeeded"}

-                 return MagicMock(status=smap[build_id], output="ok")

+                 return Munch(state=smap[build_id])

  

          mock_time.sleep.side_effect = incr

- 

-         mock_client.get_build_details.side_effect = result_map

-         mock_cc.create_from_file_config.return_value = mock_client

+         build_proxy_get.side_effect = result_map

  

          with pytest.raises(SystemExit) as err:

              main.main(argv=[
@@ -687,9 +558,7 @@ 

              ])

  

          stdout, stderr = capsys.readouterr()

- 

-         assert response_message in stdout

          assert "Created builds" in stdout

          assert "Watching build" in stdout

-         assert "Build(s) 0, 1 failed" in stderr

+         assert "Build(s) 1 failed" in stderr

          assert len(mock_time.sleep.call_args_list) == 3

This is a WIP rewrite of copr-cli to use APIv3.
For APIv3 implementation, see PR#278.

So far, it works fine for me in some use-cases, but running beaker tests with it, revealed many errors, that needs to be fixed.

You will need to alter spec file to
Requires: python3-copr >= XXX
but the XX is currently unknow as it depends on mergin api PR itself.

8 new commits added

  • [beaker-tests-sanity] empty source is now a dict, not a string
  • [beaker-tests-sanity] dont replace anything
  • [cli] fix the order of arguments
  • [cli] json_dumps is not supposed to print anything
  • [beaker-tests-sanity] repos and packages are now lists
  • [beaker-tests-sanity] remove tito and mock tests
  • [beaker-tests-sanity] copr-cli now returns source_dict instead of source_json
  • [cli] return proper status code
5 years ago

I've fixed issues in both this PR and PR#278, that beaker tests revealed. I've also modified some of the tests because we expect a bit different output here and there.

1 new commit added

  • [cli] update resource properties
5 years ago

rebased onto 21c2159bc63468253df4dfd76a8ae41b2025a60e

5 years ago

Please take a look. I've rewritten the copr-cli, updated some beaker tests and rewritten unit tests.
Unfortunately, pagure doesn't show commits list in the right order and also show incomplete diff. You need to fetch the branch to properly review it.

rebased onto 9c8109d28d5b604377d659c3a2409a822a1f0ba2

5 years ago

rebased onto 2c2341f

5 years ago

There was a merge conflict, so I've rebased the branch.

Can you just state "repos"? To avoid yum/dnf confusion.

everything else looks good to me.

1 new commit added

  • [cli] print just 'repos' to avoid yum/dnf confusion
5 years ago

Can you just state "repos"? To avoid yum/dnf confusion.

Done

+1, even though I'd slightly prefer (at least if I was the user of those) not to drop the copr cli argument parsers, but change them so they claim that "the support was dropped, use SCM".

There is some issue with pagure, so (this?) PR cannot be merged.
As there are many +1 comments, I am manually merging this branch to master, pushing it and closing this PR.

Pull-Request has been closed by frostyx

5 years ago