827 |
827 |
828 |
828 |
829 |
829 |
830 /** conduit API **/ |
830 /** conduit API **/ |
831 |
831 |
832 object Conduit |
832 object API |
833 { |
833 { |
834 def apply(user: String, host: String, port: Int = 22): Conduit = |
834 /* repository information */ |
835 new Conduit(user, host, port) |
835 |
836 } |
836 sealed case class Repository( |
837 |
837 vcs: VCS.Value, |
838 final class Conduit private(ssh_user: String, ssh_host: String, ssh_port: Int) |
838 id: Long, |
|
839 phid: String, |
|
840 name: String, |
|
841 callsign: String, |
|
842 short_name: String, |
|
843 importing: Boolean, |
|
844 ssh_url: String) |
|
845 { |
|
846 def is_hg: Boolean = vcs == VCS.hg |
|
847 } |
|
848 |
|
849 object VCS extends Enumeration |
|
850 { |
|
851 val hg, git, svn = Value |
|
852 def read(s: String): Value = |
|
853 try { withName(s) } |
|
854 catch { case _: java.util.NoSuchElementException => error("Unknown vcs type " + quote(s)) } |
|
855 } |
|
856 |
|
857 def edits(typ: String, value: JSON.T): List[JSON.Object.T] = |
|
858 List(JSON.Object("type" -> typ, "value" -> value)) |
|
859 |
|
860 def opt_edits(typ: String, value: Option[JSON.T]): List[JSON.Object.T] = |
|
861 value.toList.flatMap(edits(typ, _)) |
|
862 |
|
863 |
|
864 /* result with optional error */ |
|
865 |
|
866 sealed case class Result(result: JSON.T, error: Option[String]) |
|
867 { |
|
868 def ok: Boolean = error.isEmpty |
|
869 def get: JSON.T = if (ok) result else Exn.error(error.get) |
|
870 |
|
871 def get_value[A](unapply: JSON.T => Option[A]): A = |
|
872 unapply(get) getOrElse Exn.error("Bad JSON result: " + JSON.Format(result)) |
|
873 |
|
874 def get_string: String = get_value(JSON.Value.String.unapply) |
|
875 } |
|
876 |
|
877 def make_result(json: JSON.T): Result = |
|
878 { |
|
879 val result = JSON.value(json, "result").getOrElse(JSON.Object.empty) |
|
880 val error_info = JSON.string(json, "error_info") |
|
881 val error_code = JSON.string(json, "error_code") |
|
882 Result(result, error_info orElse error_code) |
|
883 } |
|
884 |
|
885 |
|
886 /* context for operations */ |
|
887 |
|
888 def apply(user: String, host: String, port: Int = 22): API = |
|
889 new API(user, host, port) |
|
890 } |
|
891 |
|
892 final class API private(ssh_user: String, ssh_host: String, ssh_port: Int) |
839 { |
893 { |
840 /* connection */ |
894 /* connection */ |
841 |
895 |
842 require(ssh_host.nonEmpty && ssh_port >= 0) |
896 require(ssh_host.nonEmpty && ssh_port >= 0) |
843 |
897 |
909 } |
963 } |
910 |
964 |
911 def the_repository(phid: String): API.Repository = |
965 def the_repository(phid: String): API.Repository = |
912 get_repositories(phid = phid) match { |
966 get_repositories(phid = phid) match { |
913 case List(repo) => repo |
967 case List(repo) => repo |
914 case _ => error("Bad repository " + quote(phid)) |
968 case _ => error("Bad repository PHID " + quote(phid)) |
915 } |
969 } |
916 |
970 |
917 def create_repository( |
971 def create_repository( |
918 name: String, |
972 name: String, |
919 callsign: String = "", // unique name, UPPERCASE |
973 callsign: String = "", // unique name, UPPERCASE |
941 execute("diffusion.looksoon", params = JSON.Object("repositories" -> List(phid))).get |
995 execute("diffusion.looksoon", params = JSON.Object("repositories" -> List(phid))).get |
942 |
996 |
943 the_repository(phid) |
997 the_repository(phid) |
944 } |
998 } |
945 } |
999 } |
946 |
|
947 object API |
|
948 { |
|
949 /* repository information */ |
|
950 |
|
951 sealed case class Repository( |
|
952 vcs: VCS.Value, |
|
953 id: Long, |
|
954 phid: String, |
|
955 name: String, |
|
956 callsign: String, |
|
957 short_name: String, |
|
958 importing: Boolean, |
|
959 ssh_url: String) |
|
960 { |
|
961 def is_hg: Boolean = vcs == VCS.hg |
|
962 } |
|
963 |
|
964 object VCS extends Enumeration |
|
965 { |
|
966 val hg, git, svn = Value |
|
967 def read(s: String): Value = |
|
968 try { withName(s) } |
|
969 catch { case _: java.util.NoSuchElementException => error("Unknown vcs type " + quote(s)) } |
|
970 } |
|
971 |
|
972 def edits(typ: String, value: JSON.T): List[JSON.Object.T] = |
|
973 List(JSON.Object("type" -> typ, "value" -> value)) |
|
974 |
|
975 def opt_edits(typ: String, value: Option[JSON.T]): List[JSON.Object.T] = |
|
976 value.toList.flatMap(edits(typ, _)) |
|
977 |
|
978 |
|
979 /* result with optional error */ |
|
980 |
|
981 sealed case class Result(result: JSON.T, error: Option[String]) |
|
982 { |
|
983 def ok: Boolean = error.isEmpty |
|
984 def get: JSON.T = if (ok) result else Exn.error(error.get) |
|
985 |
|
986 def get_value[A](unapply: JSON.T => Option[A]): A = |
|
987 unapply(get) getOrElse Exn.error("Bad JSON result: " + JSON.Format(result)) |
|
988 |
|
989 def get_string: String = get_value(JSON.Value.String.unapply) |
|
990 } |
|
991 |
|
992 def make_result(json: JSON.T): Result = |
|
993 { |
|
994 val result = JSON.value(json, "result").getOrElse(JSON.Object.empty) |
|
995 val error_info = JSON.string(json, "error_info") |
|
996 val error_code = JSON.string(json, "error_code") |
|
997 Result(result, error_info orElse error_code) |
|
998 } |
|
999 } |
|
1000 } |
1000 } |