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