File tree 2 files changed +44
-17
lines changed
2 files changed +44
-17
lines changed Original file line number Diff line number Diff line change @@ -136,6 +136,35 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
136
136
) ?;
137
137
verify_dependencies ( pkg, & registry, reg_ids. original ) ?;
138
138
139
+ // Bail before packaging and uploading if same version already exists in the registry
140
+
141
+ let mut source = SourceConfigMap :: empty ( opts. gctx ) ?. load ( reg_ids. original , & HashSet :: new ( ) ) ?;
142
+
143
+ let query = Dependency :: parse ( pkg. name ( ) , Some ( & ver) , reg_ids. original ) ?;
144
+
145
+ let _lock = opts
146
+ . gctx
147
+ . acquire_package_cache_lock ( CacheLockMode :: DownloadExclusive ) ?;
148
+
149
+ let duplicate_query = loop {
150
+ match source. query_vec ( & query, QueryKind :: Exact ) {
151
+ std:: task:: Poll :: Ready ( res) => {
152
+ break res?;
153
+ }
154
+ std:: task:: Poll :: Pending => source. block_until_ready ( ) ?,
155
+ }
156
+ } ;
157
+
158
+ drop ( _lock) ;
159
+
160
+ if !duplicate_query. is_empty ( ) {
161
+ bail ! (
162
+ "crate {} already has version {}. Aborting publish." ,
163
+ pkg. name( ) ,
164
+ pkg. version( )
165
+ ) ;
166
+ }
167
+
139
168
// Prepare a tarball, with a non-suppressible warning if metadata
140
169
// is missing since this is being put online.
141
170
let tarball = ops:: package_one (
Original file line number Diff line number Diff line change @@ -130,14 +130,18 @@ You may press ctrl-c to skip waiting; the crate should be available shortly.
130
130
131
131
#[ cargo_test]
132
132
fn duplicate_version ( ) {
133
+ let arc: Arc < Mutex < u32 > > = Arc :: new ( Mutex :: new ( 0 ) ) ;
133
134
let registry_dupl = RegistryBuilder :: new ( )
134
135
. http_api ( )
135
136
. http_index ( )
136
- . add_responder ( "/api/v1/crates/new" , move |_req, _server| Response {
137
- code : 200 ,
138
- headers : vec ! [ ] ,
139
- body : br#"{"errors": [{"detail": "crate version `0.0.1` is already uploaded"}]}"#
140
- . to_vec ( ) ,
137
+ . add_responder ( "/index/3/f/foo" , move |req, server| {
138
+ let mut lock = arc. lock ( ) . unwrap ( ) ;
139
+ * lock += 1 ;
140
+ if * lock <= 1 {
141
+ server. not_found ( req)
142
+ } else {
143
+ server. index ( req)
144
+ }
141
145
} )
142
146
. build ( ) ;
143
147
@@ -156,23 +160,17 @@ fn duplicate_version() {
156
160
. file ( "src/main.rs" , "fn main() {}" )
157
161
. build ( ) ;
158
162
163
+ p. cargo ( "publish" )
164
+ . replace_crates_io ( registry_dupl. index_url ( ) )
165
+ . without_status ( )
166
+ . run ( ) ;
167
+
159
168
p. cargo ( "publish" )
160
169
. replace_crates_io ( registry_dupl. index_url ( ) )
161
170
. with_stderr (
162
171
"\
163
172
[UPDATING] crates.io index
164
- [WARNING] [..]
165
- See [..]
166
- [PACKAGING] foo v0.0.1 ([CWD])
167
- [VERIFYING] foo v0.0.1 ([CWD])
168
- [..]
169
- [..]
170
- [..]
171
- [UPLOADING] foo v0.0.1 ([CWD])
172
- error: failed to publish [..]
173
-
174
- Caused by:
175
- [..] is already uploaded
173
+ error: crate foo already has version 0.0.1. Aborting publish.
176
174
" ,
177
175
)
178
176
. with_status ( 101 )
You can’t perform that action at this time.
0 commit comments